aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormlugg <mlugg@mlugg.co.uk>2025-09-10 16:41:10 +0100
committermlugg <mlugg@mlugg.co.uk>2025-09-30 13:44:53 +0100
commit4e45362529e05ba1be44fab48bc3469f5bb6492d (patch)
treeb8d161294f8519ed8471b7cdb84ff2aa037e4368 /src
parent1123741fd5fc6545daf10e2bcdcad74ec148f61b (diff)
downloadzig-4e45362529e05ba1be44fab48bc3469f5bb6492d.tar.gz
zig-4e45362529e05ba1be44fab48bc3469f5bb6492d.zip
link.Elf: fix static PIE
We mustn't emit the DT_PLTGOT entry in `.dynamic` in a statically-linked PIE, because there's no dl to relocate it (and `std.pie.relocate`, or the PIE relocator in libc, won't touch it). In that case, there cannot be any PLT entries, so there's no point emitting the `.got.plt` section at all. If we just don't create that section, `link.Elf` already knows not to add the DT_PLTGOT entry to `.dynamic`. Co-authored-by: Jacob Young <jacobly0@users.noreply.github.com>
Diffstat (limited to 'src')
-rw-r--r--src/link/Elf.zig39
1 files changed, 22 insertions, 17 deletions
diff --git a/src/link/Elf.zig b/src/link/Elf.zig
index f64e9c337b..de506700fa 100644
--- a/src/link/Elf.zig
+++ b/src/link/Elf.zig
@@ -1884,6 +1884,16 @@ fn initSyntheticSections(self: *Elf) !void {
const ptr_size = self.ptrWidthBytes();
const shared_objects = self.shared_objects.values();
+ const is_exe_or_dyn_lib = switch (comp.config.output_mode) {
+ .Exe => true,
+ .Lib => comp.config.link_mode == .dynamic,
+ .Obj => false,
+ };
+ const have_dynamic_linker = comp.config.link_mode == .dynamic and is_exe_or_dyn_lib and !target.dynamic_linker.eql(.none);
+
+ const needs_interp = have_dynamic_linker and
+ (comp.config.link_libc or comp.root_mod.resolved_target.is_explicit_dynamic_linker);
+
const needs_eh_frame = blk: {
if (self.zigObjectPtr()) |zo|
if (zo.eh_frame_index != null) break :blk true;
@@ -1891,6 +1901,7 @@ fn initSyntheticSections(self: *Elf) !void {
if (self.file(index).?.object.cies.items.len > 0) break true;
} else false;
};
+
if (needs_eh_frame) {
if (self.section_indexes.eh_frame == null) {
self.section_indexes.eh_frame = self.sectionByName(".eh_frame") orelse try self.addSection(.{
@@ -1922,13 +1933,17 @@ fn initSyntheticSections(self: *Elf) !void {
});
}
- if (self.section_indexes.got_plt == null) {
- self.section_indexes.got_plt = try self.addSection(.{
- .name = try self.insertShString(".got.plt"),
- .type = elf.SHT_PROGBITS,
- .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
- .addralign = @alignOf(u64),
- });
+ if (have_dynamic_linker) {
+ if (self.section_indexes.got_plt == null) {
+ self.section_indexes.got_plt = try self.addSection(.{
+ .name = try self.insertShString(".got.plt"),
+ .type = elf.SHT_PROGBITS,
+ .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
+ .addralign = @alignOf(u64),
+ });
+ }
+ } else {
+ assert(self.plt.symbols.items.len == 0);
}
const needs_rela_dyn = blk: {
@@ -1989,16 +2004,6 @@ fn initSyntheticSections(self: *Elf) !void {
});
}
- const is_exe_or_dyn_lib = switch (comp.config.output_mode) {
- .Exe => true,
- .Lib => comp.config.link_mode == .dynamic,
- .Obj => false,
- };
- const have_dynamic_linker = comp.config.link_mode == .dynamic and is_exe_or_dyn_lib and !target.dynamic_linker.eql(.none);
-
- const needs_interp = have_dynamic_linker and
- (comp.config.link_libc or comp.root_mod.resolved_target.is_explicit_dynamic_linker);
-
if (needs_interp and self.section_indexes.interp == null) {
self.section_indexes.interp = try self.addSection(.{
.name = try self.insertShString(".interp"),