link/elf: port macho symbol extras handling

This commit is contained in:
Jakub Konka
2024-04-15 21:50:45 +02:00
parent 700644d35d
commit d5fdb7315f
6 changed files with 42 additions and 65 deletions

View File

@@ -60,10 +60,10 @@ pub fn updateSymtabSize(self: *LinkerDefined, elf_file: *Elf) !void {
if (file_ptr.index() != self.index) continue;
global.flags.output_symtab = true;
if (global.isLocal(elf_file)) {
try global.setOutputSymtabIndex(self.output_symtab_ctx.nlocals, elf_file);
try global.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, elf_file);
self.output_symtab_ctx.nlocals += 1;
} else {
try global.setOutputSymtabIndex(self.output_symtab_ctx.nglobals, elf_file);
try global.addExtra(.{ .symtab = self.output_symtab_ctx.nglobals }, elf_file);
self.output_symtab_ctx.nglobals += 1;
}
self.output_symtab_ctx.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1;

View File

@@ -853,7 +853,7 @@ pub fn updateSymtabSize(self: *Object, elf_file: *Elf) !void {
else => {},
}
local.flags.output_symtab = true;
try local.setOutputSymtabIndex(self.output_symtab_ctx.nlocals, elf_file);
try local.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, elf_file);
self.output_symtab_ctx.nlocals += 1;
self.output_symtab_ctx.strsize += @as(u32, @intCast(local.name(elf_file).len)) + 1;
}
@@ -865,10 +865,10 @@ pub fn updateSymtabSize(self: *Object, elf_file: *Elf) !void {
if (global.atom(elf_file)) |atom| if (!atom.flags.alive) continue;
global.flags.output_symtab = true;
if (global.isLocal(elf_file)) {
try global.setOutputSymtabIndex(self.output_symtab_ctx.nlocals, elf_file);
try global.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, elf_file);
self.output_symtab_ctx.nlocals += 1;
} else {
try global.setOutputSymtabIndex(self.output_symtab_ctx.nglobals, elf_file);
try global.addExtra(.{ .symtab = self.output_symtab_ctx.nglobals }, elf_file);
self.output_symtab_ctx.nglobals += 1;
}
self.output_symtab_ctx.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1;

View File

@@ -269,7 +269,7 @@ pub fn updateSymtabSize(self: *SharedObject, elf_file: *Elf) !void {
if (file_ptr.index() != self.index) continue;
if (global.isLocal(elf_file)) continue;
global.flags.output_symtab = true;
try global.setOutputSymtabIndex(self.output_symtab_ctx.nglobals, elf_file);
try global.addExtra(.{ .symtab = self.output_symtab_ctx.nglobals }, elf_file);
self.output_symtab_ctx.nglobals += 1;
self.output_symtab_ctx.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1;
}

View File

