From 084c79ee7c1e65bf3cfe5e527b9f978f219252d3 Mon Sep 17 00:00:00 2001 From: tamnd <1218621+tamnd@users.noreply.github.com> Date: Sat, 3 Oct 2026 19:52:27 +0700 Subject: [PATCH] Record the sanitizer probes as expected and key objtool objects by relative path --- config-divergences.toml | 16 ++++++++++++++++ crates/rk/src/flags.rs | 25 ++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/config-divergences.toml b/config-divergences.toml index e2ca78d..6e3c7cf 100644 --- a/config-divergences.toml +++ b/config-divergences.toml @@ -11,3 +11,19 @@ [[divergence]] symbol = "CC_VERSION_TEXT" reason = "the first line of --version, which names the compiler and so always differs" + +[[divergence]] +symbol = "CC_HAS_KASAN_*" +reason = "rucc has no -fsanitize=kernel-address or kernel-hwaddress, and plan section 8.10 keeps the sanitizers out of the grade, with KASAN off in both builds" + +[[divergence]] +symbol = "KASAN" +reason = "only visible when the compiler can build it, see CC_HAS_KASAN_*" + +[[divergence]] +symbol = "HAVE_KCSAN_COMPILER" +reason = "rucc has no -fsanitize=thread, and plan section 8.10 keeps the sanitizers out of the grade, with KCSAN off in both builds" + +[[divergence]] +symbol = "KCSAN" +reason = "only visible when the compiler can build it, see HAVE_KCSAN_COMPILER" diff --git a/crates/rk/src/flags.rs b/crates/rk/src/flags.rs index ba845b1..ae78cb6 100644 --- a/crates/rk/src/flags.rs +++ b/crates/rk/src/flags.rs @@ -76,7 +76,7 @@ pub fn load(out: &Path) -> Result { continue; }; if let Some((object, words)) = parse_cmd(&text) { - commands.insert(object, words); + commands.insert(relative(&object, out), words); } } } @@ -84,6 +84,15 @@ pub fn load(out: &Path) -> Result { Ok(commands) } +/// An object's name relative to the output directory. objtool is built by its own makefile, which +/// names its objects by their full path, so without this every one of them is in one build only. +fn relative(object: &str, out: &Path) -> String { + Path::new(object).strip_prefix(out).map_or_else( + |_| object.to_string(), + |rest| rest.to_string_lossy().into_owned(), + ) +} + /// A command made comparable: `CC` for the compiler, no persona, no output or dependency file, /// and `OUT` and `SRC` for the directories named in `dirs`, longest first. #[must_use] @@ -289,6 +298,20 @@ mod tests { c } + #[test] + fn an_object_named_by_its_full_path_is_keyed_like_the_rest() { + let out = Path::new("/w/out/def-gcc"); + assert_eq!( + relative("/w/out/def-gcc/tools/objtool/elf.o", out), + "tools/objtool/elf.o" + ); + assert_eq!(relative("kernel/fork.o", out), "kernel/fork.o"); + assert_eq!( + relative("/w/out/def-rucc/elf.o", out), + "/w/out/def-rucc/elf.o" + ); + } + #[test] fn a_cmd_file_gives_the_compile_command_without_what_follows() { let (object, words) = parse_cmd(GCC).unwrap();