| author | |
| committer | |
| log | 906cf48e14b6faff9cdc040263b38b982b2f59af |
| tree | fc760eacf2548ee167e844ec102be60bd33790b7 |
| parent | 887f9a29f35ca32521ac6786ba6aab6fd240421f |
3 files changed, 16 insertions(+), 12 deletions(-)
src/link/Elf/Symbol.zig+10-5| ... | ... | @@ -112,13 +112,16 @@ pub fn address(symbol: Symbol, opts: struct { plt: bool = true, trampoline: bool |
| 112 | 112 | if (symbol.flags.has_trampoline and opts.trampoline) { |
| 113 | 113 | return symbol.trampolineAddress(elf_file); |
| 114 | 114 | } |
| 115 | if (symbol.flags.has_plt and opts.plt) { | |
| 116 | if (!symbol.flags.is_canonical and symbol.flags.has_got) { | |
| 115 | if (opts.plt) { | |
| 116 | if (symbol.flags.has_pltgot) { | |
| 117 | assert(!symbol.flags.is_canonical); | |
| 117 | 118 | // We have a non-lazy bound function pointer, use that! |
| 118 | 119 | return symbol.pltGotAddress(elf_file); |
| 119 | 120 | } |
| 120 | // Lazy-bound function it is! | |
| 121 | return symbol.pltAddress(elf_file); | |
| 121 | if (symbol.flags.has_plt) { | |
| 122 | // Lazy-bound function it is! | |
| 123 | return symbol.pltAddress(elf_file); | |
| 124 | } | |
| 122 | 125 | } |
| 123 | 126 | if (symbol.atom(elf_file)) |atom_ptr| { |
| 124 | 127 | if (!atom_ptr.alive) { |
| ... | ... | @@ -171,7 +174,7 @@ pub fn gotAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 171 | 174 | } |
| 172 | 175 | |
| 173 | 176 | pub fn pltGotAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 174 | if (!(symbol.flags.has_plt and symbol.flags.has_got)) return 0; | |
| 177 | if (!symbol.flags.has_pltgot) return 0; | |
| 175 | 178 | const extras = symbol.extra(elf_file); |
| 176 | 179 | const shdr = elf_file.sections.items(.shdr)[elf_file.plt_got_section_index.?]; |
| 177 | 180 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| ... | ... | @@ -430,6 +433,8 @@ pub const Flags = packed struct { |
| 430 | 433 | has_plt: bool = false, |
| 431 | 434 | /// Whether the PLT entry is canonical. |
| 432 | 435 | is_canonical: bool = false, |
| 436 | /// Whether the PLT entry is indirected via GOT. | |
| 437 | has_pltgot: bool = false, | |
| 433 | 438 | |
| 434 | 439 | /// Whether the symbol contains COPYREL directive. |
| 435 | 440 | needs_copy_rel: bool = false, |
src/link/Elf/file.zig+5-5| ... | ... | @@ -99,18 +99,18 @@ pub const File = union(enum) { |
| 99 | 99 | log.debug("'{s}' needs GOT", .{sym.name(ef)}); |
| 100 | 100 | _ = try ef.got.addGotSymbol(ref, ef); |
| 101 | 101 | } |
| 102 | if (sym.flags.needs_plt and !sym.flags.has_plt) { | |
| 103 | if (sym.flags.is_canonical) { | |
| 102 | if (sym.flags.needs_plt) { | |
| 103 | if (sym.flags.is_canonical and !sym.flags.has_plt) { | |
| 104 | 104 | log.debug("'{s}' needs CPLT", .{sym.name(ef)}); |
| 105 | 105 | sym.flags.@"export" = true; |
| 106 | 106 | try ef.plt.addSymbol(ref, ef); |
| 107 | } else if (sym.flags.needs_got and !sym.flags.has_got) { | |
| 107 | } else if (sym.flags.needs_got and !sym.flags.has_pltgot) { | |
| 108 | 108 | log.debug("'{s}' needs PLTGOT", .{sym.name(ef)}); |
| 109 | 109 | try ef.plt_got.addSymbol(ref, ef); |
| 110 | } else { | |
| 110 | } else if (!sym.flags.has_plt) { | |
| 111 | 111 | log.debug("'{s}' needs PLT", .{sym.name(ef)}); |
| 112 | 112 | try ef.plt.addSymbol(ref, ef); |
| 113 | } | |
| 113 | } else unreachable; | |
| 114 | 114 | } |
| 115 | 115 | if (sym.flags.needs_copy_rel and !sym.flags.has_copy_rel) { |
| 116 | 116 | log.debug("'{s}' needs COPYREL", .{sym.name(ef)}); |
src/link/Elf/synthetic_sections.zig+1-2| ... | ... | @@ -895,8 +895,7 @@ pub const PltGotSection = struct { |
| 895 | 895 | const gpa = comp.gpa; |
| 896 | 896 | const index = @as(u32, @intCast(plt_got.symbols.items.len)); |
| 897 | 897 | const symbol = elf_file.symbol(ref).?; |
| 898 | symbol.flags.has_plt = true; | |
| 899 | symbol.flags.has_got = true; | |
| 898 | symbol.flags.has_pltgot = true; | |
| 900 | 899 | symbol.addExtra(.{ .plt_got = index }, elf_file); |
| 901 | 900 | try plt_got.symbols.append(gpa, ref); |
| 902 | 901 | } |