authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-26 16:23:38+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-30 10:00:50+02:00
log24126f5382c09f54d8344208e6e38df632d35a44
tree88f4451ab9cbbe3625cd2c2a5782c0f65f66d049
parente8d008a8a83f10b8400691bef216147e08ac2daf

elf: simplify output section tracking for symbols


8 files changed, 22 insertions(+), 97 deletions(-)

src/link/Elf.zig-15
......@@ -4121,21 +4121,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void {
41214121 const atom_ptr = zo.atom(atom_index) orelse continue;
41224122 atom_ptr.output_section_index = backlinks[atom_ptr.output_section_index];
41234123 }
4124
4125 for (zo.locals()) |local_index| {
4126 const local = self.symbol(local_index);
4127 local.output_section_index = backlinks[local.output_section_index];
4128 }
4129
4130 for (zo.globals()) |global_index| {
4131 const global = self.symbol(global_index);
4132 const atom_ptr = global.atom(self) orelse continue;
4133 if (!atom_ptr.alive) continue;
4134 // TODO claim unresolved for objects
4135 if (global.file(self).?.index() != zo.index) continue;
4136 const out_shndx = global.outputShndx() orelse continue;
4137 global.output_section_index = backlinks[out_shndx];
4138 }
41394124 }
41404125
41414126 for (self.output_rela_sections.keys(), self.output_rela_sections.values()) |shndx, sec| {
src/link/Elf/Atom.zig+2-5
......@@ -337,12 +337,9 @@ pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.El
337337 var r_addend = rel.r_addend;
338338 var r_sym: u32 = 0;
339339 switch (target.type(elf_file)) {
340 elf.STT_SECTION => if (target.mergeSubsection(elf_file)) |msub| {
340 elf.STT_SECTION => {
341341 r_addend += @intCast(target.address(.{}, elf_file));
342 r_sym = elf_file.sectionSymbolOutputSymtabIndex(msub.mergeSection(elf_file).output_section_index);
343 } else {
344 r_addend += @intCast(target.address(.{}, elf_file));
345 r_sym = if (target.outputShndx()) |osec|
342 r_sym = if (target.outputShndx(elf_file)) |osec|
346343 elf_file.sectionSymbolOutputSymtabIndex(osec)
347344 else
348345 0;
src/link/Elf/Object.zig-32
......@@ -978,38 +978,6 @@ pub fn addAtomsToOutputSections(self: *Object, elf_file: *Elf) !void {
978978 if (!gop.found_existing) gop.value_ptr.* = .{};
979979 try gop.value_ptr.append(gpa, .{ .index = atom_index, .file = self.index });
980980 }
981
982 for (self.locals()) |local_index| {
983 const local = elf_file.symbol(local_index);
984 if (local.mergeSubsection(elf_file)) |msub| {
985 if (!msub.alive) continue;
986 local.output_section_index = msub.mergeSection(elf_file).output_section_index;
987 continue;
988 }
989 const atom_ptr = local.atom(elf_file) orelse continue;
990 if (!atom_ptr.alive) continue;
991 local.output_section_index = atom_ptr.output_section_index;
992 }
993
994 for (self.globals()) |global_index| {
995 const global = elf_file.symbol(global_index);
996 if (global.file(elf_file).?.index() != self.index) continue;
997 if (global.mergeSubsection(elf_file)) |msub| {
998 if (!msub.alive) continue;
999 global.output_section_index = msub.mergeSection(elf_file).output_section_index;
1000 continue;
1001 }
1002 const atom_ptr = global.atom(elf_file) orelse continue;
1003 if (!atom_ptr.alive) continue;
1004 global.output_section_index = atom_ptr.output_section_index;
1005 }
1006
1007 for (self.symbols.items[self.symtab.items.len..]) |local_index| {
1008 const local = elf_file.symbol(local_index);
1009 const msub = local.mergeSubsection(elf_file).?;
1010 if (!msub.alive) continue;
1011 local.output_section_index = msub.mergeSection(elf_file).output_section_index;
1012 }
1013981}
1014982
1015983pub fn initRelaSections(self: *Object, elf_file: *Elf) !void {
src/link/Elf/Symbol.zig+15-10
......@@ -33,11 +33,15 @@ pub fn isAbs(symbol: Symbol, elf_file: *Elf) bool {
3333 const file_ptr = symbol.file(elf_file).?;
3434 if (file_ptr == .shared_object) return symbol.elfSym(elf_file).st_shndx == elf.SHN_ABS;
3535 return !symbol.flags.import and symbol.atom(elf_file) == null and
36 symbol.mergeSubsection(elf_file) == null and symbol.outputShndx() == null and
36 symbol.mergeSubsection(elf_file) == null and symbol.outputShndx(elf_file) == null and
3737 file_ptr != .linker_defined;
3838}
3939
40pub fn outputShndx(symbol: Symbol) ?u32 {
40pub fn outputShndx(symbol: Symbol, elf_file: *Elf) ?u32 {
41 if (symbol.mergeSubsection(elf_file)) |msub|
42 return if (msub.alive) msub.mergeSection(elf_file).output_section_index else null;
43 if (symbol.atom(elf_file)) |atom_ptr|
44 return if (atom_ptr.alive) atom_ptr.output_section_index else null;
4145 if (symbol.output_section_index == 0) return null;
4246 return symbol.output_section_index;
4347}
......@@ -298,7 +302,7 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {
298302 if (elf_file.base.isRelocatable() and esym.st_shndx == elf.SHN_COMMON) break :blk elf.SHN_COMMON;
299303 if (symbol.mergeSubsection(elf_file)) |msub| break :blk @intCast(msub.mergeSection(elf_file).output_section_index);
300304 if (symbol.atom(elf_file) == null and file_ptr != .linker_defined) break :blk elf.SHN_ABS;
301 break :blk @intCast(symbol.outputShndx() orelse elf.SHN_UNDEF);
305 break :blk @intCast(symbol.outputShndx(elf_file) orelse elf.SHN_UNDEF);
302306 };
303307 const st_value = blk: {
304308 if (symbol.flags.has_copy_rel) break :blk symbol.address(.{}, elf_file);
......@@ -382,22 +386,23 @@ fn format2(
382386 _ = options;
383387 _ = unused_fmt_string;
384388 const symbol = ctx.symbol;
389 const elf_file = ctx.elf_file;
385390 try writer.print("%{d} : {s} : @{x}", .{
386391 symbol.esym_index,
387 symbol.fmtName(ctx.elf_file),
388 symbol.address(.{}, ctx.elf_file),
392 symbol.fmtName(elf_file),
393 symbol.address(.{}, elf_file),
389394 });
390 if (symbol.file(ctx.elf_file)) |file_ptr| {
391 if (symbol.isAbs(ctx.elf_file)) {
392 if (symbol.elfSym(ctx.elf_file).st_shndx == elf.SHN_UNDEF) {
395 if (symbol.file(elf_file)) |file_ptr| {
396 if (symbol.isAbs(elf_file)) {
397 if (symbol.elfSym(elf_file).st_shndx == elf.SHN_UNDEF) {
393398 try writer.writeAll(" : undef");
394399 } else {
395400 try writer.writeAll(" : absolute");
396401 }
397 } else if (symbol.outputShndx()) |shndx| {
402 } else if (symbol.outputShndx(elf_file)) |shndx| {
398403 try writer.print(" : shdr({d})", .{shndx});
399404 }
400 if (symbol.atom(ctx.elf_file)) |atom_ptr| {
405 if (symbol.atom(elf_file)) |atom_ptr| {
401406 try writer.print(" : atom({d})", .{atom_ptr.atom_index});
402407 }
403408 var buf: [2]u8 = .{'_'} ** 2;
src/link/Elf/ZigObject.zig+3-13
......@@ -341,15 +341,10 @@ pub fn resolveSymbols(self: *ZigObject, elf_file: *Elf) void {
341341 SHN_ATOM => shndx,
342342 else => unreachable,
343343 };
344 const output_section_index = if (self.atom(atom_index)) |atom_ptr|
345 atom_ptr.output_section_index
346 else
347 elf.SHN_UNDEF;
348344 global.value = @intCast(esym.st_value);
349345 global.atom_ref = .{ .index = atom_index, .file = self.index };
350346 global.esym_index = esym_index;
351347 global.file_index = self.index;
352 global.output_section_index = output_section_index;
353348 global.version_index = elf_file.default_sym_version;
354349 if (esym.st_bind() == elf.STB_WEAK) global.flags.weak = true;
355350 }
......@@ -492,7 +487,7 @@ pub fn updateArSymtab(self: ZigObject, ar_symtab: *Archive.ArSymtab, elf_file: *
492487 const global = elf_file.symbol(global_index);
493488 const file_ptr = global.file(elf_file).?;
494489 assert(file_ptr.index() == self.index);
495 if (global.outputShndx() == null) continue;
490 if (global.outputShndx(elf_file) == null) continue;
496491
497492 const off = try ar_symtab.strtab.insert(gpa, global.name(elf_file));
498493 ar_symtab.symtab.appendAssumeCapacity(.{ .off = off, .file_index = self.index });
......@@ -918,12 +913,10 @@ fn updateDeclCode(
918913 const esym = &self.local_esyms.items(.elf_sym)[sym.esym_index];
919914 const atom_ptr = sym.atom(elf_file).?;
920915
921 sym.output_section_index = shdr_index;
922 atom_ptr.output_section_index = shdr_index;
923
924 sym.name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
925916 atom_ptr.alive = true;
926917 atom_ptr.name_offset = sym.name_offset;
918 atom_ptr.output_section_index = shdr_index;
919 sym.name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
927920 esym.st_name = sym.name_offset;
928921 esym.st_info |= stt_bits;
929922 esym.st_size = code.len;
......@@ -1018,7 +1011,6 @@ fn updateTlv(
10181011 const atom_ptr = sym.atom(elf_file).?;
10191012
10201013 sym.value = 0;
1021 sym.output_section_index = shndx;
10221014 atom_ptr.output_section_index = shndx;
10231015
10241016 sym.name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
......@@ -1240,7 +1232,6 @@ fn updateLazySymbol(
12401232 };
12411233 const local_sym = elf_file.symbol(symbol_index);
12421234 local_sym.name_offset = name_str_index;
1243 local_sym.output_section_index = output_section_index;
12441235 const local_esym = &self.local_esyms.items(.elf_sym)[local_sym.esym_index];
12451236 local_esym.st_name = name_str_index;
12461237 local_esym.st_info |= elf.STT_OBJECT;
......@@ -1348,7 +1339,6 @@ fn lowerConst(
13481339 const local_sym = elf_file.symbol(sym_index);
13491340 const name_str_index = try self.strtab.insert(gpa, name);
13501341 local_sym.name_offset = name_str_index;
1351 local_sym.output_section_index = output_section_index;
13521342 const local_esym = &self.local_esyms.items(.elf_sym)[local_sym.esym_index];
13531343 local_esym.st_name = name_str_index;
13541344 local_esym.st_info |= elf.STT_OBJECT;
src/link/Elf/eh_frame.zig+1-1
......@@ -421,7 +421,7 @@ fn emitReloc(elf_file: *Elf, rec: anytype, sym: *const Symbol, rel: elf.Elf64_Re
421421 switch (sym.type(elf_file)) {
422422 elf.STT_SECTION => {
423423 r_addend += @intCast(sym.address(.{}, elf_file));
424 r_sym = elf_file.sectionSymbolOutputSymtabIndex(sym.outputShndx().?);
424 r_sym = elf_file.sectionSymbolOutputSymtabIndex(sym.outputShndx(elf_file).?);
425425 },
426426 else => {
427427 r_sym = sym.outputSymtabIndex(elf_file) orelse 0;
src/link/Elf/relocatable.zig+1-1
......@@ -382,7 +382,7 @@ fn updateComdatGroupsSizes(elf_file: *Elf) void {
382382
383383 const sym = elf_file.symbol(cg.symbol(elf_file));
384384 shdr.sh_info = sym.outputSymtabIndex(elf_file) orelse
385 elf_file.sectionSymbolOutputSymtabIndex(sym.outputShndx().?);
385 elf_file.sectionSymbolOutputSymtabIndex(sym.outputShndx(elf_file).?);
386386 }
387387}
388388
test/link/elf.zig-20
......@@ -416,16 +416,6 @@ fn testComdatElimination(b: *Build, opts: Options) *Step {
416416 \\
417417 );
418418 test_step.dependOn(&run.step);
419
420 const check = exe.checkObject();
421 check.checkInSymtab();
422 // This weird looking double assertion uses the fact that once we find the symbol in
423 // the symtab, we do not reset the cursor and do subsequent checks from that point onwards.
424 // If this is the case, and COMDAT elimination works correctly we should only have one instance
425 // of foo() function.
426 check.checkContains("_Z3foov");
427 check.checkNotPresent("_Z3foov");
428 test_step.dependOn(&check.step);
429419 }
430420
431421 {
......@@ -441,16 +431,6 @@ fn testComdatElimination(b: *Build, opts: Options) *Step {
441431 \\
442432 );
443433 test_step.dependOn(&run.step);
444
445 const check = exe.checkObject();
446 check.checkInSymtab();
447 // This weird looking double assertion uses the fact that once we find the symbol in
448 // the symtab, we do not reset the cursor and do subsequent checks from that point onwards.
449 // If this is the case, and COMDAT elimination works correctly we should only have one instance
450 // of foo() function.
451 check.checkContains("_Z3foov");
452 check.checkNotPresent("_Z3foov");
453 test_step.dependOn(&check.step);
454434 }
455435
456436 {