authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-01-23 19:45:34+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-01-23 21:16:01+01:00
log909159ad8ea9203297c0b670446381c537554525
tree9b10daf0618c3fad1488622e0b9e996e5d8d3ccc
parent20fae334acb79dd367e74a3b90af5fa1445364cd
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

compiler: don't enforce PIC for x86-windows and thumb-windows

Only x86_64-windows and aarch64-windows actually require PIC.

4 files changed, 39 insertions(+), 8 deletions(-)

src/Compilation/Config.zig+1-1
......@@ -255,7 +255,7 @@ pub fn resolve(options: Options) ResolveError!Config {
255255 .Exe => true,
256256 };
257257
258 if (target_util.cannotDynamicLink(target)) {
258 if (!target_util.canDynamicLink(target)) {
259259 if (options.link_mode == .dynamic) return error.TargetCannotDynamicLink;
260260 break :b .static;
261261 }
src/Package/Module.zig+1-1
......@@ -178,7 +178,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
178178 return error.PieRequiresPic;
179179 break :b true;
180180 }
181 if (options.global.link_mode == .dynamic) {
181 if (options.global.link_mode == .dynamic and target_util.requiresPicForDynamicLink(target)) {
182182 if (options.inherited.pic == false)
183183 return error.DynamicLinkingRequiresPic;
184184 break :b true;
src/Sema.zig+9-1
......@@ -9180,7 +9180,15 @@ pub fn handleExternLibName(
91809180 );
91819181 break :blk;
91829182 }
9183 if (!target.cpu.arch.isWasm() and !block.ownerModule().pic) {
9183 if (!target_util.canDynamicLink(target)) {
9184 return sema.fail(
9185 block,
9186 src_loc,
9187 "dependency on dynamic library '{s}' cannot be satisfied because target does not support dynamic linking",
9188 .{lib_name},
9189 );
9190 }
9191 if (!block.ownerModule().pic and target_util.requiresPicForDynamicLink(target)) {
91849192 return sema.fail(
91859193 block,
91869194 src_loc,
src/target.zig+28-5
......@@ -10,10 +10,24 @@ const Feature = @import("Zcu.zig").Feature;
1010
1111pub const default_stack_protector_buffer_size = 4;
1212
13pub fn cannotDynamicLink(target: *const std.Target) bool {
14 return switch (target.os.tag) {
15 .freestanding, .uefi => true,
16 else => target.cpu.arch.isSpirV(),
13pub fn canDynamicLink(target: *const std.Target) bool {
14 return switch (target.cpu.arch) {
15 .amdgcn,
16 .bpfeb,
17 .bpfel,
18 .nvptx,
19 .nvptx64,
20 .spirv32,
21 .spirv64,
22 => false,
23 .wasm32,
24 .wasm64,
25 => true,
26 else => switch (target.os.tag) {
27 // This list is likely incomplete.
28 .freestanding, .uefi => false,
29 else => true,
30 },
1731 };
1832}
1933
......@@ -41,11 +55,20 @@ pub fn libCxxNeedsLibUnwind(target: *const std.Target) bool {
4155/// This function returns whether non-pic code is completely invalid on the given target.
4256pub fn requiresPIC(target: *const std.Target, linking_libc: bool) bool {
4357 return target.abi.isAndroid() or
44 target.os.tag == .windows or target.os.tag == .uefi or
58 ((target.os.tag == .windows or target.os.tag == .uefi) and (target.cpu.arch == .aarch64 or target.cpu.arch == .x86_64)) or
4559 target.requiresLibC() or
4660 (linking_libc and target.isGnuLibC());
4761}
4862
63pub fn requiresPicForDynamicLink(target: *const std.Target) bool {
64 assert(canDynamicLink(target));
65
66 return switch (target.os.tag) {
67 .windows => target.cpu.arch == .aarch64 or target.cpu.arch == .x86_64,
68 else => !target.cpu.arch.isWasm(),
69 };
70}
71
4972pub fn picLevel(target: *const std.Target) u32 {
5073 // MIPS always uses PIC level 1; other platforms vary in their default PIC levels, but they
5174 // support both level 1 and 2, in which case we prefer 2.