authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-02 10:32:21+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-02 15:17:44+02:00
logda56727e6a50286992b025ce8ef39bd3dc88c630
tree1b8e982744e65dbc01e6ed3508debcc459b3c0b8
parentcf3a6fe0f539fd07d99701a06d0c3672ef0992c2

elf: write symbol names into .strtab rather than .shstrtab


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

src/link/Elf.zig+64-22
......@@ -129,8 +129,10 @@ phdr_load_rw_index: ?u16 = null,
129129entry_addr: ?u64 = null,
130130page_size: u32,
131131
132/// .shstrtab buffer
132133shstrtab: StringTable(.strtab) = .{},
133shstrtab_index: ?u16 = null,
134/// .strtab buffer
135strtab: StringTable(.strtab) = .{},
134136
135137symtab_section_index: ?u16 = null,
136138text_section_index: ?u16 = null,
......@@ -142,6 +144,8 @@ debug_abbrev_section_index: ?u16 = null,
142144debug_str_section_index: ?u16 = null,
143145debug_aranges_section_index: ?u16 = null,
144146debug_line_section_index: ?u16 = null,
147shstrtab_section_index: ?u16 = null,
148strtab_section_index: ?u16 = null,
145149
146150/// The same order as in the file. ELF requires global symbols to all be after the
147151/// local symbols, they cannot be mixed. So we must buffer all the global symbols and
......@@ -158,6 +162,7 @@ got_table: TableSection(u32) = .{},
158162phdr_table_dirty: bool = false,
159163shdr_table_dirty: bool = false,
160164shstrtab_dirty: bool = false,
165strtab_dirty: bool = false,
161166got_table_count_dirty: bool = false,
162167
163168debug_strtab_dirty: bool = false,
......@@ -323,6 +328,7 @@ pub fn deinit(self: *Elf) void {
323328
324329 self.program_headers.deinit(gpa);
325330 self.shstrtab.deinit(gpa);
331 self.strtab.deinit(gpa);
326332 self.local_symbols.deinit(gpa);
327333 self.global_symbols.deinit(gpa);
328334 self.global_symbol_free_list.deinit(gpa);
......@@ -581,12 +587,12 @@ pub fn populateMissingMetadata(self: *Elf) !void {
581587 self.phdr_table_dirty = true;
582588 }
583589
584 if (self.shstrtab_index == null) {
585 self.shstrtab_index = @as(u16, @intCast(self.sections.slice().len));
590 if (self.shstrtab_section_index == null) {
591 self.shstrtab_section_index = @as(u16, @intCast(self.sections.slice().len));
586592 assert(self.shstrtab.buffer.items.len == 0);
587593 try self.shstrtab.buffer.append(gpa, 0); // need a 0 at position 0
588594 const off = self.findFreeSpace(self.shstrtab.buffer.items.len, 1);
589 log.debug("found shstrtab free space 0x{x} to 0x{x}", .{ off, off + self.shstrtab.buffer.items.len });
595 log.debug("found .shstrtab free space 0x{x} to 0x{x}", .{ off, off + self.shstrtab.buffer.items.len });
590596 try self.sections.append(gpa, .{
591597 .shdr = .{
592598 .sh_name = try self.shstrtab.insert(gpa, ".shstrtab"),
......@@ -606,6 +612,31 @@ pub fn populateMissingMetadata(self: *Elf) !void {
606612 self.shdr_table_dirty = true;
607613 }
608614
615 if (self.strtab_section_index == null) {
616 self.strtab_section_index = @as(u16, @intCast(self.sections.slice().len));
617 assert(self.strtab.buffer.items.len == 0);
618 try self.strtab.buffer.append(gpa, 0); // need a 0 at position 0
619 const off = self.findFreeSpace(self.strtab.buffer.items.len, 1);
620 log.debug("found .strtab free space 0x{x} to 0x{x}", .{ off, off + self.strtab.buffer.items.len });
621 try self.sections.append(gpa, .{
622 .shdr = .{
623 .sh_name = try self.shstrtab.insert(gpa, ".strtab"),
624 .sh_type = elf.SHT_STRTAB,
625 .sh_flags = 0,
626 .sh_addr = 0,
627 .sh_offset = off,
628 .sh_size = self.strtab.buffer.items.len,
629 .sh_link = 0,
630 .sh_info = 0,
631 .sh_addralign = 1,
632 .sh_entsize = 0,
633 },
634 .phdr_index = undefined,
635 });
636 self.strtab_dirty = true;
637 self.shdr_table_dirty = true;
638 }
639
609640 if (self.text_section_index == null) {
610641 self.text_section_index = @as(u16, @intCast(self.sections.slice().len));
611642 const phdr = &self.program_headers.items[self.phdr_load_re_index.?];
......@@ -711,7 +742,7 @@ pub fn populateMissingMetadata(self: *Elf) !void {
711742 .sh_offset = off,
712743 .sh_size = file_size,
713744 // The section header index of the associated string table.
714 .sh_link = self.shstrtab_index.?,
745 .sh_link = self.strtab_section_index.?,
715746 .sh_info = @as(u32, @intCast(self.local_symbols.items.len)),
716747 .sh_addralign = min_align,
717748 .sh_entsize = each_size,
......@@ -1076,7 +1107,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
10761107 const source_sym = atom.getSymbol(self);
10771108 const source_shdr = self.sections.items(.shdr)[source_sym.st_shndx];
10781109
1079 log.debug("relocating '{?s}'", .{self.shstrtab.get(source_sym.st_name)});
1110 log.debug("relocating '{?s}'", .{self.strtab.get(source_sym.st_name)});
10801111
10811112 for (relocs.items) |*reloc| {
10821113 const target_sym = self.local_symbols.items[reloc.target];
......@@ -1090,7 +1121,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
10901121 log.debug(" ({x}: [() => 0x{x}] ({?s}))", .{
10911122 reloc.offset,
10921123 target_vaddr,
1093 self.shstrtab.get(target_sym.st_name),
1124 self.strtab.get(target_sym.st_name),
10941125 });
10951126
10961127 switch (self.ptr_width) {
......@@ -1212,7 +1243,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
12121243 }
12131244
12141245 {
1215 const shdr_index = self.shstrtab_index.?;
1246 const shdr_index = self.shstrtab_section_index.?;
12161247 if (self.shstrtab_dirty or self.shstrtab.buffer.items.len != self.sections.items(.shdr)[shdr_index].sh_size) {
12171248 try self.growNonAllocSection(shdr_index, self.shstrtab.buffer.items.len, 1, false);
12181249 const shstrtab_sect = self.sections.items(.shdr)[shdr_index];
......@@ -1221,6 +1252,16 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
12211252 }
12221253 }
12231254
1255 {
1256 const shdr_index = self.strtab_section_index.?;
1257 if (self.strtab_dirty or self.strtab.buffer.items.len != self.sections.items(.shdr)[shdr_index].sh_size) {
1258 try self.growNonAllocSection(shdr_index, self.strtab.buffer.items.len, 1, false);
1259 const strtab_sect = self.sections.items(.shdr)[shdr_index];
1260 try self.base.file.?.pwriteAll(self.strtab.buffer.items, strtab_sect.sh_offset);
1261 self.strtab_dirty = false;
1262 }
1263 }
1264
12241265 if (self.dwarf) |dwarf| {
12251266 const shdr_index = self.debug_str_section_index.?;
12261267 if (self.debug_strtab_dirty or dwarf.strtab.buffer.items.len != self.sections.items(.shdr)[shdr_index].sh_size) {
......@@ -1298,6 +1339,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
12981339 assert(!self.phdr_table_dirty);
12991340 assert(!self.shdr_table_dirty);
13001341 assert(!self.shstrtab_dirty);
1342 assert(!self.strtab_dirty);
13011343 assert(!self.debug_strtab_dirty);
13021344 assert(!self.got_table_count_dirty);
13031345}
......@@ -2115,7 +2157,7 @@ fn writeElfHeader(self: *Elf) !void {
21152157 mem.writeInt(u16, hdr_buf[index..][0..2], e_shnum, endian);
21162158 index += 2;
21172159
2118 mem.writeInt(u16, hdr_buf[index..][0..2], self.shstrtab_index.?, endian);
2160 mem.writeInt(u16, hdr_buf[index..][0..2], self.shstrtab_section_index.?, endian);
21192161 index += 2;
21202162
21212163 assert(index == e_ehsize);
......@@ -2485,7 +2527,7 @@ fn updateDeclCode(self: *Elf, decl_index: Module.Decl.Index, code: []const u8, s
24852527 const shdr_index = decl_metadata.shdr;
24862528 if (atom.getSymbol(self).st_size != 0 and self.base.child_pid == null) {
24872529 const local_sym = atom.getSymbolPtr(self);
2488 local_sym.st_name = try self.shstrtab.insert(gpa, decl_name);
2530 local_sym.st_name = try self.strtab.insert(gpa, decl_name);
24892531 local_sym.st_info = (elf.STB_LOCAL << 4) | stt_bits;
24902532 local_sym.st_other = 0;
24912533 local_sym.st_shndx = shdr_index;
......@@ -2515,7 +2557,7 @@ fn updateDeclCode(self: *Elf, decl_index: Module.Decl.Index, code: []const u8, s
25152557 } else {
25162558 const local_sym = atom.getSymbolPtr(self);
25172559 local_sym.* = .{
2518 .st_name = try self.shstrtab.insert(gpa, decl_name),
2560 .st_name = try self.strtab.insert(gpa, decl_name),
25192561 .st_info = (elf.STB_LOCAL << 4) | stt_bits,
25202562 .st_other = 0,
25212563 .st_shndx = shdr_index,
......@@ -2716,9 +2758,9 @@ fn updateLazySymbolAtom(
27162758 sym.ty.fmt(mod),
27172759 });
27182760 defer gpa.free(name);
2719 break :blk try self.shstrtab.insert(gpa, name);
2761 break :blk try self.strtab.insert(gpa, name);
27202762 };
2721 const name = self.shstrtab.get(name_str_index).?;
2763 const name = self.strtab.get(name_str_index).?;
27222764
27232765 const atom = self.getAtom(atom_index);
27242766 const local_sym_index = atom.getSymbolIndex().?;
......@@ -2793,9 +2835,9 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module
27932835 const index = unnamed_consts.items.len;
27942836 const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
27952837 defer gpa.free(name);
2796 break :blk try self.shstrtab.insert(gpa, name);
2838 break :blk try self.strtab.insert(gpa, name);
27972839 };
2798 const name = self.shstrtab.get(name_str_index).?;
2840 const name = self.strtab.get(name_str_index).?;
27992841
28002842 const atom_index = try self.createAtom();
28012843
......@@ -2900,7 +2942,7 @@ pub fn updateDeclExports(
29002942 if (decl_metadata.getExport(self, exp_name)) |i| {
29012943 const sym = &self.global_symbols.items[i];
29022944 sym.* = .{
2903 .st_name = try self.shstrtab.insert(gpa, exp_name),
2945 .st_name = try self.strtab.insert(gpa, exp_name),
29042946 .st_info = (stb_bits << 4) | stt_bits,
29052947 .st_other = 0,
29062948 .st_shndx = shdr_index,
......@@ -2914,7 +2956,7 @@ pub fn updateDeclExports(
29142956 };
29152957 try decl_metadata.exports.append(gpa, @as(u32, @intCast(i)));
29162958 self.global_symbols.items[i] = .{
2917 .st_name = try self.shstrtab.insert(gpa, exp_name),
2959 .st_name = try self.strtab.insert(gpa, exp_name),
29182960 .st_info = (stb_bits << 4) | stt_bits,
29192961 .st_other = 0,
29202962 .st_shndx = shdr_index,
......@@ -3080,7 +3122,7 @@ fn writeSymbol(self: *Elf, index: usize) !void {
30803122 .p64 => syms_sect.sh_offset + @sizeOf(elf.Elf64_Sym) * index,
30813123 };
30823124 const local = self.local_symbols.items[index];
3083 log.debug("writing symbol {d}, '{?s}' at 0x{x}", .{ index, self.shstrtab.get(local.st_name), off });
3125 log.debug("writing symbol {d}, '{?s}' at 0x{x}", .{ index, self.strtab.get(local.st_name), off });
30843126 log.debug(" ({})", .{local});
30853127 switch (self.ptr_width) {
30863128 .p32 => {
......@@ -3460,11 +3502,11 @@ const CsuObjects = struct {
34603502fn logSymtab(self: Elf) void {
34613503 log.debug("locals:", .{});
34623504 for (self.local_symbols.items, 0..) |sym, id| {
3463 log.debug(" {d}: {?s}: @{x} in {d}", .{ id, self.shstrtab.get(sym.st_name), sym.st_value, sym.st_shndx });
3505 log.debug(" {d}: {?s}: @{x} in {d}", .{ id, self.strtab.get(sym.st_name), sym.st_value, sym.st_shndx });
34643506 }
34653507 log.debug("globals:", .{});
34663508 for (self.global_symbols.items, 0..) |sym, id| {
3467 log.debug(" {d}: {?s}: @{x} in {d}", .{ id, self.shstrtab.get(sym.st_name), sym.st_value, sym.st_shndx });
3509 log.debug(" {d}: {?s}: @{x} in {d}", .{ id, self.strtab.get(sym.st_name), sym.st_value, sym.st_shndx });
34683510 }
34693511}
34703512
......@@ -3491,13 +3533,13 @@ pub fn getSymbol(self: *const Elf, sym_index: u32) elf.Elf64_Sym {
34913533/// Returns name of the symbol at sym_index.
34923534pub fn getSymbolName(self: *const Elf, sym_index: u32) []const u8 {
34933535 const sym = self.local_symbols.items[sym_index];
3494 return self.shstrtab.get(sym.st_name).?;
3536 return self.strtab.get(sym.st_name).?;
34953537}
34963538
34973539/// Returns name of the global symbol at index.
34983540pub fn getGlobalName(self: *const Elf, index: u32) []const u8 {
34993541 const sym = self.global_symbols.items[index];
3500 return self.shstrtab.get(sym.st_name).?;
3542 return self.strtab.get(sym.st_name).?;
35013543}
35023544
35033545pub fn getAtom(self: *const Elf, atom_index: Atom.Index) Atom {