aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2024-04-15 21:50:45 +0200
committerJakub Konka <kubkon@jakubkonka.com>2024-04-20 23:36:41 +0200
commitd5fdb7315f2f5742c58af547909437401651ffd5 (patch)
treebd9f8e9f3947e83b0c20230d00f79000c2f8fb19 /src
parent700644d35dd674c7381c4794d566e0e64f45c174 (diff)
downloadzig-d5fdb7315f2f5742c58af547909437401651ffd5.tar.gz
zig-d5fdb7315f2f5742c58af547909437401651ffd5.zip
link/elf: port macho symbol extras handling
Diffstat (limited to 'src')
-rw-r--r--src/link/Elf/LinkerDefined.zig4
-rw-r--r--src/link/Elf/Object.zig6
-rw-r--r--src/link/Elf/SharedObject.zig2
-rw-r--r--src/link/Elf/Symbol.zig34
-rw-r--r--src/link/Elf/ZigObject.zig6
-rw-r--r--src/link/Elf/synthetic_sections.zig55
6 files changed, 42 insertions, 65 deletions
diff --git a/src/link/Elf/LinkerDefined.zig b/src/link/Elf/LinkerDefined.zig
index b9fffa1a4a..97edd34791 100644
--- a/src/link/Elf/LinkerDefined.zig
+++ b/src/link/Elf/LinkerDefined.zig
@@ -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;
diff --git a/src/link/Elf/Object.zig b/src/link/Elf/Object.zig
index d483540aa6..eda2d89471 100644
--- a/src/link/Elf/Object.zig
+++ b/src/link/Elf/Object.zig
@@ -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;
diff --git a/src/link/Elf/SharedObject.zig b/src/link/Elf/SharedObject.zig
index d40367f304..4491c04dc8 100644
--- a/src/link/Elf/SharedObject.zig
+++ b/src/link/Elf/SharedObject.zig
@@ -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;
}
diff --git a/src/link/Elf/Symbol.zig b/src/link/Elf/Symbol.zig
index 9db17f2f4f..1cf41b459a 100644
--- a/src/link/Elf/Symbol.zig
+++ b/src/link/Elf/Symbol.zig
@@ -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 {
diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig
index f65ef43eac..af74f2637b 100644
--- a/src/link/Elf/ZigObject.zig
+++ b/src/link/Elf/ZigObject.zig
@@ -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;
diff --git a/src/link/Elf/synthetic_sections.zig b/src/link/Elf/synthetic_sections.zig
index 2ef7d49540..e76809c79a 100644
--- a/src/link/Elf/synthetic_sections.zig
+++ b/src/link/Elf/synthetic_sections.zig
@@ -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 });
}