From d06aa21e484e891db208003d9814499586d80006 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 2 Oct 2023 14:45:21 +0200 Subject: [PATCH] elf: for now always update .shstrtab and .strtab sections --- src/link/Elf.zig | 105 ++++++++++++++++++++--------------------------- 1 file changed, 45 insertions(+), 60 deletions(-) diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 72de224eda..91865b461f 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -111,8 +111,6 @@ symbols_free_list: std.ArrayListUnmanaged(Symbol.Index) = .{}, phdr_table_dirty: bool = false, shdr_table_dirty: bool = false, -shstrtab_dirty: bool = false, -strtab_dirty: bool = false, got_dirty: bool = false, debug_strtab_dirty: bool = false, @@ -723,24 +721,6 @@ pub fn populateMissingMetadata(self: *Elf) !void { } } - if (self.shstrtab_section_index == null) { - self.shstrtab_section_index = try self.allocateNonAllocSection(.{ - .name = ".shstrtab", - .size = @intCast(self.shstrtab.buffer.items.len), - .type = elf.SHT_STRTAB, - }); - self.shstrtab_dirty = true; - } - - if (self.strtab_section_index == null) { - self.strtab_section_index = try self.allocateNonAllocSection(.{ - .name = ".strtab", - .size = @intCast(self.strtab.buffer.items.len), - .type = elf.SHT_STRTAB, - }); - self.strtab_dirty = true; - } - if (self.text_section_index == null) { self.text_section_index = try self.allocateAllocSection(.{ .name = ".text", @@ -1375,11 +1355,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node } else null; } - // Generate and emit non-incremental sections. - try self.initSyntheticSections(); - try self.updateSyntheticSectionSizes(); - try self.writeSyntheticSections(); - if (self.dwarf) |*dw| { if (self.debug_abbrev_section_dirty) { try dw.writeDbgAbbrev(); @@ -1416,8 +1391,22 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node try dw.writeDbgLineHeader(); self.debug_line_header_dirty = false; } + + if (self.debug_str_section_index) |index| { + if (self.debug_strtab_dirty or dw.strtab.buffer.items.len != self.shdrs.items[index].sh_size) { + try self.growNonAllocSection(index, dw.strtab.buffer.items.len, 1, false); + const shdr = self.shdrs.items[index]; + try self.base.file.?.pwriteAll(dw.strtab.buffer.items, shdr.sh_offset); + self.debug_strtab_dirty = false; + } + } } + // Generate and emit non-incremental sections. + try self.initSyntheticSections(); + try self.updateSyntheticSectionSizes(); + try self.writeSyntheticSections(); + if (self.phdr_table_dirty) { const phsize: u64 = switch (self.ptr_width) { .p32 => @sizeOf(elf.Elf32_Phdr), @@ -1480,36 +1469,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node self.phdr_table_dirty = false; } - { - const shdr_index = self.shstrtab_section_index.?; - if (self.shstrtab_dirty or self.shstrtab.buffer.items.len != self.shdrs.items[shdr_index].sh_size) { - try self.growNonAllocSection(shdr_index, self.shstrtab.buffer.items.len, 1, false); - const shstrtab_sect = &self.shdrs.items[shdr_index]; - try self.base.file.?.pwriteAll(self.shstrtab.buffer.items, shstrtab_sect.sh_offset); - self.shstrtab_dirty = false; - } - } - - { - const shdr_index = self.strtab_section_index.?; - if (self.strtab_dirty or self.strtab.buffer.items.len != self.shdrs.items[shdr_index].sh_size) { - try self.growNonAllocSection(shdr_index, self.strtab.buffer.items.len, 1, false); - const strtab_sect = self.shdrs.items[shdr_index]; - try self.base.file.?.pwriteAll(self.strtab.buffer.items, strtab_sect.sh_offset); - self.strtab_dirty = false; - } - } - - if (self.dwarf) |dwarf| { - const shdr_index = self.debug_str_section_index.?; - if (self.debug_strtab_dirty or dwarf.strtab.buffer.items.len != self.shdrs.items[shdr_index].sh_size) { - try self.growNonAllocSection(shdr_index, dwarf.strtab.buffer.items.len, 1, false); - const debug_strtab_sect = self.shdrs.items[shdr_index]; - try self.base.file.?.pwriteAll(dwarf.strtab.buffer.items, debug_strtab_sect.sh_offset); - self.debug_strtab_dirty = false; - } - } - if (self.shdr_table_dirty) { const shsize: u64 = switch (self.ptr_width) { .p32 => @sizeOf(elf.Elf32_Shdr), @@ -1580,8 +1539,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node assert(!self.debug_aranges_section_dirty); assert(!self.phdr_table_dirty); assert(!self.shdr_table_dirty); - assert(!self.shstrtab_dirty); - assert(!self.strtab_dirty); assert(!self.debug_strtab_dirty); assert(!self.got.dirty); } @@ -3523,12 +3480,34 @@ fn initSyntheticSections(self: *Elf) !void { .entsize = if (small_ptr) @sizeOf(elf.Elf32_Sym) else @sizeOf(elf.Elf64_Sym), }); } + if (self.strtab_section_index == null) { + self.strtab_section_index = try self.addSection(.{ + .name = ".strtab", + .type = elf.SHT_STRTAB, + .entsize = 1, + .addralign = 1, + }); + } + if (self.shstrtab_section_index == null) { + self.shstrtab_section_index = try self.addSection(.{ + .name = ".shstrtab", + .type = elf.SHT_STRTAB, + .entsize = 1, + .addralign = 1, + }); + } } fn updateSyntheticSectionSizes(self: *Elf) !void { if (self.symtab_section_index != null) { try self.updateSymtabSize(); } + if (self.strtab_section_index) |index| { + try self.growNonAllocSection(index, self.strtab.buffer.items.len, 1, false); + } + if (self.shstrtab_section_index) |index| { + try self.growNonAllocSection(index, self.shstrtab.buffer.items.len, 1, false); + } } fn updateSymtabSize(self: *Elf) !void { @@ -3562,7 +3541,6 @@ fn updateSymtabSize(self: *Elf) !void { const shdr = &self.shdrs.items[self.symtab_section_index.?]; shdr.sh_info = sizes.nlocals + 1; shdr.sh_link = self.strtab_section_index.?; - self.markDirty(self.symtab_section_index.?, null); const sym_size: u64 = switch (self.ptr_width) { .p32 => @sizeOf(elf.Elf32_Sym), @@ -3573,11 +3551,18 @@ fn updateSymtabSize(self: *Elf) !void { .p64 => @alignOf(elf.Elf64_Sym), }; const needed_size = (sizes.nlocals + sizes.nglobals + 1) * sym_size; - shdr.sh_size = needed_size; - try self.growNonAllocSection(self.symtab_section_index.?, needed_size, sym_align, true); + try self.growNonAllocSection(self.symtab_section_index.?, needed_size, sym_align, false); } fn writeSyntheticSections(self: *Elf) !void { + if (self.shstrtab_section_index) |index| { + const shdr = self.shdrs.items[index]; + try self.base.file.?.pwriteAll(self.shstrtab.buffer.items, shdr.sh_offset); + } + if (self.strtab_section_index) |index| { + const shdr = self.shdrs.items[index]; + try self.base.file.?.pwriteAll(self.strtab.buffer.items, shdr.sh_offset); + } if (self.symtab_section_index) |_| { try self.writeSymtab(); }