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

compiler: Rework PIE option logic.
This commit is contained in:
Alex Rønne Petersen 2025-06-05 01:14:03 +02:00 committed by GitHub
commit 14873f9a34
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 28 additions and 11 deletions

View file

@ -6228,6 +6228,9 @@ pub fn addCCArgs(
}
if (target_util.supports_fpic(target)) {
// PIE needs to go before PIC because Clang interprets `-fno-PIE` to imply `-fno-PIC`, which
// we don't necessarily want.
try argv.append(if (comp.config.pie) "-fPIE" else "-fno-PIE");
try argv.append(if (mod.pic) "-fPIC" else "-fno-PIC");
}

View file

@ -135,6 +135,7 @@ pub const ResolveError = error{
LibCppRequiresLibC,
LibUnwindRequiresLibC,
TargetCannotDynamicLink,
TargetCannotStaticLinkExecutables,
LibCRequiresDynamicLinking,
SharedLibrariesRequireDynamicLinking,
ExportMemoryAndDynamicIncompatible,
@ -360,6 +361,10 @@ pub fn resolve(options: Options) ResolveError!Config {
if (options.link_mode == .dynamic) return error.TargetCannotDynamicLink;
break :b .static;
}
if (target.os.tag == .fuchsia and options.output_mode == .Exe) {
if (options.link_mode == .static) return error.TargetCannotStaticLinkExecutables;
break :b .dynamic;
}
if (explicitly_exe_or_dyn_lib and link_libc and
(target_util.osRequiresLibC(target) or
// For these libcs, Zig can only provide dynamic libc when cross-compiling.
@ -416,22 +421,29 @@ pub fn resolve(options: Options) ResolveError!Config {
const pie: bool = b: {
switch (options.output_mode) {
.Obj, .Exe => {},
.Exe => if (target.os.tag == .fuchsia or
(target.abi.isAndroid() and link_mode == .dynamic))
{
if (options.pie == false) return error.TargetRequiresPie;
break :b true;
},
.Lib => if (link_mode == .dynamic) {
if (options.pie == true) return error.DynamicLibraryPrecludesPie;
break :b false;
},
}
if (target_util.requiresPIE(target)) {
if (options.pie == false) return error.TargetRequiresPie;
break :b true;
.Obj => {},
}
if (options.any_sanitize_thread) {
if (options.pie == false) return error.SanitizeThreadRequiresPie;
break :b true;
}
if (options.pie) |pie| break :b pie;
break :b false;
break :b if (options.output_mode == .Exe) switch (target.os.tag) {
.fuchsia,
.openbsd,
=> true,
else => target.os.tag.isDarwin(),
} else false;
};
const root_strip = b: {

View file

@ -4118,6 +4118,7 @@ fn createModule(
error.LibCppRequiresLibC => fatal("libc++ requires linking libc", .{}),
error.LibUnwindRequiresLibC => fatal("libunwind requires linking libc", .{}),
error.TargetCannotDynamicLink => fatal("dynamic linking unavailable on the specified target", .{}),
error.TargetCannotStaticLinkExecutables => fatal("static linking of executables unavailable on the specified target", .{}),
error.LibCRequiresDynamicLinking => fatal("libc of the specified target requires dynamic linking", .{}),
error.SharedLibrariesRequireDynamicLinking => fatal("using shared libraries requires dynamic linking", .{}),
error.ExportMemoryAndDynamicIncompatible => fatal("exporting memory is incompatible with dynamic linking", .{}),

View file

@ -43,10 +43,6 @@ pub fn libCxxNeedsLibUnwind(target: std.Target) bool {
};
}
pub fn requiresPIE(target: std.Target) bool {
return target.abi.isAndroid() or target.os.tag.isDarwin() or target.os.tag == .openbsd;
}
/// This function returns whether non-pic code is completely invalid on the given target.
pub fn requiresPIC(target: std.Target, linking_libc: bool) bool {
return target.abi.isAndroid() or
@ -64,7 +60,12 @@ pub fn picLevel(target: std.Target) u32 {
/// This is not whether the target supports Position Independent Code, but whether the -fPIC
/// C compiler argument is valid to Clang.
pub fn supports_fpic(target: std.Target) bool {
return target.os.tag != .windows and target.os.tag != .uefi;
return switch (target.os.tag) {
.windows,
.uefi,
=> target.abi == .gnu or target.abi == .cygnus,
else => true,
};
}
pub fn alwaysSingleThreaded(target: std.Target) bool {