@@ -143,14 +143,6 @@ pub fn outputSymtabIndex(symbol: Symbol, elf_file: *Elf) ?u32 {
return if (symbol.isLocal(elf_file)) idx + symtab_ctx.ilocal else idx + symtab_ctx.iglobal;
}
pub fn setOutputSymtabIndex(symbol: *Symbol, index: u32, elf_file: *Elf) !void {
if (symbol.extra(elf_file)) |extras| {
var new_extras = extras;
new_extras.symtab = index;
symbol.setExtra(new_extras, elf_file);
} else try symbol.addExtra(.{ .symtab = index }, elf_file);
}
pub fn gotAddress(symbol: Symbol, elf_file: *Elf) u64 {
if (!symbol.flags.has_got) return 0;
const extras = symbol.extra(elf_file).?;
@@ -240,8 +232,30 @@ pub fn dsoAlignment(symbol: Symbol, elf_file: *Elf) !u64 {
@min(alignment, try std.math.powi(u64, 2, @ctz(esym.st_value)));
}
pub fn addExtra(symbol: *Symbol, extras: Extra, elf_file: *Elf) !void {
symbol.extra_index = try elf_file.addSymbolExtra(extras);
const AddExtraOpts = struct {
got: ?u32 = null,
plt: ?u32 = null,
plt_got: ?u32 = null,
dynamic: ?u32 = null,
symtab: ?u32 = null,
copy_rel: ?u32 = null,
tlsgd: ?u32 = null,
gottp: ?u32 = null,
tlsdesc: ?u32 = null,
zig_got: ?u32 = null,
};
pub fn addExtra(symbol: *Symbol, opts: AddExtraOpts, elf_file: *Elf) !void {
if (symbol.extra(elf_file) == null) {
symbol.extra_index = try elf_file.addSymbolExtra(.{});
}
var extras = symbol.extra(elf_file).?;
inline for (@typeInfo(@TypeOf(opts)).Struct.fields) |field| {
if (@field(opts, field.name)) |x| {
@field(extras, field.name) = x;
}
}
symbol.setExtra(extras, elf_file);
}
pub fn extra(symbol: Symbol, elf_file: *Elf) ?Extra {

View File

@@ -566,7 +566,7 @@ pub fn updateSymtabSize(self: *ZigObject, elf_file: *Elf) !void {
else => {},
}
local.flags.output_symtab = true;
try local.setOutputSymtabIndex(self.output_symtab_ctx.nlocals, elf_file);
try local.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, elf_file);
self.output_symtab_ctx.nlocals += 1;
self.output_symtab_ctx.strsize += @as(u32, @intCast(local.name(elf_file).len)) + 1;
}
@@ -578,10 +578,10 @@ pub fn updateSymtabSize(self: *ZigObject, elf_file: *Elf) !void {
if (global.atom(elf_file)) |atom| if (!atom.flags.alive) continue;
global.flags.output_symtab = true;
if (global.isLocal(elf_file)) {
try global.setOutputSymtabIndex(self.output_symtab_ctx.nlocals, elf_file);
try global.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, elf_file);
self.output_symtab_ctx.nlocals += 1;
} else {
try global.setOutputSymtabIndex(self.output_symtab_ctx.nglobals, elf_file);
try global.addExtra(.{ .symtab = self.output_symtab_ctx.nglobals }, elf_file);
self.output_symtab_ctx.nglobals += 1;
}
self.output_symtab_ctx.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1;

View File

@@ -259,11 +259,7 @@ pub const ZigGotSection = struct {
if (elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) {
zig_got.flags.needs_rela = true;
}
if (symbol.extra(elf_file)) |extra| {
var new_extra = extra;
new_extra.zig_got = index;
symbol.setExtra(new_extra, elf_file);
} else try symbol.addExtra(.{ .zig_got = index }, elf_file);
try symbol.addExtra(.{ .zig_got = index }, elf_file);
return index;
}
@@ -499,11 +495,7 @@ pub const GotSection = struct {
{
got.flags.needs_rela = true;
}
if (symbol.extra(elf_file)) |extra| {
var new_extra = extra;
new_extra.got = index;
symbol.setExtra(new_extra, elf_file);
} else try symbol.addExtra(.{ .got = index }, elf_file);
try symbol.addExtra(.{ .got = index }, elf_file);
return index;
}
@@ -529,11 +521,7 @@ pub const GotSection = struct {
const symbol = elf_file.symbol(sym_index);
symbol.flags.has_tlsgd = true;
if (symbol.flags.import or elf_file.isEffectivelyDynLib()) got.flags.needs_rela = true;
if (symbol.extra(elf_file)) |extra| {
var new_extra = extra;
new_extra.tlsgd = index;
symbol.setExtra(new_extra, elf_file);
} else try symbol.addExtra(.{ .tlsgd = index }, elf_file);
try symbol.addExtra(.{ .tlsgd = index }, elf_file);
}
pub fn addGotTpSymbol(got: *GotSection, sym_index: Symbol.Index, elf_file: *Elf) !void {
@@ -546,11 +534,7 @@ pub const GotSection = struct {
const symbol = elf_file.symbol(sym_index);
symbol.flags.has_gottp = true;
if (symbol.flags.import or elf_file.isEffectivelyDynLib()) got.flags.needs_rela = true;
if (symbol.extra(elf_file)) |extra| {
var new_extra = extra;
new_extra.gottp = index;
symbol.setExtra(new_extra, elf_file);
} else try symbol.addExtra(.{ .gottp = index }, elf_file);
try symbol.addExtra(.{ .gottp = index }, elf_file);
}
pub fn addTlsDescSymbol(got: *GotSection, sym_index: Symbol.Index, elf_file: *Elf) !void {
@@ -563,11 +547,7 @@ pub const GotSection = struct {
const symbol = elf_file.symbol(sym_index);
symbol.flags.has_tlsdesc = true;
got.flags.needs_rela = true;
if (symbol.extra(elf_file)) |extra| {
var new_extra = extra;
new_extra.tlsdesc = index;
symbol.setExtra(new_extra, elf_file);
} else try symbol.addExtra(.{ .tlsdesc = index }, elf_file);
try symbol.addExtra(.{ .tlsdesc = index }, elf_file);
}
pub fn size(got: GotSection, elf_file: *Elf) usize {
@@ -877,11 +857,7 @@ pub const PltSection = struct {
const index = @as(u32, @intCast(plt.symbols.items.len));
const symbol = elf_file.symbol(sym_index);
symbol.flags.has_plt = true;
if (symbol.extra(elf_file)) |extra| {
var new_extra = extra;
new_extra.plt = index;
symbol.setExtra(new_extra, elf_file);
} else try symbol.addExtra(.{ .plt = index }, elf_file);
try symbol.addExtra(.{ .plt = index }, elf_file);
try plt.symbols.append(gpa, sym_index);
}
@@ -1132,11 +1108,7 @@ pub const PltGotSection = struct {
const symbol = elf_file.symbol(sym_index);
symbol.flags.has_plt = true;
symbol.flags.has_got = true;
if (symbol.extra(elf_file)) |extra| {
var new_extra = extra;
new_extra.plt_got = index;
symbol.setExtra(new_extra, elf_file);
} else try symbol.addExtra(.{ .plt_got = index }, elf_file);
try symbol.addExtra(.{ .plt_got = index }, elf_file);
try plt_got.symbols.append(gpa, sym_index);
}
@@ -1248,12 +1220,7 @@ pub const CopyRelSection = struct {
symbol.flags.@"export" = true;
symbol.flags.has_copy_rel = true;
symbol.flags.weak = false;
if (symbol.extra(elf_file)) |extra| {
var new_extra = extra;
new_extra.copy_rel = index;
symbol.setExtra(new_extra, elf_file);
} else try symbol.addExtra(.{ .copy_rel = index }, elf_file);
try symbol.addExtra(.{ .copy_rel = index }, elf_file);
try copy_rel.symbols.append(gpa, sym_index);
const shared_object = symbol.file(elf_file).?.shared_object;
@@ -1335,11 +1302,7 @@ pub const DynsymSection = struct {
const index = @as(u32, @intCast(dynsym.entries.items.len + 1));
const sym = elf_file.symbol(sym_index);
sym.flags.has_dynamic = true;
if (sym.extra(elf_file)) |extra| {
var new_extra = extra;
new_extra.dynamic = index;
sym.setExtra(new_extra, elf_file);
} else try sym.addExtra(.{ .dynamic = index }, elf_file);
try sym.addExtra(.{ .dynamic = index }, elf_file);
const off = try elf_file.insertDynString(sym.name(elf_file));
try dynsym.entries.append(gpa, .{ .symbol_index = sym_index, .off = off });
}