authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-01-24 02:09:41+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-01-24 02:09:41+01:00
log1b544f447ac373ad676ccf921a2e8f2d05def15f
tree38b4cf8f07e79b8d3f876e692618460af064e2a4
parent5c42193b177e4b56ca91acb256cad36dd7cd4dec
parente437efd6015cdc369a2ca632565d105e9f04f20f

Merge pull request 'enable `thumb-windows-gnu` module tests' (#30968) from alexrp/zig:windows-pic into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/30968

5 files changed, 78 insertions(+), 38 deletions(-)

src/Compilation/Config.zig+1-1
...@@ -255,7 +255,7 @@ pub fn resolve(options: Options) ResolveError!Config {...@@ -255,7 +255,7 @@ pub fn resolve(options: Options) ResolveError!Config {
255 .Exe => true,255 .Exe => true,
256 };256 };
257257
258 if (target_util.cannotDynamicLink(target)) {258 if (!target_util.canDynamicLink(target)) {
259 if (options.link_mode == .dynamic) return error.TargetCannotDynamicLink;259 if (options.link_mode == .dynamic) return error.TargetCannotDynamicLink;
260 break :b .static;260 break :b .static;
261 }261 }
src/Package/Module.zig+1-1
...@@ -178,7 +178,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {...@@ -178,7 +178,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
178 return error.PieRequiresPic;178 return error.PieRequiresPic;
179 break :b true;179 break :b true;
180 }180 }
181 if (options.global.link_mode == .dynamic) {181 if (options.global.link_mode == .dynamic and target_util.requiresPicForDynamicLink(target)) {
182 if (options.inherited.pic == false)182 if (options.inherited.pic == false)
183 return error.DynamicLinkingRequiresPic;183 return error.DynamicLinkingRequiresPic;
184 break :b true;184 break :b true;
src/Sema.zig+9-1
...@@ -9180,7 +9180,15 @@ pub fn handleExternLibName(...@@ -9180,7 +9180,15 @@ pub fn handleExternLibName(
9180 );9180 );
9181 break :blk;9181 break :blk;
9182 }9182 }
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)) {
9184 return sema.fail(9192 return sema.fail(
9185 block,9193 block,
9186 src_loc,9194 src_loc,
src/target.zig+29-8
...@@ -10,10 +10,24 @@ const Feature = @import("Zcu.zig").Feature;...@@ -10,10 +10,24 @@ const Feature = @import("Zcu.zig").Feature;
1010
11pub const default_stack_protector_buffer_size = 4;11pub const default_stack_protector_buffer_size = 4;
1212
13pub fn cannotDynamicLink(target: *const std.Target) bool {13pub fn canDynamicLink(target: *const std.Target) bool {
14 return switch (target.os.tag) {14 return switch (target.cpu.arch) {
15 .freestanding => true,15 .amdgcn,
16 else => target.cpu.arch.isSpirV(),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 },
17 };31 };
18}32}
1933
...@@ -41,11 +55,20 @@ pub fn libCxxNeedsLibUnwind(target: *const std.Target) bool {...@@ -41,11 +55,20 @@ pub fn libCxxNeedsLibUnwind(target: *const std.Target) bool {
41/// This function returns whether non-pic code is completely invalid on the given target.55/// This function returns whether non-pic code is completely invalid on the given target.
42pub fn requiresPIC(target: *const std.Target, linking_libc: bool) bool {56pub fn requiresPIC(target: *const std.Target, linking_libc: bool) bool {
43 return target.abi.isAndroid() or57 return target.abi.isAndroid() or
44 target.os.tag == .windows or target.os.tag == .uefi or58 ((target.os.tag == .windows or target.os.tag == .uefi) and (target.cpu.arch == .aarch64 or target.cpu.arch == .x86_64)) or
45 target.requiresLibC() or59 target.requiresLibC() or
46 (linking_libc and target.isGnuLibC());60 (linking_libc and target.isGnuLibC());
47}61}
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
49pub fn picLevel(target: *const std.Target) u32 {72pub fn picLevel(target: *const std.Target) u32 {
50 // MIPS always uses PIC level 1; other platforms vary in their default PIC levels, but they73 // MIPS always uses PIC level 1; other platforms vary in their default PIC levels, but they
51 // support both level 1 and 2, in which case we prefer 2.74 // support both level 1 and 2, in which case we prefer 2.
...@@ -56,9 +79,7 @@ pub fn picLevel(target: *const std.Target) u32 {...@@ -56,9 +79,7 @@ pub fn picLevel(target: *const std.Target) u32 {
56/// C compiler argument is valid to Clang.79/// C compiler argument is valid to Clang.
57pub fn supports_fpic(target: *const std.Target) bool {80pub fn supports_fpic(target: *const std.Target) bool {
58 return switch (target.os.tag) {81 return switch (target.os.tag) {
59 .windows,82 .windows, .uefi => false, // Technically allowed for `Abi.gnu`, but completely ignored by Clang (by design) anyway.
60 .uefi,
61 => target.abi == .gnu,
62 else => true,83 else => true,
63 };84 };
64}85}
test/tests.zig+38-27
...@@ -28,6 +28,8 @@ const TestTarget = struct {...@@ -28,6 +28,8 @@ const TestTarget = struct {
28 use_lld: ?bool = null,28 use_lld: ?bool = null,
29 pic: ?bool = null,29 pic: ?bool = null,
30 strip: ?bool = null,30 strip: ?bool = null,
31 function_sections: ?bool = null,
32 data_sections: ?bool = null,
31 skip_modules: []const []const u8 = &.{},33 skip_modules: []const []const u8 = &.{},
3234
33 // This is intended for targets that, for any reason, shouldn't be run as part of a normal test35 // This is intended for targets that, for any reason, shouldn't be run as part of a normal test
...@@ -40,7 +42,7 @@ const test_targets = blk: {...@@ -40,7 +42,7 @@ const test_targets = blk: {
40 // getBaselineCpuFeatures calls populateDependencies which has a O(N ^ 2) algorithm42 // getBaselineCpuFeatures calls populateDependencies which has a O(N ^ 2) algorithm
41 // (where N is roughly 160, which technically makes it O(1), but it adds up to a43 // (where N is roughly 160, which technically makes it O(1), but it adds up to a
42 // lot of branches)44 // lot of branches)
43 @setEvalBranchQuota(60000);45 @setEvalBranchQuota(80_000);
44 break :blk [_]TestTarget{46 break :blk [_]TestTarget{
45 // Native Targets47 // Native Targets
4648
...@@ -1526,36 +1528,43 @@ const test_targets = blk: {...@@ -1526,36 +1528,43 @@ const test_targets = blk: {
1526 },1528 },
15271529
1528 .{1530 .{
1529 .target = .{1531 .target = std.Target.Query.parse(.{
1530 .cpu_arch = .thumb,1532 .arch_os_abi = "thumb-windows-msvc",
1531 .os_tag = .windows,1533 .cpu_features = "baseline+long_calls",
1532 .abi = .msvc,1534 }) catch unreachable,
1533 },1535 .pic = false, // Long calls don't work with PIC.
1536 .function_sections = true,
1537 .data_sections = true,
1534 },1538 },
1535 .{1539 .{
1536 .target = .{1540 .target = std.Target.Query.parse(.{
1537 .cpu_arch = .thumb,1541 .arch_os_abi = "thumb-windows-msvc",
1538 .os_tag = .windows,1542 .cpu_features = "baseline+long_calls",
1539 .abi = .msvc,1543 }) catch unreachable,
1540 },
1541 .link_libc = true,1544 .link_libc = true,
1545 .pic = false, // Long calls don't work with PIC.
1546 .function_sections = true,
1547 .data_sections = true,
1548 },
1549 .{
1550 .target = std.Target.Query.parse(.{
1551 .arch_os_abi = "thumb-windows-gnu",
1552 .cpu_features = "baseline+long_calls",
1553 }) catch unreachable,
1554 .pic = false, // Long calls don't work with PIC.
1555 .function_sections = true,
1556 .data_sections = true,
1557 },
1558 .{
1559 .target = std.Target.Query.parse(.{
1560 .arch_os_abi = "thumb-windows-gnu",
1561 .cpu_features = "baseline+long_calls",
1562 }) catch unreachable,
1563 .link_libc = true,
1564 .pic = false, // Long calls don't work with PIC.
1565 .function_sections = true,
1566 .data_sections = true,
1542 },1567 },
1543 // https://github.com/ziglang/zig/issues/24016
1544 // .{
1545 // .target = .{
1546 // .cpu_arch = .thumb,
1547 // .os_tag = .windows,
1548 // .abi = .gnu,
1549 // },
1550 // },
1551 // .{
1552 // .target = .{
1553 // .cpu_arch = .thumb,
1554 // .os_tag = .windows,
1555 // .abi = .gnu,
1556 // },
1557 // .link_libc = true,
1558 // },
15591568
1560 .{1569 .{
1561 .target = .{1570 .target = .{
...@@ -2454,6 +2463,8 @@ fn addOneModuleTest(...@@ -2454,6 +2463,8 @@ fn addOneModuleTest(
2454 if (options.build_options) |build_options| {2463 if (options.build_options) |build_options| {
2455 these_tests.root_module.addOptions("build_options", build_options);2464 these_tests.root_module.addOptions("build_options", build_options);
2456 }2465 }
2466 if (test_target.function_sections) |fs| these_tests.link_function_sections = fs;
2467 if (test_target.data_sections) |ds| these_tests.link_data_sections = ds;
2457 const single_threaded_suffix = if (test_target.single_threaded == true) "-single" else "";2468 const single_threaded_suffix = if (test_target.single_threaded == true) "-single" else "";
2458 const backend_suffix = if (test_target.use_llvm == true)2469 const backend_suffix = if (test_target.use_llvm == true)
2459 "-llvm"2470 "-llvm"