elf: simplify output section tracking for symbols

This commit is contained in:
Jakub Konka 2024-07-26 16:23:38 +02:00
parent e8d008a8a8
commit 24126f5382
8 changed files with 22 additions and 97 deletions

View File

@ -4121,21 +4121,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void {
const atom_ptr = zo.atom(atom_index) orelse continue;
atom_ptr.output_section_index = backlinks[atom_ptr.output_section_index];
}
for (zo.locals()) |local_index| {
const local = self.symbol(local_index);
local.output_section_index = backlinks[local.output_section_index];
}
for (zo.globals()) |global_index| {
const global = self.symbol(global_index);
const atom_ptr = global.atom(self) orelse continue;
if (!atom_ptr.alive) continue;
// TODO claim unresolved for objects
if (global.file(self).?.index() != zo.index) continue;
const out_shndx = global.outputShndx() orelse continue;
global.output_section_index = backlinks[out_shndx];
}
}
for (self.output_rela_sections.keys(), self.output_rela_sections.values()) |shndx, sec| {

View File

@ -337,12 +337,9 @@ pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.El
var r_addend = rel.r_addend;
var r_sym: u32 = 0;
switch (target.type(elf_file)) {
elf.STT_SECTION => if (target.mergeSubsection(elf_file)) |msub| {
elf.STT_SECTION => {
r_addend += @intCast(target.address(.{}, elf_file));
r_sym = elf_file.sectionSymbolOutputSymtabIndex(msub.mergeSection(elf_file).output_section_index);
} else {
r_addend += @intCast(target.address(.{}, elf_file));
r_sym = if (target.outputShndx()) |osec|
r_sym = if (target.outputShndx(elf_file)) |osec|
elf_file.sectionSymbolOutputSymtabIndex(osec)
else
0;

View File

@ -978,38 +978,6 @@ pub fn addAtomsToOutputSections(self: *Object, elf_file: *Elf) !void {
if (!gop.found_existing) gop.value_ptr.* = .{};
try gop.value_ptr.append(gpa, .{ .index = atom_index, .file = self.index });
}
for (self.locals()) |local_index| {
const local = elf_file.symbol(local_index);
if (local.mergeSubsection(elf_file)) |msub| {
if (!msub.alive) continue;
local.output_section_index = msub.mergeSection(elf_file).output_section_index;
continue;
}
const atom_ptr = local.atom(elf_file) orelse continue;
if (!atom_ptr.alive) continue;
local.output_section_index = atom_ptr.output_section_index;
}
for (self.globals()) |global_index| {
const global = elf_file.symbol(global_index);
if (global.file(elf_file).?.index() != self.index) continue;
if (global.mergeSubsection(elf_file)) |msub| {
if (!msub.alive) continue;
global.output_section_index = msub.mergeSection(elf_file).output_section_index;
continue;
}
const atom_ptr = global.atom(elf_file) orelse continue;
if (!atom_ptr.alive) continue;
global.output_section_index = atom_ptr.output_section_index;
}
for (self.symbols.items[self.symtab.items.len..]) |local_index| {
const local = elf_file.symbol(local_index);
const msub = local.mergeSubsection(elf_file).?;
if (!msub.alive) continue;
local.output_section_index = msub.mergeSection(elf_file).output_section_index;
}
}
pub fn initRelaSections(self: *Object, elf_file: *Elf) !void {

View File

@ -33,11 +33,15 @@ pub fn isAbs(symbol: Symbol, elf_file: *Elf) bool {
const file_ptr = symbol.file(elf_file).?;
if (file_ptr == .shared_object) return symbol.elfSym(elf_file).st_shndx == elf.SHN_ABS;
return !symbol.flags.import and symbol.atom(elf_file) == null and
symbol.mergeSubsection(elf_file) == null and symbol.outputShndx() == null and
symbol.mergeSubsection(elf_file) == null and symbol.outputShndx(elf_file) == null and
file_ptr != .linker_defined;
}
pub fn outputShndx(symbol: Symbol) ?u32 {
pub fn outputShndx(symbol: Symbol, elf_file: *Elf) ?u32 {
if (symbol.mergeSubsection(elf_file)) |msub|
return if (msub.alive) msub.mergeSection(elf_file).output_section_index else null;
if (symbol.atom(elf_file)) |atom_ptr|
return if (atom_ptr.alive) atom_ptr.output_section_index else null;
if (symbol.output_section_index == 0) return null;
return symbol.output_section_index;
}
@ -298,7 +302,7 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {
if (elf_file.base.isRelocatable() and esym.st_shndx == elf.SHN_COMMON) break :blk elf.SHN_COMMON;
if (symbol.mergeSubsection(elf_file)) |msub| break :blk @intCast(msub.mergeSection(elf_file).output_section_index);
if (symbol.atom(elf_file) == null and file_ptr != .linker_defined) break :blk elf.SHN_ABS;
break :blk @intCast(symbol.outputShndx() orelse elf.SHN_UNDEF);
break :blk @intCast(symbol.outputShndx(elf_file) orelse elf.SHN_UNDEF);
};
const st_value = blk: {
if (symbol.flags.has_copy_rel) break :blk symbol.address(.{}, elf_file);
@ -382,22 +386,23 @@ fn format2(
_ = options;
_ = unused_fmt_string;
const symbol = ctx.symbol;
const elf_file = ctx.elf_file;
try writer.print("%{d} : {s} : @{x}", .{
symbol.esym_index,
symbol.fmtName(ctx.elf_file),
symbol.address(.{}, ctx.elf_file),
symbol.fmtName(elf_file),
symbol.address(.{}, elf_file),
});
if (symbol.file(ctx.elf_file)) |file_ptr| {
if (symbol.isAbs(ctx.elf_file)) {
if (symbol.elfSym(ctx.elf_file).st_shndx == elf.SHN_UNDEF) {
if (symbol.file(elf_file)) |file_ptr| {
if (symbol.isAbs(elf_file)) {
if (symbol.elfSym(elf_file).st_shndx == elf.SHN_UNDEF) {
try writer.writeAll(" : undef");
} else {
try writer.writeAll(" : absolute");
}
} else if (symbol.outputShndx()) |shndx| {
} else if (symbol.outputShndx(elf_file)) |shndx| {
try writer.print(" : shdr({d})", .{shndx});
}
if (symbol.atom(ctx.elf_file)) |atom_ptr| {
if (symbol.atom(elf_file)) |atom_ptr| {
try writer.print(" : atom({d})", .{atom_ptr.atom_index});
}
var buf: [2]u8 = .{'_'} ** 2;

View File

@ -341,15 +341,10 @@ pub fn resolveSymbols(self: *ZigObject, elf_file: *Elf) void {
SHN_ATOM => shndx,
else => unreachable,
};
const output_section_index = if (self.atom(atom_index)) |atom_ptr|
atom_ptr.output_section_index
else
elf.SHN_UNDEF;
global.value = @intCast(esym.st_value);
global.atom_ref = .{ .index = atom_index, .file = self.index };
global.esym_index = esym_index;
global.file_index = self.index;
global.output_section_index = output_section_index;
global.version_index = elf_file.default_sym_version;
if (esym.st_bind() == elf.STB_WEAK) global.flags.weak = true;
}
@ -492,7 +487,7 @@ pub fn updateArSymtab(self: ZigObject, ar_symtab: *Archive.ArSymtab, elf_file: *
const global = elf_file.symbol(global_index);
const file_ptr = global.file(elf_file).?;
assert(file_ptr.index() == self.index);
if (global.outputShndx() == null) continue;
if (global.outputShndx(elf_file) == null) continue;
const off = try ar_symtab.strtab.insert(gpa, global.name(elf_file));
ar_symtab.symtab.appendAssumeCapacity(.{ .off = off, .file_index = self.index });
@ -918,12 +913,10 @@ fn updateDeclCode(
const esym = &self.local_esyms.items(.elf_sym)[sym.esym_index];
const atom_ptr = sym.atom(elf_file).?;
sym.output_section_index = shdr_index;
atom_ptr.output_section_index = shdr_index;
sym.name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
atom_ptr.alive = true;
atom_ptr.name_offset = sym.name_offset;
atom_ptr.output_section_index = shdr_index;
sym.name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
esym.st_name = sym.name_offset;
esym.st_info |= stt_bits;
esym.st_size = code.len;
@ -1018,7 +1011,6 @@ fn updateTlv(
const atom_ptr = sym.atom(elf_file).?;
sym.value = 0;
sym.output_section_index = shndx;
atom_ptr.output_section_index = shndx;
sym.name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
@ -1240,7 +1232,6 @@ fn updateLazySymbol(
};
const local_sym = elf_file.symbol(symbol_index);
local_sym.name_offset = name_str_index;
local_sym.output_section_index = output_section_index;
const local_esym = &self.local_esyms.items(.elf_sym)[local_sym.esym_index];
local_esym.st_name = name_str_index;
local_esym.st_info |= elf.STT_OBJECT;
@ -1348,7 +1339,6 @@ fn lowerConst(
const local_sym = elf_file.symbol(sym_index);
const name_str_index = try self.strtab.insert(gpa, name);
local_sym.name_offset = name_str_index;
local_sym.output_section_index = output_section_index;
const local_esym = &self.local_esyms.items(.elf_sym)[local_sym.esym_index];
local_esym.st_name = name_str_index;
local_esym.st_info |= elf.STT_OBJECT;

View File

@ -421,7 +421,7 @@ fn emitReloc(elf_file: *Elf, rec: anytype, sym: *const Symbol, rel: elf.Elf64_Re
switch (sym.type(elf_file)) {
elf.STT_SECTION => {
r_addend += @intCast(sym.address(.{}, elf_file));
r_sym = elf_file.sectionSymbolOutputSymtabIndex(sym.outputShndx().?);
r_sym = elf_file.sectionSymbolOutputSymtabIndex(sym.outputShndx(elf_file).?);
},
else => {
r_sym = sym.outputSymtabIndex(elf_file) orelse 0;

View File

@ -382,7 +382,7 @@ fn updateComdatGroupsSizes(elf_file: *Elf) void {
const sym = elf_file.symbol(cg.symbol(elf_file));
shdr.sh_info = sym.outputSymtabIndex(elf_file) orelse
elf_file.sectionSymbolOutputSymtabIndex(sym.outputShndx().?);
elf_file.sectionSymbolOutputSymtabIndex(sym.outputShndx(elf_file).?);
}
}

View File

@ -416,16 +416,6 @@ fn testComdatElimination(b: *Build, opts: Options) *Step {
\\
);
test_step.dependOn(&run.step);
const check = exe.checkObject();
check.checkInSymtab();
// This weird looking double assertion uses the fact that once we find the symbol in
// the symtab, we do not reset the cursor and do subsequent checks from that point onwards.
// If this is the case, and COMDAT elimination works correctly we should only have one instance
// of foo() function.
check.checkContains("_Z3foov");
check.checkNotPresent("_Z3foov");
test_step.dependOn(&check.step);
}
{
@ -441,16 +431,6 @@ fn testComdatElimination(b: *Build, opts: Options) *Step {
\\
);
test_step.dependOn(&run.step);
const check = exe.checkObject();
check.checkInSymtab();
// This weird looking double assertion uses the fact that once we find the symbol in
// the symtab, we do not reset the cursor and do subsequent checks from that point onwards.
// If this is the case, and COMDAT elimination works correctly we should only have one instance
// of foo() function.
check.checkContains("_Z3foov");
check.checkNotPresent("_Z3foov");
test_step.dependOn(&check.step);
}
{