link/elf: port macho symbol extras handling
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user