Skip to content

Commit c1f1bc1

Browse files
committed
Teach bootstrap how to build rust_test_helpers for pauthtest
Also: * update tests to force dynamic library when targetting pauthtest * various test fixes * introduce end-to-end tests for pauthtest (in run-make)
1 parent faed284 commit c1f1bc1

61 files changed

Lines changed: 492 additions & 72 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/bootstrap/src/core/build_steps/test.rs

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::collections::HashSet;
1010
use std::env::split_paths;
1111
use std::ffi::{OsStr, OsString};
1212
use std::path::{Path, PathBuf};
13+
use std::process::Command;
1314
use std::{env, fs, iter};
1415

1516
use build_helper::exit;
@@ -2227,7 +2228,13 @@ Please disable assertions with `rust.debug-assertions = false`.
22272228
"-Lnative={}",
22282229
builder.test_helpers_out(test_compiler.host).display()
22292230
));
2230-
targetflags.push(format!("-Lnative={}", builder.test_helpers_out(target).display()));
2231+
let target_helpers = builder.test_helpers_out(target);
2232+
targetflags.push(format!("-Lnative={}", target_helpers.display()));
2233+
if target.is_pauthtest() {
2234+
// For the pauthtest target, embed an rpath to the directory containing the helper
2235+
// dynamic library.
2236+
targetflags.push(format!("-Clink-arg=-Wl,-rpath,{}", target_helpers.display()));
2237+
}
22312238
}
22322239

