| ... | @@ -604,10 +604,6 @@ fn allocateNonAllocSection(self: *Elf, opts: AllocateNonAllocSectionOpts) error{ | ... | @@ -604,10 +604,6 @@ fn allocateNonAllocSection(self: *Elf, opts: AllocateNonAllocSectionOpts) error{ |
| 604 | | 604 | |
| 605 | pub fn populateMissingMetadata(self: *Elf) !void { | 605 | pub fn populateMissingMetadata(self: *Elf) !void { |
| 606 | const gpa = self.base.allocator; | 606 | const gpa = self.base.allocator; |
| 607 | const small_ptr = switch (self.ptr_width) { | | |
| 608 | .p32 => true, | | |
| 609 | .p64 => false, | | |
| 610 | }; | | |
| 611 | const ptr_size: u8 = self.ptrWidthBytes(); | 607 | const ptr_size: u8 = self.ptrWidthBytes(); |
| 612 | const is_linux = self.base.options.target.os.tag == .linux; | 608 | const is_linux = self.base.options.target.os.tag == .linux; |
| 613 | const image_base = self.calcImageBase(); | 609 | const image_base = self.calcImageBase(); |
| ... | @@ -826,21 +822,6 @@ pub fn populateMissingMetadata(self: *Elf) !void { | ... | @@ -826,21 +822,6 @@ pub fn populateMissingMetadata(self: *Elf) !void { |
| 826 | } | 822 | } |
| 827 | } | 823 | } |
| 828 | | 824 | |
| 829 | if (self.symtab_section_index == null) { | | |
| 830 | const min_align: u16 = if (small_ptr) @alignOf(elf.Elf32_Sym) else @alignOf(elf.Elf64_Sym); | | |
| 831 | const each_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Sym) else @sizeOf(elf.Elf64_Sym); | | |
| 832 | self.symtab_section_index = try self.allocateNonAllocSection(.{ | | |
| 833 | .name = ".symtab", | | |
| 834 | .size = self.base.options.symbol_count_hint * each_size, | | |
| 835 | .alignment = min_align, | | |
| 836 | .type = elf.SHT_SYMTAB, | | |
| 837 | .link = self.strtab_section_index.?, // Index of associated string table | | |
| 838 | .info = @intCast(self.symbols.items.len), | | |
| 839 | .entsize = each_size, | | |
| 840 | }); | | |
| 841 | self.shdr_table_dirty = true; | | |
| 842 | } | | |
| 843 | | | |
| 844 | if (self.dwarf) |*dw| { | 825 | if (self.dwarf) |*dw| { |
| 845 | if (self.debug_str_section_index == null) { | 826 | if (self.debug_str_section_index == null) { |
| 846 | assert(dw.strtab.buffer.items.len == 0); | 827 | assert(dw.strtab.buffer.items.len == 0); |
| ... | @@ -1404,9 +1385,10 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1404,9 +1385,10 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1404 | } else null; | 1385 | } else null; |
| 1405 | } | 1386 | } |
| 1406 | | 1387 | |
| 1407 | // Generate and emit the symbol table. | 1388 | // Generate and emit non-incremental sections. |
| 1408 | try self.updateSymtabSize(); | 1389 | try self.initSyntheticSections(); |
| 1409 | try self.writeSymtab(); | 1390 | try self.updateSyntheticSectionSizes(); |
| | 1391 | try self.writeSyntheticSections(); |
| 1410 | | 1392 | |
| 1411 | if (self.dwarf) |*dw| { | 1393 | if (self.dwarf) |*dw| { |
| 1412 | if (self.debug_abbrev_section_dirty) { | 1394 | if (self.debug_abbrev_section_dirty) { |
| ... | @@ -3537,6 +3519,29 @@ fn allocateLinkerDefinedSymbols(self: *Elf) void { | ... | @@ -3537,6 +3519,29 @@ fn allocateLinkerDefinedSymbols(self: *Elf) void { |
| 3537 | } | 3519 | } |
| 3538 | } | 3520 | } |
| 3539 | | 3521 | |
| | 3522 | fn initSyntheticSections(self: *Elf) !void { |
| | 3523 | const small_ptr = switch (self.ptr_width) { |
| | 3524 | .p32 => true, |
| | 3525 | .p64 => false, |
| | 3526 | }; |
| | 3527 | |
| | 3528 | if (self.symtab_section_index == null) { |
| | 3529 | self.symtab_section_index = try self.addSection(.{ |
| | 3530 | .name = ".symtab", |
| | 3531 | .type = elf.SHT_SYMTAB, |
| | 3532 | .addralign = if (small_ptr) @alignOf(elf.Elf32_Sym) else @alignOf(elf.Elf64_Sym), |
| | 3533 | .entsize = if (small_ptr) @sizeOf(elf.Elf32_Sym) else @sizeOf(elf.Elf64_Sym), |
| | 3534 | }); |
| | 3535 | self.shdr_table_dirty = true; |
| | 3536 | } |
| | 3537 | } |
| | 3538 | |
| | 3539 | fn updateSyntheticSectionSizes(self: *Elf) !void { |
| | 3540 | if (self.symtab_section_index != null) { |
| | 3541 | try self.updateSymtabSize(); |
| | 3542 | } |
| | 3543 | } |
| | 3544 | |
| 3540 | fn updateSymtabSize(self: *Elf) !void { | 3545 | fn updateSymtabSize(self: *Elf) !void { |
| 3541 | var sizes = SymtabSize{}; | 3546 | var sizes = SymtabSize{}; |
| 3542 | | 3547 | |
| ... | @@ -3567,6 +3572,7 @@ fn updateSymtabSize(self: *Elf) !void { | ... | @@ -3567,6 +3572,7 @@ fn updateSymtabSize(self: *Elf) !void { |
| 3567 | | 3572 | |
| 3568 | const shdr = &self.shdrs.items[self.symtab_section_index.?]; | 3573 | const shdr = &self.shdrs.items[self.symtab_section_index.?]; |
| 3569 | shdr.sh_info = sizes.nlocals + 1; | 3574 | shdr.sh_info = sizes.nlocals + 1; |
| | 3575 | shdr.sh_link = self.strtab_section_index.?; |
| 3570 | self.markDirty(self.symtab_section_index.?, null); | 3576 | self.markDirty(self.symtab_section_index.?, null); |
| 3571 | | 3577 | |
| 3572 | const sym_size: u64 = switch (self.ptr_width) { | 3578 | const sym_size: u64 = switch (self.ptr_width) { |
| ... | @@ -3582,6 +3588,12 @@ fn updateSymtabSize(self: *Elf) !void { | ... | @@ -3582,6 +3588,12 @@ fn updateSymtabSize(self: *Elf) !void { |
| 3582 | try self.growNonAllocSection(self.symtab_section_index.?, needed_size, sym_align, true); | 3588 | try self.growNonAllocSection(self.symtab_section_index.?, needed_size, sym_align, true); |
| 3583 | } | 3589 | } |
| 3584 | | 3590 | |
| | 3591 | fn writeSyntheticSections(self: *Elf) !void { |
| | 3592 | if (self.symtab_section_index) |_| { |
| | 3593 | try self.writeSymtab(); |
| | 3594 | } |
| | 3595 | } |
| | 3596 | |
| 3585 | fn writeSymtab(self: *Elf) !void { | 3597 | fn writeSymtab(self: *Elf) !void { |
| 3586 | const gpa = self.base.allocator; | 3598 | const gpa = self.base.allocator; |
| 3587 | const shdr = &self.shdrs.items[self.symtab_section_index.?]; | 3599 | const shdr = &self.shdrs.items[self.symtab_section_index.?]; |
| ... | @@ -3983,6 +3995,35 @@ pub fn isDynLib(self: Elf) bool { | ... | @@ -3983,6 +3995,35 @@ pub fn isDynLib(self: Elf) bool { |
| 3983 | return self.base.options.output_mode == .Lib and self.base.options.link_mode == .Dynamic; | 3995 | return self.base.options.output_mode == .Lib and self.base.options.link_mode == .Dynamic; |
| 3984 | } | 3996 | } |
| 3985 | | 3997 | |
| | 3998 | pub const AddSectionOpts = struct { |
| | 3999 | name: [:0]const u8, |
| | 4000 | type: u32 = elf.SHT_NULL, |
| | 4001 | flags: u64 = 0, |
| | 4002 | link: u32 = 0, |
| | 4003 | info: u32 = 0, |
| | 4004 | addralign: u64 = 0, |
| | 4005 | entsize: u64 = 0, |
| | 4006 | }; |
| | 4007 | |
| | 4008 | pub fn addSection(self: *Elf, opts: AddSectionOpts) !u16 { |
| | 4009 | const gpa = self.base.allocator; |
| | 4010 | const index = @as(u16, @intCast(self.shdrs.items.len)); |
| | 4011 | const shdr = try self.shdrs.addOne(gpa); |
| | 4012 | shdr.* = .{ |
| | 4013 | .sh_name = try self.shstrtab.insert(gpa, opts.name), |
| | 4014 | .sh_type = opts.type, |
| | 4015 | .sh_flags = opts.flags, |
| | 4016 | .sh_addr = 0, |
| | 4017 | .sh_offset = 0, |
| | 4018 | .sh_size = 0, |
| | 4019 | .sh_link = 0, |
| | 4020 | .sh_info = opts.info, |
| | 4021 | .sh_addralign = opts.addralign, |
| | 4022 | .sh_entsize = opts.entsize, |
| | 4023 | }; |
| | 4024 | return index; |
| | 4025 | } |
| | 4026 | |
| 3986 | pub fn sectionByName(self: *Elf, name: [:0]const u8) ?u16 { | 4027 | pub fn sectionByName(self: *Elf, name: [:0]const u8) ?u16 { |
| 3987 | for (self.shdrs.items, 0..) |*shdr, i| { | 4028 | for (self.shdrs.items, 0..) |*shdr, i| { |
| 3988 | const this_name = self.shstrtab.getAssumeExists(shdr.sh_name); | 4029 | const this_name = self.shstrtab.getAssumeExists(shdr.sh_name); |