| use std::process::Command; | |
| #[cfg(target_os="macos")] | |
| fn is_pie_executable(executable: &str) -> bool { | |
| let output = Command::new("otool") | |
| .args(["-hv", executable]) | |
| .output() | |
| .expect("Failed to check executable"); | |
| if !output.status.success() { | |
| panic!("otool exited with non-zero exit code"); | |
| } | |
| output.stdout.windows(5).any(|w| { | |
| (w[0] == b' ' || w[0] == b'\t') | |
| && (w[1..=3] == b"PIE") | |
| && (w[4] == b' ' || w[4] == b'\n') | |
| }) | |
| } | |
| #[cfg(all(target_family="unix", not(target_os="macos")))] | |
| fn is_pie_executable(executable: &str) -> bool { | |
| let output = Command::new("readelf") | |
| .args(["-lW", executable]) | |
| .env("LANG", "C") | |
| .env("LC_ALL", "C") | |
| .output() | |
| .expect("Failed to check executable"); | |
| if !output.status.success() { | |
| panic!("readelf exited with non-zero exit code"); | |
| } | |
| let is_pie = output.stdout.windows(20).any(|w| w == b"Elf file type is DYN"); | |
| let is_not_pie = output.stdout.windows(21).any(|w| w == b"Elf file type is EXEC"); | |
| assert!(is_pie ^ is_not_pie, "Cannot determine type of ELF file"); | |
| is_pie | |
| } | |
| fn main() { | |
| let commands = [ | |
| // The actual path to the commands will be filled in by CMake. | |
| r#"$<TARGET_FILE:default_RustPie>"#, | |
| r#"$<TARGET_FILE:disabled_RustPie>"#, | |
| r#"$<TARGET_FILE:enabled_RustPie>"#, | |
| ]; | |
| for command in commands { | |
| println!("Start command: {command:?}"); | |
| let result = Command::new(command) | |
| .spawn() | |
| .expect("Failed to launch command") | |
| .wait() | |
| .expect("Failure while waiting for process to finish") | |
| .success(); | |
| if !result { | |
| panic!("Process exited with non-zero exit code."); | |
| } | |
| } | |
| assert!( | |
| !is_pie_executable(commands[1]), | |
| "ERROR: disabled_RustPie must not be a PIE executable, but it is not." | |
| ); | |
| assert!( | |
| is_pie_executable(commands[2]), | |
| "ERROR: enabled_RustPie must be a PIE executable, but it is not." | |
| ); | |
| } |