22332240
for flag in hostflags {
@@ -3858,32 +3865,54 @@ impl Step for TestHelpers {
38583865
};
38593866
let dst = builder.test_helpers_out(target);
38603867
let src = builder.src.join("tests/auxiliary/rust_test_helpers.c");
3861-
if up_to_date(&src, &dst.join("librust_test_helpers.a")) {
3862-
return;
3863-
}
3864-
38653868
let _guard = builder.msg_unstaged(Kind::Build, "test helpers", target);
38663869
t!(fs::create_dir_all(&dst));
3867-
let mut cfg = cc::Build::new();
38683870

3869-
// We may have found various cross-compilers a little differently due to our
3870-
// extra configuration, so inform cc of these compilers. Note, though, that
3871-
// on MSVC we still need cc's detection of env vars (ugh).
3872-
if !target.is_msvc() {
3873-
if let Some(ar) = builder.ar(target) {
3874-
cfg.archiver(ar);
3871+
if !up_to_date(&src, &dst.join("librust_test_helpers.a")) {
3872+
let mut cfg = cc::Build::new();
3873+
3874+
// We may have found various cross-compilers a little differently due to our
3875+
// extra configuration, so inform cc of these compilers. Note, though, that
3876+
// on MSVC we still need cc's detection of env vars (ugh).
3877+
if !target.is_msvc() {
3878+
if let Some(ar) = builder.ar(target) {
3879+
cfg.archiver(ar);
3880+
}
3881+
cfg.compiler(builder.cc(target));
3882+
}
3883+
cfg.cargo_metadata(false)
3884+
.out_dir(&dst)
3885+
.target(&target.triple)
3886+
.host(&builder.config.host_target.triple)
3887+
.opt_level(0)
3888+
.warnings(false)
3889+
.debug(false)
3890+
.file(builder.src.join("tests/auxiliary/rust_test_helpers.c"))
3891+
.compile("rust_test_helpers");
3892+
}
3893+
if target.is_pauthtest() {
3894+
let so = dst.join("librust_test_helpers.so");
3895+
if up_to_date(&src, &so) {
3896+
return;
3897+
}
3898+
3899+
let status = Command::new(builder.cc(target))
3900+
.arg("-target")
3901+
.arg(target.triple)
3902+
.arg("-march=armv8.3-a+pauth")
3903+
.arg("-fPIC")
3904+
.arg("-shared")
3905+
.arg("-O0") // Use O0 to match what static library is compiled at.
3906+
.arg("-o")
3907+
.arg(&so)
3908+
.arg(&src)
3909+
.status()
3910+
.unwrap_or_else(|_| panic!("Failed to run clang for {} toolchain", target.triple));
3911+
3912+
if !status.success() {
3913+
panic!("Linking of librust_test_helpers.so failed (target: {})", target.triple);
38753914
}
3876-
cfg.compiler(builder.cc(target));
38773915
}
3878-
cfg.cargo_metadata(false)
3879-
.out_dir(&dst)
3880-
.target(&target.triple)
3881-
.host(&builder.config.host_target.triple)
3882-
.opt_level(0)
3883-
.warnings(false)
3884-
.debug(false)
3885-
.file(builder.src.join("tests/auxiliary/rust_test_helpers.c"))
3886-
.compile("rust_test_helpers");
38873916
}
38883917
}
38893918

src/bootstrap/src/core/config/target_selection.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ impl TargetSelection {
7878
self.contains("msvc")
7979
}
8080

81+
pub fn is_pauthtest(&self) -> bool {
82+
self.triple == "aarch64-unknown-linux-pauthtest"
83+
}
84+
8185
pub fn is_windows(&self) -> bool {
8286
self.contains("windows")
8387
}

src/bootstrap/src/core/sanity.rs

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use crate::builder::Kind;
2121
use crate::core::build_steps::tool;
2222
use crate::core::config::{CompilerBuiltins, Target};
2323
use crate::utils::exec::command;
24-
use crate::{Build, Subcommand};
24+
use crate::{Build, Subcommand, t};
2525

2626
pub struct Finder {
2727
cache: HashMap<OsString, Option<PathBuf>>,
@@ -37,7 +37,7 @@ pub struct Finder {
3737
/// when the newly-bumped stage 0 compiler now knows about the formerly-missing targets.
3838
const STAGE0_MISSING_TARGETS: &[&str] = &[
3939
// just a dummy comment so the list doesn't get onelined
40-
"aarch64-unknown-linux-pauthtest", // Stage 0 compiler is not guaranteed to see pauthtest yet.
40+
"aarch64-unknown-linux-pauthtest", // Stage 0 compiler is not guaranteed to see the target yet.
4141
];
4242

4343
/// Minimum version threshold for libstdc++ required when using prebuilt LLVM
@@ -412,6 +412,53 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
412412
{
413413
cmd_finder.must_have("wasm-component-ld");
414414
}
415+
416+
// aarch64-unknown-linux-pauthtest must use clang
417+
if !skip_tools_checks && target.is_pauthtest() {
418+
let cc_tool = build.cc_tool(*target);
419+
let linker_path = build
420+
.linker(*target)
421+
.unwrap_or_else(|| panic!("{} requires an explicit clang linker", target.triple));
422+
423+
if !cc_tool.is_like_clang() {
424+
panic!(
425+
"Clang is required to build C code for {} target, got:\n\
426+
cc tool: `{}`,\n\
427+
linker: `{}`\n",
428+
target.triple,
429+
cc_tool.path().display(),
430+
linker_path.display(),
431+
);
432+
}
433+
let cc_canon = t!(fs::canonicalize(cc_tool.path()));
434+
let linker_canon = t!(fs::canonicalize(&linker_path));
435+
if cc_canon != linker_canon {
436+
panic!(
437+
"CC and Linker are expected to be the same for {} target, got:\n\
438+
CC: `{}`,\n\
439+
Linker: `{}`\n",
440+
target.triple,
441+
cc_canon.display(),
442+
linker_canon.display(),
443+
);
444+
}
445+
446+
let output =
447+
command(cc_tool.path()).arg("-dumpversion").run_capture_stdout(&build).stdout();
448+
let version_str = output.trim();
449+
let mut parts = version_str.split('.').map(|s| s.parse::<u32>().unwrap_or(0));
450+
let major = parts.next().unwrap_or(0);
451+
let minor = parts.next().unwrap_or(0);
452+
let patch = parts.next().unwrap_or(0);
453+
if (major, minor, patch) < (22, 1, 0) {
454+
panic!(
455+
"clang version too old: {} ({} target trequires >= 22.1.0), path: {}",
456+
target.triple,
457+
version_str,
458+
cc_tool.path().display()
459+
);
460+
}
461+
}
415462
}
416463

417464
if let Some(ref s) = build.config.ccache {

tests/assembly-llvm/asm/aarch64-outline-atomics.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
//@ compile-flags: -Copt-level=3
33
//@ only-aarch64
44
//@ only-linux
5+
// aarch64-unknown-linux-pauthtest requires armv8.3-a, which includes Large System Extensions,
6+
// providing hardware implementations of atomic operations.
7+
//@ ignore-aarch64-unknown-linux-pauthtest
58

69
#![crate_type = "rlib"]
710

tests/codegen-llvm/box-uninit-bytes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,4 @@ pub fn box_lotsa_padding() -> Box<LotsaPadding> {
4343
// from the CHECK-NOT above, and also verify the attributes got set reasonably.
4444
// CHECK: declare {{(dso_local )?}}noalias noundef ptr @{{.*}}__rust_alloc(i{{[0-9]+}} noundef, i{{[0-9]+}} allocalign noundef range(i{{[0-9]+}} 1, {{-2147483647|-9223372036854775807}})) unnamed_addr [[RUST_ALLOC_ATTRS:#[0-9]+]]
4545

46-
// CHECK-DAG: attributes [[RUST_ALLOC_ATTRS]] = { {{.*}} allockind("alloc,uninitialized,aligned") allocsize(0) {{(uwtable )?}}"alloc-family"="__rust_alloc" {{.*}} }
46+
// CHECK-DAG: attributes [[RUST_ALLOC_ATTRS]] = { {{.*}} allockind("alloc,uninitialized,aligned"){{.*}} allocsize(0) {{(uwtable )?}}{{.*}}"alloc-family"="__rust_alloc" {{.*}} }

tests/codegen-llvm/cffi/c-variadic.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
//@ needs-unwind
22
//@ compile-flags: -C no-prepopulate-passes -Copt-level=0
3+
// Pauthtest generates pointer authentication metadata for call instructions
4+
// and wraps function pointers in ConstPtrAuth. Disable this test for this target
5+
// to avoid clutter from pointer authentication complexity.
6+
//@ ignore-aarch64-unknown-linux-pauthtest
37

48
#![crate_type = "lib"]
59
#![feature(c_variadic)]

tests/codegen-llvm/inline-always-works-always.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
//@[NO-OPT] compile-flags: -Copt-level=0
33
//@[SIZE-OPT] compile-flags: -Copt-level=s
44
//@[SPEED-OPT] compile-flags: -Copt-level=3
5+
// Pointer authenticated calls are not guaranteed to be inlined.
6+
//@ ignore-aarch64-unknown-linux-pauthtest
57

68
#![crate_type = "rlib"]
79

tests/codegen-llvm/issues/issue-73258.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#![crate_type = "lib"]
44

55
// Adapted from <https://github.com/rust-lang/rust/issues/73258#issue-637346014>
6+
// We explicitly match against `call{{.*}}(` because the aarch64-unknown-linux-pauthtest target
7+
// emits `ptrauth-calls` attribute, which would otherwise make a plain `call` match ambiguous.
68

79
#[derive(Clone, Copy)]
810
#[repr(u8)]
@@ -17,22 +19,22 @@ pub enum Foo {
1719
#[no_mangle]
1820
pub unsafe fn issue_73258(ptr: *const Foo) -> Foo {
1921
// CHECK-NOT: icmp
20-
// CHECK-NOT: call
22+
// CHECK-NOT: call{{.*}}(
2123
// CHECK-NOT: br {{.*}}
2224
// CHECK-NOT: select
2325

2426
// CHECK: %[[R:.+]] = load i8
2527
// CHECK-SAME: !range !
2628

2729
// CHECK-NOT: icmp
28-
// CHECK-NOT: call
30+
// CHECK-NOT: call{{.*}}(
2931
// CHECK-NOT: br {{.*}}
3032
// CHECK-NOT: select
3133

3234
// CHECK: ret i8 %[[R]]
3335

3436
// CHECK-NOT: icmp
35-
// CHECK-NOT: call
37+
// CHECK-NOT: call{{.*}}(
3638
// CHECK-NOT: br {{.*}}
3739
// CHECK-NOT: select
3840
let k: Option<Foo> = Some(ptr.read());

tests/incremental/auxiliary/issue-54059.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ proc_macro_expr_impl! {
4040
}
4141
}
4242

43-
#[link(name="rust_test_helpers")]
43+
#[cfg_attr(target_env = "pauthtest", link(name = "rust_test_helpers", kind = "dylib"))]
44+
#[cfg_attr(not(target_env = "pauthtest"), link(name = "rust_test_helpers"))]
4445
extern "C" {
4546
pub fn rust_dbg_extern_identity_u64(v: u64) -> u64;
4647
}

tests/run-make/c-link-to-rust-va-list-fn/rmake.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
//@ needs-target-std
77
//@ ignore-android: FIXME(#142855)
88
//@ ignore-sgx: (x86 machine code cannot be directly executed)
9+
//@ ignore-aarch64-unknown-linux-pauthtest: (it requires non-trivial compilation of c sources,
10+
// and only supports dynamic linking, ignore the test).
911

1012
use run_make_support::{cc, extra_c_flags, run, rustc, static_lib_name};
1113

0 commit comments

Comments
 (0)