From 6db3289de7bef781140e510d192928c9b11a6b47 Mon Sep 17 00:00:00 2001 From: Jerry Wang Date: Wed, 19 Jun 2024 16:12:15 -0400 Subject: [PATCH 1/6] Add more flags for `llvm-readobj` --- src/tools/run-make-support/src/llvm.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/tools/run-make-support/src/llvm.rs b/src/tools/run-make-support/src/llvm.rs index 99bce08fc23..c397bd3b1a0 100644 --- a/src/tools/run-make-support/src/llvm.rs +++ b/src/tools/run-make-support/src/llvm.rs @@ -102,6 +102,24 @@ impl LlvmReadobj { self } + /// Pass `--program-headers` to display program headers. + pub fn program_headers(&mut self) -> &mut Self { + self.cmd.arg("--program-headers"); + self + } + + /// Pass `--symbols` to display the symbol. + pub fn symbols(&mut self) -> &mut Self { + self.cmd.arg("--symbols"); + self + } + + /// Pass `--dynamic-table` to display the dynamic symbol table. + pub fn dynamic_table(&mut self) -> &mut Self { + self.cmd.arg("--dynamic-table"); + self + } + /// Specify the section to display. pub fn section(&mut self, section: &str) -> &mut Self { self.cmd.arg("--string-dump"); From 5a66a796fcf6c486748feb757d46709b78caea08 Mon Sep 17 00:00:00 2001 From: Jerry Wang Date: Sat, 22 Jun 2024 14:14:01 -0400 Subject: [PATCH 2/6] Add `stdin` to `run_make_support::command::Command` --- src/tools/run-make-support/src/command.rs | 6 ++++-- src/tools/run-make-support/src/llvm.rs | 2 +- src/tools/run-make-support/src/rustc.rs | 2 +- src/tools/run-make-support/src/rustdoc.rs | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/tools/run-make-support/src/command.rs b/src/tools/run-make-support/src/command.rs index f39bcfd60df..0a1bd9b0b34 100644 --- a/src/tools/run-make-support/src/command.rs +++ b/src/tools/run-make-support/src/command.rs @@ -36,8 +36,10 @@ impl Command { Self { cmd: StdCommand::new(program), stdin: None, drop_bomb: DropBomb::arm(program) } } - pub fn set_stdin(&mut self, stdin: Box<[u8]>) { - self.stdin = Some(stdin); + /// Specify a stdin input + pub fn stdin>(&mut self, input: I) -> &mut Self { + self.stdin = Some(input.as_ref().to_vec().into_boxed_slice()); + self } /// Specify an environment variable. diff --git a/src/tools/run-make-support/src/llvm.rs b/src/tools/run-make-support/src/llvm.rs index c397bd3b1a0..7f42223bf7f 100644 --- a/src/tools/run-make-support/src/llvm.rs +++ b/src/tools/run-make-support/src/llvm.rs @@ -171,7 +171,7 @@ impl LlvmFilecheck { /// Pipe a read file into standard input containing patterns that will be matched against the .patterns(path) call. pub fn stdin>(&mut self, input: I) -> &mut Self { - self.cmd.set_stdin(input.as_ref().to_vec().into_boxed_slice()); + self.cmd.stdin(input); self } diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index a377dad99d6..28ece1dff12 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -244,7 +244,7 @@ impl Rustc { /// Specify a stdin input pub fn stdin>(&mut self, input: I) -> &mut Self { - self.cmd.set_stdin(input.as_ref().to_vec().into_boxed_slice()); + self.cmd.stdin(input); self } diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs index 93078561254..fb00427b1c1 100644 --- a/src/tools/run-make-support/src/rustdoc.rs +++ b/src/tools/run-make-support/src/rustdoc.rs @@ -92,7 +92,7 @@ impl Rustdoc { /// Specify a stdin input pub fn stdin>(&mut self, input: I) -> &mut Self { - self.cmd.set_stdin(input.as_ref().to_vec().into_boxed_slice()); + self.cmd.stdin(input); self } From e16f492e42537725c69c95693d7b8291127288b4 Mon Sep 17 00:00:00 2001 From: Jerry Wang Date: Wed, 19 Jun 2024 16:30:41 -0400 Subject: [PATCH 3/6] Migrate `relro-levels` to `rmake` --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/relro-levels/Makefile | 22 -------------- tests/run-make/relro-levels/rmake.rs | 29 +++++++++++++++++++ 3 files changed, 29 insertions(+), 23 deletions(-) delete mode 100644 tests/run-make/relro-levels/Makefile create mode 100644 tests/run-make/relro-levels/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index c3a94d17cd9..f7e572e0a97 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -151,7 +151,6 @@ run-make/raw-dylib-inline-cross-dylib/Makefile run-make/raw-dylib-link-ordinal/Makefile run-make/raw-dylib-stdcall-ordinal/Makefile run-make/redundant-libs/Makefile -run-make/relro-levels/Makefile run-make/remap-path-prefix-dwarf/Makefile run-make/remap-path-prefix/Makefile run-make/reproducible-build-2/Makefile diff --git a/tests/run-make/relro-levels/Makefile b/tests/run-make/relro-levels/Makefile deleted file mode 100644 index 94f08bcb494..00000000000 --- a/tests/run-make/relro-levels/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# only-linux -# -# This tests the different -Crelro-level values, and makes sure that they work properly. - -all: - # Ensure that binaries built with the full relro level links them with both - # RELRO and BIND_NOW for doing eager symbol resolving. - $(RUSTC) -Crelro-level=full hello.rs - readelf -l $(TMPDIR)/hello | grep -q GNU_RELRO - readelf -d $(TMPDIR)/hello | grep -q BIND_NOW - - $(RUSTC) -Crelro-level=partial hello.rs - readelf -l $(TMPDIR)/hello | grep -q GNU_RELRO - - # Ensure that we're *not* built with RELRO when setting it to off. We do - # not want to check for BIND_NOW however, as the linker might have that - # enabled by default. - $(RUSTC) -Crelro-level=off hello.rs - ! readelf -l $(TMPDIR)/hello | grep -q GNU_RELRO diff --git a/tests/run-make/relro-levels/rmake.rs b/tests/run-make/relro-levels/rmake.rs new file mode 100644 index 00000000000..cdfe899baaf --- /dev/null +++ b/tests/run-make/relro-levels/rmake.rs @@ -0,0 +1,29 @@ +// This tests the different -Crelro-level values, and makes sure that they work properly. + +//@ ignore-cross-compile +//@ only-linux + +use run_make_support::llvm_readobj; +use run_make_support::rustc; + +fn compile(relro_level: &str) { + rustc().arg(format!("-Crelro-level={relro_level}")).input("hello.rs").run(); +} + +fn main() { + // Ensure that binaries built with the full relro level links them with both + // RELRO and BIND_NOW for doing eager symbol resolving. + + compile("full"); + llvm_readobj().program_headers().input("hello").run().assert_stdout_contains("GNU_RELRO"); + llvm_readobj().dynamic_table().input("hello").run().assert_stdout_contains("BIND_NOW"); + + compile("partial"); + llvm_readobj().program_headers().input("hello").run().assert_stdout_contains("GNU_RELRO"); + + // Ensure that we're *not* built with RELRO when setting it to off. We do + // not want to check for BIND_NOW however, as the linker might have that + // enabled by default. + compile("off"); + llvm_readobj().program_headers().input("hello").run().assert_stdout_not_contains("GNU_RELRO"); +} From f90d4e4371b91688d01906624396f96ec53ff094 Mon Sep 17 00:00:00 2001 From: Jerry Wang Date: Wed, 19 Jun 2024 18:58:59 -0400 Subject: [PATCH 4/6] Migrate `static-pie` to `rmake` --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/static-pie/Makefile | 18 -------- tests/run-make/static-pie/rmake.rs | 46 +++++++++++++++++++ 3 files changed, 46 insertions(+), 19 deletions(-) delete mode 100644 tests/run-make/static-pie/Makefile create mode 100644 tests/run-make/static-pie/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index f7e572e0a97..07073ef5d40 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -176,7 +176,6 @@ run-make/split-debuginfo/Makefile run-make/stable-symbol-names/Makefile run-make/static-dylib-by-default/Makefile run-make/static-extern-type/Makefile -run-make/static-pie/Makefile run-make/staticlib-blank-lib/Makefile run-make/staticlib-dylib-linkage/Makefile run-make/std-core-cycle/Makefile diff --git a/tests/run-make/static-pie/Makefile b/tests/run-make/static-pie/Makefile deleted file mode 100644 index 8379730cc3d..00000000000 --- a/tests/run-make/static-pie/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -include ../tools.mk - -# only-x86_64 -# only-linux -# ignore-32bit - -# How to manually run this -# $ ./x.py test --target x86_64-unknown-linux-[musl,gnu] tests/run-make/static-pie - -all: test-clang test-gcc - -test-%: - if ./check_$*_version.sh; then\ - ${RUSTC} -Clinker=$* -Clinker-flavor=gcc --target ${TARGET} -C target-feature=+crt-static test-aslr.rs; \ - ! readelf -l $(call RUN_BINFILE,test-aslr) | $(CGREP) INTERP; \ - readelf -l $(call RUN_BINFILE,test-aslr) | $(CGREP) DYNAMIC; \ - $(call RUN,test-aslr) --test-aslr; \ - fi diff --git a/tests/run-make/static-pie/rmake.rs b/tests/run-make/static-pie/rmake.rs new file mode 100644 index 00000000000..038e8b48071 --- /dev/null +++ b/tests/run-make/static-pie/rmake.rs @@ -0,0 +1,46 @@ +// 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; +use run_make_support::rustc; +use run_make_support::{cmd, run_with_args, target}; + +fn ok_compiler_version(compiler: &str) -> bool { + let check_file = format!("check_{compiler}_version.sh"); + + Command::new(check_file).status().is_ok_and(|status| status.success()) +} + +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"); +} From c69770d730f8f5ff53b92f73be9deb5081f0c1b0 Mon Sep 17 00:00:00 2001 From: Jerry Wang Date: Wed, 19 Jun 2024 20:58:56 -0400 Subject: [PATCH 5/6] Migrate `static-pie` scripts to `rmake` --- .../static-pie/check_clang_version.sh | 20 ----------- .../run-make/static-pie/check_gcc_version.sh | 20 ----------- tests/run-make/static-pie/rmake.rs | 33 +++++++++++++++++-- 3 files changed, 30 insertions(+), 43 deletions(-) delete mode 100755 tests/run-make/static-pie/check_clang_version.sh delete mode 100755 tests/run-make/static-pie/check_gcc_version.sh diff --git a/tests/run-make/static-pie/check_clang_version.sh b/tests/run-make/static-pie/check_clang_version.sh deleted file mode 100755 index b8e97c3da7d..00000000000 --- a/tests/run-make/static-pie/check_clang_version.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -if command -v clang > /dev/null -then - CLANG_VERSION=$(echo __clang_major__ | clang -E -x c - | grep -v -e '^#' ) - echo "clang version $CLANG_VERSION detected" - if (( $CLANG_VERSION >= 9 )) - then - echo "clang supports -static-pie" - exit 0 - else - echo "clang too old to support -static-pie, skipping test" - exit 1 - fi -else - echo "No clang version detected" - exit 2 -fi diff --git a/tests/run-make/static-pie/check_gcc_version.sh b/tests/run-make/static-pie/check_gcc_version.sh deleted file mode 100755 index d07e1d151df..00000000000 --- a/tests/run-make/static-pie/check_gcc_version.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -if command -v gcc > /dev/null -then - GCC_VERSION=$(echo __GNUC__ | gcc -E -x c - | grep -v -e '^#' ) - echo "gcc version $GCC_VERSION detected" - if (( $GCC_VERSION >= 8 )) - then - echo "gcc supports -static-pie" - exit 0 - else - echo "gcc too old to support -static-pie, skipping test" - exit 1 - fi -else - echo "No gcc version detected" - exit 2 -fi diff --git a/tests/run-make/static-pie/rmake.rs b/tests/run-make/static-pie/rmake.rs index 038e8b48071..77c5e253bc0 100644 --- a/tests/run-make/static-pie/rmake.rs +++ b/tests/run-make/static-pie/rmake.rs @@ -8,13 +8,40 @@ use std::process::Command; use run_make_support::llvm_readobj; +use run_make_support::regex::Regex; use run_make_support::rustc; use run_make_support::{cmd, run_with_args, target}; -fn ok_compiler_version(compiler: &str) -> bool { - let check_file = format!("check_{compiler}_version.sh"); +// Minimum major versions supporting -static-pie +const GCC_VERSION: u32 = 8; +const CLANG_VERSION: u32 = 9; - Command::new(check_file).status().is_ok_and(|status| status.success()) +// 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(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) { From a19077d0f3339f31bd6b1b5d7b2b3006480c715a Mon Sep 17 00:00:00 2001 From: Jerry Wang Date: Sat, 22 Jun 2024 19:44:51 -0400 Subject: [PATCH 6/6] Enable cross compilation on `run-make/relro-levels` --- tests/run-make/relro-levels/rmake.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/run-make/relro-levels/rmake.rs b/tests/run-make/relro-levels/rmake.rs index cdfe899baaf..56545ebc5aa 100644 --- a/tests/run-make/relro-levels/rmake.rs +++ b/tests/run-make/relro-levels/rmake.rs @@ -1,6 +1,5 @@ // This tests the different -Crelro-level values, and makes sure that they work properly. -//@ ignore-cross-compile //@ only-linux use run_make_support::llvm_readobj;