diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-10-01 12:00:07 +0200 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2024-10-09 12:38:11 -0700 |
| commit | 906cf48e14b6faff9cdc040263b38b982b2f59af (patch) | |
| tree | fc760eacf2548ee167e844ec102be60bd33790b7 | |
| parent | 887f9a29f35ca32521ac6786ba6aab6fd240421f (diff) | |
| download | zig-906cf48e14b6faff9cdc040263b38b982b2f59af.tar.gz zig-906cf48e14b6faff9cdc040263b38b982b2f59af.zip | |
elf: fix creation of synthetic sections
| -rw-r--r-- | src/link/Elf/Symbol.zig | 15 | ||||
| -rw-r--r-- | src/link/Elf/file.zig | 10 | ||||
| -rw-r--r-- | src/link/Elf/synthetic_sections.zig | 3 |
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); } |
