authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-06-05 01:14:03+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-06-05 01:14:03+02:00
log14873f9a3434a0d753ca8438f389a7931956cf26
tree48528df4b76310258f7f9ec9641920262ed775a5
parent80f2aeb8bee41707eb5be5a0dcf21ff2b8137919
parentc8b92f3a8ed740148c225608b6504fb8461249bc
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #24068 from alexrp/android-pic-pie

compiler: Rework PIE option logic.

4 files changed, 28 insertions(+), 11 deletions(-)

src/Compilation.zig+3
...@@ -6228,6 +6228,9 @@ pub fn addCCArgs(...@@ -6228,6 +6228,9 @@ pub fn addCCArgs(
6228 }6228 }
62296229
6230 if (target_util.supports_fpic(target)) {6230 if (target_util.supports_fpic(target)) {
6231 // PIE needs to go before PIC because Clang interprets `-fno-PIE` to imply `-fno-PIC`, which
6232 // we don't necessarily want.
6233 try argv.append(if (comp.config.pie) "-fPIE" else "-fno-PIE");
6231 try argv.append(if (mod.pic) "-fPIC" else "-fno-PIC");6234 try argv.append(if (mod.pic) "-fPIC" else "-fno-PIC");
6232 }6235 }
62336236
src/Compilation/Config.zig+18-6
...@@ -135,6 +135,7 @@ pub const ResolveError = error{...@@ -135,6 +135,7 @@ pub const ResolveError = error{
135 LibCppRequiresLibC,135 LibCppRequiresLibC,
136 LibUnwindRequiresLibC,136 LibUnwindRequiresLibC,
137 TargetCannotDynamicLink,137 TargetCannotDynamicLink,
138 TargetCannotStaticLinkExecutables,
138 LibCRequiresDynamicLinking,139 LibCRequiresDynamicLinking,
139 SharedLibrariesRequireDynamicLinking,140 SharedLibrariesRequireDynamicLinking,
140 ExportMemoryAndDynamicIncompatible,141 ExportMemoryAndDynamicIncompatible,
...@@ -360,6 +361,10 @@ pub fn resolve(options: Options) ResolveError!Config {...@@ -360,6 +361,10 @@ pub fn resolve(options: Options) ResolveError!Config {
360 if (options.link_mode == .dynamic) return error.TargetCannotDynamicLink;361 if (options.link_mode == .dynamic) return error.TargetCannotDynamicLink;
361 break :b .static;362 break :b .static;
362 }363 }
364 if (target.os.tag == .fuchsia and options.output_mode == .Exe) {
365 if (options.link_mode == .static) return error.TargetCannotStaticLinkExecutables;
366 break :b .dynamic;
367 }
363 if (explicitly_exe_or_dyn_lib and link_libc and368 if (explicitly_exe_or_dyn_lib and link_libc and
364 (target_util.osRequiresLibC(target) or369 (target_util.osRequiresLibC(target) or
365 // For these libcs, Zig can only provide dynamic libc when cross-compiling.370 // For these libcs, Zig can only provide dynamic libc when cross-compiling.
...@@ -416,22 +421,29 @@ pub fn resolve(options: Options) ResolveError!Config {...@@ -416,22 +421,29 @@ pub fn resolve(options: Options) ResolveError!Config {
416421
417 const pie: bool = b: {422 const pie: bool = b: {
418 switch (options.output_mode) {423 switch (options.output_mode) {
419 .Obj, .Exe => {},424 .Exe => if (target.os.tag == .fuchsia or
425 (target.abi.isAndroid() and link_mode == .dynamic))
426 {
427 if (options.pie == false) return error.TargetRequiresPie;
428 break :b true;
429 },
420 .Lib => if (link_mode == .dynamic) {430 .Lib => if (link_mode == .dynamic) {
421 if (options.pie == true) return error.DynamicLibraryPrecludesPie;431 if (options.pie == true) return error.DynamicLibraryPrecludesPie;
422 break :b false;432 break :b false;
423 },433 },
424 }434 .Obj => {},
425 if (target_util.requiresPIE(target)) {
426 if (options.pie == false) return error.TargetRequiresPie;
427 break :b true;
428 }435 }
429 if (options.any_sanitize_thread) {436 if (options.any_sanitize_thread) {
430 if (options.pie == false) return error.SanitizeThreadRequiresPie;437 if (options.pie == false) return error.SanitizeThreadRequiresPie;
431 break :b true;438 break :b true;
432 }439 }
433 if (options.pie) |pie| break :b pie;440 if (options.pie) |pie| break :b pie;
434 break :b false;441 break :b if (options.output_mode == .Exe) switch (target.os.tag) {
442 .fuchsia,
443 .openbsd,
444 => true,
445 else => target.os.tag.isDarwin(),
446 } else false;
435 };447 };
436448
437 const root_strip = b: {449 const root_strip = b: {
src/main.zig+1
...@@ -4118,6 +4118,7 @@ fn createModule(...@@ -4118,6 +4118,7 @@ fn createModule(
4118 error.LibCppRequiresLibC => fatal("libc++ requires linking libc", .{}),4118 error.LibCppRequiresLibC => fatal("libc++ requires linking libc", .{}),
4119 error.LibUnwindRequiresLibC => fatal("libunwind requires linking libc", .{}),4119 error.LibUnwindRequiresLibC => fatal("libunwind requires linking libc", .{}),
4120 error.TargetCannotDynamicLink => fatal("dynamic linking unavailable on the specified target", .{}),4120 error.TargetCannotDynamicLink => fatal("dynamic linking unavailable on the specified target", .{}),
4121 error.TargetCannotStaticLinkExecutables => fatal("static linking of executables unavailable on the specified target", .{}),
4121 error.LibCRequiresDynamicLinking => fatal("libc of the specified target requires dynamic linking", .{}),4122 error.LibCRequiresDynamicLinking => fatal("libc of the specified target requires dynamic linking", .{}),
4122 error.SharedLibrariesRequireDynamicLinking => fatal("using shared libraries requires dynamic linking", .{}),4123 error.SharedLibrariesRequireDynamicLinking => fatal("using shared libraries requires dynamic linking", .{}),
4123 error.ExportMemoryAndDynamicIncompatible => fatal("exporting memory is incompatible with dynamic linking", .{}),4124 error.ExportMemoryAndDynamicIncompatible => fatal("exporting memory is incompatible with dynamic linking", .{}),
src/target.zig+6-5
...@@ -43,10 +43,6 @@ pub fn libCxxNeedsLibUnwind(target: std.Target) bool {...@@ -43,10 +43,6 @@ pub fn libCxxNeedsLibUnwind(target: std.Target) bool {
43 };43 };
44}44}
4545
46pub fn requiresPIE(target: std.Target) bool {
47 return target.abi.isAndroid() or target.os.tag.isDarwin() or target.os.tag == .openbsd;
48}
49
50/// This function returns whether non-pic code is completely invalid on the given target.46/// This function returns whether non-pic code is completely invalid on the given target.
51pub fn requiresPIC(target: std.Target, linking_libc: bool) bool {47pub fn requiresPIC(target: std.Target, linking_libc: bool) bool {
52 return target.abi.isAndroid() or48 return target.abi.isAndroid() or
...@@ -64,7 +60,12 @@ pub fn picLevel(target: std.Target) u32 {...@@ -64,7 +60,12 @@ pub fn picLevel(target: std.Target) u32 {
64/// This is not whether the target supports Position Independent Code, but whether the -fPIC60/// This is not whether the target supports Position Independent Code, but whether the -fPIC
65/// C compiler argument is valid to Clang.61/// C compiler argument is valid to Clang.
66pub fn supports_fpic(target: std.Target) bool {62pub fn supports_fpic(target: std.Target) bool {
67 return target.os.tag != .windows and target.os.tag != .uefi;63 return switch (target.os.tag) {
64 .windows,
65 .uefi,
66 => target.abi == .gnu or target.abi == .cygnus,
67 else => true,
68 };
68}69}
6970
70pub fn alwaysSingleThreaded(target: std.Target) bool {71pub fn alwaysSingleThreaded(target: std.Target) bool {