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 {...@@ -4121,21 +4121,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void {
4121 const atom_ptr = zo.atom(atom_index) orelse continue;4121 const atom_ptr = zo.atom(atom_index) orelse continue;
4122 atom_ptr.output_section_index = backlinks[atom_ptr.output_section_index];4122 atom_ptr.output_section_index = backlinks[atom_ptr.output_section_index];
4123 }4123 }
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 }
4139 }4124 }
41404125
4141 for (self.output_rela_sections.keys(), self.output_rela_sections.values()) |shndx, sec| {4126 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...@@ -337,12 +337,9 @@ pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.El
337 var r_addend = rel.r_addend;337 var r_addend = rel.r_addend;
338 var r_sym: u32 = 0;338 var r_sym: u32 = 0;
339 switch (target.type(elf_file)) {339 switch (target.type(elf_file)) {
340 elf.STT_SECTION => if (target.mergeSubsection(elf_file)) |msub| {340 elf.STT_SECTION => {
341 r_addend += @intCast(target.address(.{}, elf_file));341 r_addend += @intCast(target.address(.{}, elf_file));
342 r_sym = elf_file.sectionSymbolOutputSymtabIndex(msub.mergeSection(elf_file).output_section_index);342 r_sym = if (target.outputShndx(elf_file)) |osec|
343 } else {
344 r_addend += @intCast(target.address(.{}, elf_file));
345 r_sym = if (target.outputShndx()) |osec|
346 elf_file.sectionSymbolOutputSymtabIndex(osec)343 elf_file.sectionSymbolOutputSymtabIndex(osec)
347 else344 else
348 0;345 0;
src/link/Elf/Object.zig-32
...@@ -978,38 +978,6 @@ pub fn addAtomsToOutputSections(self: *Object, elf_file: *Elf) !void {...@@ -978,38 +978,6 @@ pub fn addAtomsToOutputSections(self: *Object, elf_file: *Elf) !void {
978 if (!gop.found_existing) gop.value_ptr.* = .{};978 if (!gop.found_existing) gop.value_ptr.* = .{};
979 try gop.value_ptr.append(gpa, .{ .index = atom_index, .file = self.index });979 try gop.value_ptr.append(gpa, .{ .index = atom_index, .file = self.index });
980 }980 }
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 }
1013}981}
1014982
1015pub fn initRelaSections(self: *Object, elf_file: *Elf) !void {983pub 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 {...@@ -33,11 +33,15 @@ pub fn isAbs(symbol: Symbol, elf_file: *Elf) bool {
33 const file_ptr = symbol.file(elf_file).?;33 const file_ptr = symbol.file(elf_file).?;
34 if (file_ptr == .shared_object) return symbol.elfSym(elf_file).st_shndx == elf.SHN_ABS;34 if (file_ptr == .shared_object) return symbol.elfSym(elf_file).st_shndx == elf.SHN_ABS;
35 return !symbol.flags.import and symbol.atom(elf_file) == null and35 return !symbol.flags.import and symbol.atom(elf_file) == null and
36 symbol.mergeSubsection(elf_file) == null and symbol.outputShndx() == null and36 symbol.mergeSubsection(elf_file) == null and symbol.outputShndx(elf_file) == null and
37 file_ptr != .linker_defined;37 file_ptr != .linker_defined;
38}38}
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;
41 if (symbol.output_section_index == 0) return null;45 if (symbol.output_section_index == 0) return null;
42 return symbol.output_section_index;46 return symbol.output_section_index;
43}47}
...@@ -298,7 +302,7 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {...@@ -298,7 +302,7 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {
298 if (elf_file.base.isRelocatable() and esym.st_shndx == elf.SHN_COMMON) break :blk elf.SHN_COMMON;302 if (elf_file.base.isRelocatable() and esym.st_shndx == elf.SHN_COMMON) break :blk elf.SHN_COMMON;
299 if (symbol.mergeSubsection(elf_file)) |msub| break :blk @intCast(msub.mergeSection(elf_file).output_section_index);303 if (symbol.mergeSubsection(elf_file)) |msub| break :blk @intCast(msub.mergeSection(elf_file).output_section_index);
300 if (symbol.atom(elf_file) == null and file_ptr != .linker_defined) break :blk elf.SHN_ABS;304 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);
302 };306 };
303 const st_value = blk: {307 const st_value = blk: {
304 if (symbol.flags.has_copy_rel) break :blk symbol.address(.{}, elf_file);308 if (symbol.flags.has_copy_rel) break :blk symbol.address(.{}, elf_file);
...@@ -382,22 +386,23 @@ fn format2(...@@ -382,22 +386,23 @@ fn format2(
382 _ = options;386 _ = options;
383 _ = unused_fmt_string;387 _ = unused_fmt_string;
384 const symbol = ctx.symbol;388 const symbol = ctx.symbol;
389 const elf_file = ctx.elf_file;
385 try writer.print("%{d} : {s} : @{x}", .{390 try writer.print("%{d} : {s} : @{x}", .{
386 symbol.esym_index,391 symbol.esym_index,
387 symbol.fmtName(ctx.elf_file),392 symbol.fmtName(elf_file),
388 symbol.address(.{}, ctx.elf_file),393 symbol.address(.{}, elf_file),
389 });394 });
390 if (symbol.file(ctx.elf_file)) |file_ptr| {395 if (symbol.file(elf_file)) |file_ptr| {
391 if (symbol.isAbs(ctx.elf_file)) {396 if (symbol.isAbs(elf_file)) {
392 if (symbol.elfSym(ctx.elf_file).st_shndx == elf.SHN_UNDEF) {397 if (symbol.elfSym(elf_file).st_shndx == elf.SHN_UNDEF) {
393 try writer.writeAll(" : undef");398 try writer.writeAll(" : undef");
394 } else {399 } else {
395 try writer.writeAll(" : absolute");400 try writer.writeAll(" : absolute");
396 }401 }
397 } else if (symbol.outputShndx()) |shndx| {402 } else if (symbol.outputShndx(elf_file)) |shndx| {
398 try writer.print(" : shdr({d})", .{shndx});403 try writer.print(" : shdr({d})", .{shndx});
399 }404 }
400 if (symbol.atom(ctx.elf_file)) |atom_ptr| {405 if (symbol.atom(elf_file)) |atom_ptr| {
401 try writer.print(" : atom({d})", .{atom_ptr.atom_index});406 try writer.print(" : atom({d})", .{atom_ptr.atom_index});
402 }407 }
403 var buf: [2]u8 = .{'_'} ** 2;408 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 {...@@ -341,15 +341,10 @@ pub fn resolveSymbols(self: *ZigObject, elf_file: *Elf) void {
341 SHN_ATOM => shndx,341 SHN_ATOM => shndx,
342 else => unreachable,342 else => unreachable,
343 };343 };
344 const output_section_index = if (self.atom(atom_index)) |atom_ptr|
345 atom_ptr.output_section_index
346 else
347 elf.SHN_UNDEF;
348 global.value = @intCast(esym.st_value);344 global.value = @intCast(esym.st_value);
349 global.atom_ref = .{ .index = atom_index, .file = self.index };345 global.atom_ref = .{ .index = atom_index, .file = self.index };
350 global.esym_index = esym_index;346 global.esym_index = esym_index;
351 global.file_index = self.index;347 global.file_index = self.index;
352 global.output_section_index = output_section_index;
353 global.version_index = elf_file.default_sym_version;348 global.version_index = elf_file.default_sym_version;
354 if (esym.st_bind() == elf.STB_WEAK) global.flags.weak = true;349 if (esym.st_bind() == elf.STB_WEAK) global.flags.weak = true;
355 }350 }
...@@ -492,7 +487,7 @@ pub fn updateArSymtab(self: ZigObject, ar_symtab: *Archive.ArSymtab, elf_file: *...@@ -492,7 +487,7 @@ pub fn updateArSymtab(self: ZigObject, ar_symtab: *Archive.ArSymtab, elf_file: *
492 const global = elf_file.symbol(global_index);487 const global = elf_file.symbol(global_index);
493 const file_ptr = global.file(elf_file).?;488 const file_ptr = global.file(elf_file).?;
494 assert(file_ptr.index() == self.index);489 assert(file_ptr.index() == self.index);
495 if (global.outputShndx() == null) continue;490 if (global.outputShndx(elf_file) == null) continue;
496491
497 const off = try ar_symtab.strtab.insert(gpa, global.name(elf_file));492 const off = try ar_symtab.strtab.insert(gpa, global.name(elf_file));
498 ar_symtab.symtab.appendAssumeCapacity(.{ .off = off, .file_index = self.index });493 ar_symtab.symtab.appendAssumeCapacity(.{ .off = off, .file_index = self.index });
...@@ -918,12 +913,10 @@ fn updateDeclCode(...@@ -918,12 +913,10 @@ fn updateDeclCode(
918 const esym = &self.local_esyms.items(.elf_sym)[sym.esym_index];913 const esym = &self.local_esyms.items(.elf_sym)[sym.esym_index];
919 const atom_ptr = sym.atom(elf_file).?;914 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));
925 atom_ptr.alive = true;916 atom_ptr.alive = true;
926 atom_ptr.name_offset = sym.name_offset;917 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));
927 esym.st_name = sym.name_offset;920 esym.st_name = sym.name_offset;
928 esym.st_info |= stt_bits;921 esym.st_info |= stt_bits;
929 esym.st_size = code.len;922 esym.st_size = code.len;
...@@ -1018,7 +1011,6 @@ fn updateTlv(...@@ -1018,7 +1011,6 @@ fn updateTlv(
1018 const atom_ptr = sym.atom(elf_file).?;1011 const atom_ptr = sym.atom(elf_file).?;
10191012
1020 sym.value = 0;1013 sym.value = 0;
1021 sym.output_section_index = shndx;
1022 atom_ptr.output_section_index = shndx;1014 atom_ptr.output_section_index = shndx;
10231015
1024 sym.name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));1016 sym.name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
...@@ -1240,7 +1232,6 @@ fn updateLazySymbol(...@@ -1240,7 +1232,6 @@ fn updateLazySymbol(
1240 };1232 };
1241 const local_sym = elf_file.symbol(symbol_index);1233 const local_sym = elf_file.symbol(symbol_index);
1242 local_sym.name_offset = name_str_index;1234 local_sym.name_offset = name_str_index;
1243 local_sym.output_section_index = output_section_index;
1244 const local_esym = &self.local_esyms.items(.elf_sym)[local_sym.esym_index];1235 const local_esym = &self.local_esyms.items(.elf_sym)[local_sym.esym_index];
1245 local_esym.st_name = name_str_index;1236 local_esym.st_name = name_str_index;
1246 local_esym.st_info |= elf.STT_OBJECT;1237 local_esym.st_info |= elf.STT_OBJECT;
...@@ -1348,7 +1339,6 @@ fn lowerConst(...@@ -1348,7 +1339,6 @@ fn lowerConst(
1348 const local_sym = elf_file.symbol(sym_index);1339 const local_sym = elf_file.symbol(sym_index);
1349 const name_str_index = try self.strtab.insert(gpa, name);1340 const name_str_index = try self.strtab.insert(gpa, name);
1350 local_sym.name_offset = name_str_index;1341 local_sym.name_offset = name_str_index;
1351 local_sym.output_section_index = output_section_index;
1352 const local_esym = &self.local_esyms.items(.elf_sym)[local_sym.esym_index];1342 const local_esym = &self.local_esyms.items(.elf_sym)[local_sym.esym_index];
1353 local_esym.st_name = name_str_index;1343 local_esym.st_name = name_str_index;
1354 local_esym.st_info |= elf.STT_OBJECT;1344 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...@@ -421,7 +421,7 @@ fn emitReloc(elf_file: *Elf, rec: anytype, sym: *const Symbol, rel: elf.Elf64_Re
421 switch (sym.type(elf_file)) {421 switch (sym.type(elf_file)) {
422 elf.STT_SECTION => {422 elf.STT_SECTION => {
423 r_addend += @intCast(sym.address(.{}, elf_file));423 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).?);
425 },425 },
426 else => {426 else => {
427 r_sym = sym.outputSymtabIndex(elf_file) orelse 0;427 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 {...@@ -382,7 +382,7 @@ fn updateComdatGroupsSizes(elf_file: *Elf) void {
382382
383 const sym = elf_file.symbol(cg.symbol(elf_file));383 const sym = elf_file.symbol(cg.symbol(elf_file));
384 shdr.sh_info = sym.outputSymtabIndex(elf_file) orelse384 shdr.sh_info = sym.outputSymtabIndex(elf_file) orelse
385 elf_file.sectionSymbolOutputSymtabIndex(sym.outputShndx().?);385 elf_file.sectionSymbolOutputSymtabIndex(sym.outputShndx(elf_file).?);
386 }386 }
387}387}
388388
test/link/elf.zig-20
...@@ -416,16 +416,6 @@ fn testComdatElimination(b: *Build, opts: Options) *Step {...@@ -416,16 +416,6 @@ fn testComdatElimination(b: *Build, opts: Options) *Step {
416 \\416 \\
417 );417 );
418 test_step.dependOn(&run.step);418 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);
429 }419 }
430420
431 {421 {
...@@ -441,16 +431,6 @@ fn testComdatElimination(b: *Build, opts: Options) *Step {...@@ -441,16 +431,6 @@ fn testComdatElimination(b: *Build, opts: Options) *Step {
441 \\431 \\
442 );432 );
443 test_step.dependOn(&run.step);433 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);
454 }434 }
455435
456 {436 {