2024-06-19 17:58:59 -05:00
|
|
|
// 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::llvm_readobj;
|
2024-06-19 19:58:56 -05:00
|
|
|
use run_make_support::regex::Regex;
|
2024-06-19 17:58:59 -05:00
|
|
|
use run_make_support::rustc;
|
|
|
|
use run_make_support::{cmd, run_with_args, target};
|
|
|
|
|
2024-06-19 19:58:56 -05:00
|
|
|
// 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`.
|
2024-06-19 17:58:59 -05:00
|
|
|
fn ok_compiler_version(compiler: &str) -> bool {
|
2024-06-19 19:58:56 -05:00
|
|
|
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;
|
|
|
|
}
|
2024-06-19 17:58:59 -05:00
|
|
|
|
2024-06-19 19:58:56 -05:00
|
|
|
let compiler_output =
|
|
|
|
cmd(compiler).stdin(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
|
|
|
|
}
|
2024-06-19 17:58:59 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
fn test(compiler: &str) {
|
|
|
|
if !ok_compiler_version(compiler) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
rustc()
|
|
|
|
.input("test-aslr.rs")
|
|
|
|
.target(&target())
|
|
|
|
.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");
|
|
|
|
}
|