| author | |
| committer | |
| log | a81fb5fb76131d0df3042f20e2d20a3b9216b254 |
| tree | 65306edd14da5500e59a54107d159b248237e78a |
| parent | 826e1c30ba81884e1a8fad8664b3da17953d89d1 |
| signature |
To my knowledge, the only platforms that actually *require* PIE are Fuchsia and
Android, and the latter *only* when building a dynamically-linked executable.
OpenBSD and macOS both strongly encourage using PIE by default, but it isn't
technically required. So for the latter platforms, we enable it by default but
don't enforce it.
Also, importantly, if we're building an object file or a static library, and the
user hasn't explicitly told us whether to build PIE or non-PIE code (and the
target doesn't require PIE), we should *not* default to PIE. Doing so produces
code that cannot be linked into non-PIE output. In other words, building an
object file or a static library as PIE is an optimization only to be done when
the user knows that it'll end up in a PIE executable in the end.
Closes #21837.2 files changed, 13 insertions(+), 10 deletions(-)
src/Compilation/Config.zig+13-6| ... | @@ -416,22 +416,29 @@ pub fn resolve(options: Options) ResolveError!Config { | ... | @@ -416,22 +416,29 @@ pub fn resolve(options: Options) ResolveError!Config { |
| 416 | 416 | ||
| 417 | const pie: bool = b: { | 417 | const pie: bool = b: { |
| 418 | switch (options.output_mode) { | 418 | switch (options.output_mode) { |
| 419 | .Obj, .Exe => {}, | 419 | .Exe => if (target.os.tag == .fuchsia or |
| 420 | (target.abi.isAndroid() and link_mode == .dynamic)) | ||
| 421 | { | ||
| 422 | if (options.pie == false) return error.TargetRequiresPie; | ||
| 423 | break :b true; | ||
| 424 | }, | ||
| 420 | .Lib => if (link_mode == .dynamic) { | 425 | .Lib => if (link_mode == .dynamic) { |
| 421 | if (options.pie == true) return error.DynamicLibraryPrecludesPie; | 426 | if (options.pie == true) return error.DynamicLibraryPrecludesPie; |
| 422 | break :b false; | 427 | break :b false; |
| 423 | }, | 428 | }, |
| 424 | } | 429 | .Obj => {}, |
| 425 | if (target_util.requiresPIE(target)) { | ||
| 426 | if (options.pie == false) return error.TargetRequiresPie; | ||
| 427 | break :b true; | ||
| 428 | } | 430 | } |
| 429 | if (options.any_sanitize_thread) { | 431 | if (options.any_sanitize_thread) { |
| 430 | if (options.pie == false) return error.SanitizeThreadRequiresPie; | 432 | if (options.pie == false) return error.SanitizeThreadRequiresPie; |
| 431 | break :b true; | 433 | break :b true; |
| 432 | } | 434 | } |
| 433 | if (options.pie) |pie| break :b pie; | 435 | if (options.pie) |pie| break :b pie; |
| 434 | break :b false; | 436 | break :b if (options.output_mode == .Exe) switch (target.os.tag) { |
| 437 | .fuchsia, | ||
| 438 | .openbsd, | ||
| 439 | => true, | ||
| 440 | else => target.os.tag.isDarwin(), | ||
| 441 | } else false; | ||
| 435 | }; | 442 | }; |
| 436 | 443 | ||
| 437 | const root_strip = b: { | 444 | const root_strip = b: { |
src/target.zig-4| ... | @@ -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 | } |
| 45 | 45 | ||
| 46 | pub 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. |
| 51 | pub fn requiresPIC(target: std.Target, linking_libc: bool) bool { | 47 | pub fn requiresPIC(target: std.Target, linking_libc: bool) bool { |
| 52 | return target.abi.isAndroid() or | 48 | return target.abi.isAndroid() or |