| ... | ... | @@ -40,6 +40,8 @@ phdr_got_index: ?u16 = null, |
| 40 | 40 | phdr_load_ro_index: ?u16 = null, |
| 41 | 41 | /// The index into the program headers of a PT_LOAD program header with Write flag |
| 42 | 42 | phdr_load_rw_index: ?u16 = null, |
| 43 | /// The index into the program headers of a PT_LOAD program header with zerofill data. |
| 44 | phdr_load_zerofill_index: ?u16 = null, |
| 43 | 45 | |
| 44 | 46 | entry_addr: ?u64 = null, |
| 45 | 47 | page_size: u32, |
| ... | ... | @@ -56,6 +58,7 @@ got: GotSection = .{}, |
| 56 | 58 | text_section_index: ?u16 = null, |
| 57 | 59 | rodata_section_index: ?u16 = null, |
| 58 | 60 | data_section_index: ?u16 = null, |
| 61 | bss_section_index: ?u16 = null, |
| 59 | 62 | eh_frame_section_index: ?u16 = null, |
| 60 | 63 | eh_frame_hdr_section_index: ?u16 = null, |
| 61 | 64 | dynamic_section_index: ?u16 = null, |
| ... | ... | @@ -532,6 +535,26 @@ pub fn populateMissingMetadata(self: *Elf) !void { |
| 532 | 535 | self.phdr_table_dirty = true; |
| 533 | 536 | } |
| 534 | 537 | |
| 538 | if (self.phdr_load_zerofill_index == null) { |
| 539 | self.phdr_load_zerofill_index = @as(u16, @intCast(self.phdrs.items.len)); |
| 540 | const p_align = if (self.base.options.target.os.tag == .linux) self.page_size else @as(u16, ptr_size); |
| 541 | const off = self.phdrs.items[self.phdr_load_rw_index.?].p_offset; |
| 542 | log.debug("found PT_LOAD zerofill free space 0x{x} to 0x{x}", .{ off, off }); |
| 543 | // TODO Same as for GOT |
| 544 | const addr: u32 = if (self.base.options.target.ptrBitWidth() >= 32) 0x14000000 else 0xf000; |
| 545 | try self.phdrs.append(gpa, .{ |
| 546 | .p_type = elf.PT_LOAD, |
| 547 | .p_offset = off, |
| 548 | .p_filesz = 0, |
| 549 | .p_vaddr = addr, |
| 550 | .p_paddr = addr, |
| 551 | .p_memsz = 0, |
| 552 | .p_align = p_align, |
| 553 | .p_flags = elf.PF_R | elf.PF_W, |
| 554 | }); |
| 555 | self.phdr_table_dirty = true; |
| 556 | } |
| 557 | |
| 535 | 558 | if (self.shstrtab_section_index == null) { |
| 536 | 559 | self.shstrtab_section_index = @as(u16, @intCast(self.shdrs.items.len)); |
| 537 | 560 | assert(self.shstrtab.buffer.items.len == 0); |
| ... | ... | @@ -655,6 +678,26 @@ pub fn populateMissingMetadata(self: *Elf) !void { |
| 655 | 678 | self.shdr_table_dirty = true; |
| 656 | 679 | } |
| 657 | 680 | |
| 681 | if (self.bss_section_index == null) { |
| 682 | self.bss_section_index = @as(u16, @intCast(self.shdrs.items.len)); |
| 683 | const phdr = &self.phdrs.items[self.phdr_load_zerofill_index.?]; |
| 684 | try self.shdrs.append(gpa, .{ |
| 685 | .sh_name = try self.shstrtab.insert(gpa, ".bss"), |
| 686 | .sh_type = elf.SHT_NOBITS, |
| 687 | .sh_flags = elf.SHF_WRITE | elf.SHF_ALLOC, |
| 688 | .sh_addr = phdr.p_vaddr, |
| 689 | .sh_offset = phdr.p_offset, |
| 690 | .sh_size = phdr.p_filesz, |
| 691 | .sh_link = 0, |
| 692 | .sh_info = 0, |
| 693 | .sh_addralign = @as(u16, ptr_size), |
| 694 | .sh_entsize = 0, |
| 695 | }); |
| 696 | try self.phdr_to_shdr_table.putNoClobber(gpa, self.bss_section_index.?, self.phdr_load_zerofill_index.?); |
| 697 | try self.last_atom_and_free_list_table.putNoClobber(gpa, self.bss_section_index.?, .{}); |
| 698 | self.shdr_table_dirty = true; |
| 699 | } |
| 700 | |
| 658 | 701 | if (self.symtab_section_index == null) { |
| 659 | 702 | self.symtab_section_index = @as(u16, @intCast(self.shdrs.items.len)); |
| 660 | 703 | const min_align: u16 = if (small_ptr) @alignOf(elf.Elf32_Sym) else @alignOf(elf.Elf64_Sym); |
| ... | ... | @@ -868,8 +911,9 @@ pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void { |
| 868 | 911 | const shdr = &self.shdrs.items[shdr_index]; |
| 869 | 912 | const phdr_index = self.phdr_to_shdr_table.get(shdr_index).?; |
| 870 | 913 | const phdr = &self.phdrs.items[phdr_index]; |
| 914 | const is_zerofill = shdr.sh_type == elf.SHT_NOBITS; |
| 871 | 915 | |
| 872 | | if (needed_size > self.allocatedSize(shdr.sh_offset)) { |
| 916 | if (needed_size > self.allocatedSize(shdr.sh_offset) and !is_zerofill) { |
| 873 | 917 | // Must move the entire section. |
| 874 | 918 | const new_offset = self.findFreeSpace(needed_size, self.page_size); |
| 875 | 919 | const existing_size = if (self.last_atom_and_free_list_table.get(shdr_index)) |meta| blk: { |
| ... | ... | @@ -893,7 +937,10 @@ pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void { |
| 893 | 937 | |
| 894 | 938 | shdr.sh_size = needed_size; |
| 895 | 939 | phdr.p_memsz = needed_size; |
| 896 | | phdr.p_filesz = needed_size; |
| 940 | |
| 941 | if (!is_zerofill) { |
| 942 | phdr.p_filesz = needed_size; |
| 943 | } |
| 897 | 944 | |
| 898 | 945 | self.markDirty(shdr_index, phdr_index); |
| 899 | 946 | } |