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