aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2024-10-01 12:00:07 +0200
committerAndrew Kelley <andrew@ziglang.org>2024-10-09 12:38:11 -0700
commit906cf48e14b6faff9cdc040263b38b982b2f59af (patch)
treefc760eacf2548ee167e844ec102be60bd33790b7
parent887f9a29f35ca32521ac6786ba6aab6fd240421f (diff)
downloadzig-906cf48e14b6faff9cdc040263b38b982b2f59af.tar.gz
zig-906cf48e14b6faff9cdc040263b38b982b2f59af.zip
elf: fix creation of synthetic sections
-rw-r--r--src/link/Elf/Symbol.zig15
-rw-r--r--src/link/Elf/file.zig10
-rw-r--r--src/link/Elf/synthetic_sections.zig3
3 files changed, 16 insertions, 12 deletions
diff --git a/src/link/Elf/Symbol.zig b/src/link/Elf/Symbol.zig
index cdf1b6f40a..6eaaedf28c 100644
--- a/src/link/Elf/Symbol.zig
+++ b/src/link/Elf/Symbol.zig
@@ -112,13 +112,16 @@ pub fn address(symbol: Symbol, opts: struct { plt: bool = true, trampoline: bool
if (symbol.flags.has_trampoline and opts.trampoline) {
return symbol.trampolineAddress(elf_file);
}
- if (symbol.flags.has_plt and opts.plt) {
- if (!symbol.flags.is_canonical and symbol.flags.has_got) {
+ if (opts.plt) {
+ if (symbol.flags.has_pltgot) {
+ assert(!symbol.flags.is_canonical);
// We have a non-lazy bound function pointer, use that!
return symbol.pltGotAddress(elf_file);
}
- // Lazy-bound function it is!
- return symbol.pltAddress(elf_file);
+ if (symbol.flags.has_plt) {
+ // Lazy-bound function it is!
+ return symbol.pltAddress(elf_file);
+ }
}
if (symbol.atom(elf_file)) |atom_ptr| {
if (!atom_ptr.alive) {
@@ -171,7 +174,7 @@ pub fn gotAddress(symbol: Symbol, elf_file: *Elf) i64 {
}
pub fn pltGotAddress(symbol: Symbol, elf_file: *Elf) i64 {
- if (!(symbol.flags.has_plt and symbol.flags.has_got)) return 0;
+ if (!symbol.flags.has_pltgot) return 0;
const extras = symbol.extra(elf_file);
const shdr = elf_file.sections.items(.shdr)[elf_file.plt_got_section_index.?];
const cpu_arch = elf_file.getTarget().cpu.arch;
@@ -430,6 +433,8 @@ pub const Flags = packed struct {
has_plt: bool = false,
/// Whether the PLT entry is canonical.
is_canonical: bool = false,
+ /// Whether the PLT entry is indirected via GOT.
+ has_pltgot: bool = false,
/// Whether the symbol contains COPYREL directive.
needs_copy_rel: bool = false,
diff --git a/src/link/Elf/file.zig b/src/link/Elf/file.zig
index a1db5110f0..32de82f962 100644
--- a/src/link/Elf/file.zig
+++ b/src/link/Elf/file.zig
@@ -99,18 +99,18 @@ pub const File = union(enum) {
log.debug("'{s}' needs GOT", .{sym.name(ef)});
_ = try ef.got.addGotSymbol(ref, ef);
}
- if (sym.flags.needs_plt and !sym.flags.has_plt) {
- if (sym.flags.is_canonical) {
+ if (sym.flags.needs_plt) {
+ if (sym.flags.is_canonical and !sym.flags.has_plt) {
log.debug("'{s}' needs CPLT", .{sym.name(ef)});
sym.flags.@"export" = true;
try ef.plt.addSymbol(ref, ef);
- } else if (sym.flags.needs_got and !sym.flags.has_got) {
+ } else if (sym.flags.needs_got and !sym.flags.has_pltgot) {
log.debug("'{s}' needs PLTGOT", .{sym.name(ef)});
try ef.plt_got.addSymbol(ref, ef);
- } else {
+ } else if (!sym.flags.has_plt) {
log.debug("'{s}' needs PLT", .{sym.name(ef)});
try ef.plt.addSymbol(ref, ef);
- }
+ } else unreachable;
}
if (sym.flags.needs_copy_rel and !sym.flags.has_copy_rel) {
log.debug("'{s}' needs COPYREL", .{sym.name(ef)});
diff --git a/src/link/Elf/synthetic_sections.zig b/src/link/Elf/synthetic_sections.zig
index f914bb8d84..6a1ae59a62 100644
--- a/src/link/Elf/synthetic_sections.zig
+++ b/src/link/Elf/synthetic_sections.zig
@@ -895,8 +895,7 @@ pub const PltGotSection = struct {
const gpa = comp.gpa;
const index = @as(u32, @intCast(plt_got.symbols.items.len));
const symbol = elf_file.symbol(ref).?;
- symbol.flags.has_plt = true;
- symbol.flags.has_got = true;
+ symbol.flags.has_pltgot = true;
symbol.addExtra(.{ .plt_got = index }, elf_file);
try plt_got.symbols.append(gpa, ref);
}