authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-02 13:44:15+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-16 19:33:03+02:00
logc8c50a058e4d18a47724c489a2b9b7e3316c105a
tree029c5c657ea379a1a228514e677b5f5cd63ec6fb
parent52f8a1a24c274c7ad6b28562498da0b58e91ccbf

elf: do not prealloc space for .symtab


1 files changed, 63 insertions(+), 22 deletions(-)

src/link/Elf.zig+63-22
...@@ -604,10 +604,6 @@ fn allocateNonAllocSection(self: *Elf, opts: AllocateNonAllocSectionOpts) error{...@@ -604,10 +604,6 @@ fn allocateNonAllocSection(self: *Elf, opts: AllocateNonAllocSectionOpts) error{
604604
605pub fn populateMissingMetadata(self: *Elf) !void {605pub 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 }
828824
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 }
14061387
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();
14101392
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}
35393521
3522fn 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
3539fn updateSyntheticSectionSizes(self: *Elf) !void {
3540 if (self.symtab_section_index != null) {
3541 try self.updateSymtabSize();
3542 }
3543}
3544
3540fn updateSymtabSize(self: *Elf) !void {3545fn updateSymtabSize(self: *Elf) !void {
3541 var sizes = SymtabSize{};3546 var sizes = SymtabSize{};
35423547
...@@ -3567,6 +3572,7 @@ fn updateSymtabSize(self: *Elf) !void {...@@ -3567,6 +3572,7 @@ fn updateSymtabSize(self: *Elf) !void {
35673572
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);
35713577
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}
35843590
3591fn writeSyntheticSections(self: *Elf) !void {
3592 if (self.symtab_section_index) |_| {
3593 try self.writeSymtab();
3594 }
3595}
3596
3585fn writeSymtab(self: *Elf) !void {3597fn 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}
39853997
3998pub 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
4008pub 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
3986pub fn sectionByName(self: *Elf, name: [:0]const u8) ?u16 {4027pub 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);