From 4e45362529e05ba1be44fab48bc3469f5bb6492d Mon Sep 17 00:00:00 2001 From: mlugg Date: Wed, 10 Sep 2025 16:41:10 +0100 Subject: 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 --- src/link/Elf.zig | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) (limited to 'src/link') 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"), -- cgit v1.2.3