| // How to manually run this | 
 | // $ ./x.py test --target x86_64-unknown-linux-[musl,gnu] tests/run-make/static-pie | 
 |  | 
 | //@ only-x86_64 | 
 | //@ only-linux | 
 | //@ ignore-32bit | 
 |  | 
 | use std::process::Command; | 
 |  | 
 | use run_make_support::regex::Regex; | 
 | use run_make_support::{cmd, llvm_readobj, run_with_args, rustc, target}; | 
 |  | 
 | // Minimum major versions supporting -static-pie | 
 | const GCC_VERSION: u32 = 8; | 
 | const CLANG_VERSION: u32 = 9; | 
 |  | 
 | // Return `true` if the `compiler` version supports `-static-pie`. | 
 | fn ok_compiler_version(compiler: &str) -> bool { | 
 |     let (trigger, version_threshold) = match compiler { | 
 |         "clang" => ("__clang_major__", CLANG_VERSION), | 
 |         "gcc" => ("__GNUC__", GCC_VERSION), | 
 |         other => panic!("unexpected compiler '{other}', expected 'clang' or 'gcc'"), | 
 |     }; | 
 |  | 
 |     if Command::new(compiler).spawn().is_err() { | 
 |         eprintln!("No {compiler} version detected"); | 
 |         return false; | 
 |     } | 
 |  | 
 |     let compiler_output = | 
 |         cmd(compiler).stdin_buf(trigger).arg("-").arg("-E").arg("-x").arg("c").run().stdout_utf8(); | 
 |     let re = Regex::new(r"(?m)^(\d+)").unwrap(); | 
 |     let version: u32 = | 
 |         re.captures(&compiler_output).unwrap().get(1).unwrap().as_str().parse().unwrap(); | 
 |  | 
 |     if version >= version_threshold { | 
 |         eprintln!("{compiler} supports -static-pie"); | 
 |         true | 
 |     } else { | 
 |         eprintln!("{compiler} too old to support -static-pie, skipping test"); | 
 |         false | 
 |     } | 
 | } | 
 |  | 
 | fn test(compiler: &str) { | 
 |     if !ok_compiler_version(compiler) { | 
 |         return; | 
 |     } | 
 |  | 
 |     rustc() | 
 |         .input("test-aslr.rs") | 
 |         .linker(compiler) | 
 |         .arg("-Clinker-flavor=gcc") | 
 |         .arg("-Ctarget-feature=+crt-static") | 
 |         .run(); | 
 |  | 
 |     llvm_readobj() | 
 |         .symbols() | 
 |         .input("test-aslr") | 
 |         .run() | 
 |         .assert_stdout_not_contains("INTERP") | 
 |         .assert_stdout_contains("DYNAMIC"); | 
 |  | 
 |     run_with_args("test-aslr", &["--test-aslr"]); | 
 | } | 
 |  | 
 | fn main() { | 
 |     test("clang"); | 
 |     test("gcc"); | 
 | } |