From 8149fffb1b67da3d20089144d71787e73493e38b Mon Sep 17 00:00:00 2001 From: Brad Smith Date: Sat, 10 Oct 2026 02:20:48 -0400 Subject: [PATCH] link/Lld: always pass -pie or -no-pie for executables When linking an executable, Zig only passed -pie when building a PIE and otherwise relied on LLD defaulting to non-PIE. That default isn't guaranteed: OpenBSD's system LLD defaults to PIE. With Zig built against it, non-PIE executables were linked as PIE, failing against non-PIC objects. For example, building stage3 on OpenBSD/aarch64 fails while generating the langref, when the global assembly doctest is linked for x86_64-linux: error: ld.lld: relocation R_X86_64_32S cannot be used against local symbol; recompile with -fPIC note: referenced by atomics.zig:104 (compiler_rt/atomics.zig:104) Pass -no-pie explicitly in the non-PIE case so the output matches comp.config.pie regardless of how LLD was built. --- src/link/Lld.zig | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/link/Lld.zig b/src/link/Lld.zig index ccdaadab5a4900375fc7396ee76842cffdff0df0..8146893508633f30811afecb55cb022987eb70a0 100644 --- a/src/link/Lld.zig +++ b/src/link/Lld.zig @@ -1029,8 +1029,10 @@ fn elfLink(lld: *Lld, arena: Allocator) !void { try argv.append("-shared"); } - if (comp.config.pie and output_mode == .Exe) { - try argv.append("-pie"); + if (output_mode == .Exe) { + // Always be explicit: some lld builds (e.g. OpenBSD's) default + // to PIE, which breaks non-PIE executables for other targets. + try argv.append(if (comp.config.pie) "-pie" else "-no-pie"); } if (is_exe_or_dyn_lib and target.os.tag == .netbsd) { -- 2.54.0