authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-10-01 12:00:07+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-09 12:38:11-07:00
log906cf48e14b6faff9cdc040263b38b982b2f59af
treefc760eacf2548ee167e844ec102be60bd33790b7
parent887f9a29f35ca32521ac6786ba6aab6fd240421f

elf: fix creation of synthetic sections


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}
172175
173pub fn pltGotAddress(symbol: Symbol, elf_file: *Elf) i64 {176pub 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,
433438
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 }