Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The goal is simple to state and slow to reach: every Linux release, from the mus

## Rows

A row is an architecture with a QEMU machine and a reference toolchain. X64 is x86-64 and comes first. A64 is arm64. X32 is i686, which the x86-64 kernel needs anyway for its real mode setup code and its 32-bit vDSO. R64 is riscv64 and waits for rucc to have a RISC-V back end.
A row is an architecture with a QEMU machine and a reference toolchain. X64 is x86-64 and comes first. A64 is arm64. X32 is i686, which the x86-64 kernel needs anyway for its real mode setup code and its 32-bit vDSO. R64 is riscv64, where 7.2.8 built by rucc boots and passes the same smoke and KUnit tests as gcc.

## Milestones

Expand Down
40 changes: 40 additions & 0 deletions config-divergences.toml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,46 @@ reason = "The same as CC_CAN_LINK, one level stricter. On X32 in 6.1 Kconfig ask
symbol = "GCC_ASM_GOTO_OUTPUT_WORKAROUND"
reason = "This follows GCC_VERSION. In 6.1 it is y for gcc 12.0 to 12.3, which have bug 113921 in asm goto with outputs, and it adds an empty asm volatile after each asm goto. rucc claims 12.2.0 for 6.1 and gets it. The CI reference gcc-12 got it at 12.3.0 and does not at 12.4.0, and a reference gcc-13 at 13.3, as on server2, has the fix and does not either. The extra empty asm emits no code"

[[divergence]]
symbol = "CC_HAS_MIN_FUNCTION_ALIGNMENT"
reason = "-fmin-function-alignment came in gcc 14. The persona is gcc 14.2 and rucc takes the flag and honors it, while the riscv64 reference is Ubuntu 24.04's gcc 13.3, which does not know it. The kernel only uses it to align functions, and on riscv64 it decides whether dynamic ftrace can be offered, see GCC_SUPPORTS_DYNAMIC_FTRACE"

[[divergence]]
symbol = "CC_HAS_SANE_FUNCTION_ALIGNMENT"
reason = "follows CC_HAS_MIN_FUNCTION_ALIGNMENT, see there"

[[divergence]]
symbol = "GCC_SUPPORTS_DYNAMIC_FTRACE"
reason = "on riscv64 with compressed instructions this needs -fmin-function-alignment, which gcc 13.3 lacks, see CC_HAS_MIN_FUNCTION_ALIGNMENT. rucc also takes -fpatchable-function-entry"

[[divergence]]
symbol = "HAVE_DYNAMIC_FTRACE*"
reason = "selected by RISCV when GCC_SUPPORTS_DYNAMIC_FTRACE is set, see there"

[[divergence]]
symbol = "HAVE_FUNCTION_TRACER"
reason = "selected by RISCV with dynamic ftrace, see GCC_SUPPORTS_DYNAMIC_FTRACE"

[[divergence]]
symbol = "HAVE_FUNCTION_GRAPH_TRACER"
reason = "selected by RISCV with dynamic ftrace, see GCC_SUPPORTS_DYNAMIC_FTRACE"

[[divergence]]
symbol = "FUNCTION_TRACER"
reason = "only visible with HAVE_FUNCTION_TRACER, see GCC_SUPPORTS_DYNAMIC_FTRACE. It is off in the rucc build, so no unit is built differently"

[[divergence]]
symbol = "STACK_TRACER"
reason = "only visible with HAVE_FUNCTION_TRACER, see GCC_SUPPORTS_DYNAMIC_FTRACE. It is off in the rucc build"

[[divergence]]
symbol = "TOOLCHAIN_HAS_ZA*"
reason = "The riscv64 reference is Ubuntu 24.04's gcc 13.3, which refuses Zacas and Zabha in -march. rucc takes them and assembles amocas and the byte and halfword AMOs, checked against llvm-mc"

[[divergence]]
symbol = "RISCV_ISA_ZABHA"
reason = "follows TOOLCHAIN_HAS_ZABHA, see TOOLCHAIN_HAS_ZA*. The kernel picks the Zabha code at boot through alternatives, so a machine without it runs the same code as the gcc build"

[[flags]]
flag = "/home/runner/.cache/rucc/include/*"
reason = "the -isystem the kernel takes from $(CC) -print-file-name=include for the units that use the NEON intrinsics, which is where each compiler keeps its own arm_neon.h"
Expand Down
10 changes: 6 additions & 4 deletions crates/rk-shim/src/bringup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,16 @@ const NEWER_THAN_BRINGUP: &[&str] = &["-fzero-init-padding-bits="];

/// The arguments a call hands to its compiler.
///
/// rk puts the era's persona in `CC` as `-fgnuc-version=` and `-fgnu-as-version=`, which only rucc
/// knows. GCC refuses
/// it, so a delegated call leaves it out, along with the flags in [`NEWER_THAN_BRINGUP`]. Every
/// other argument goes through as kbuild wrote it.
/// rk puts the era's persona in `CC` as `-fgnuc-version=` and `-fgnu-as-version=`, and on a cross
/// row `--target=`, which only rucc knows. GCC refuses it, so a delegated call leaves it out,
/// along with the flags in [`NEWER_THAN_BRINGUP`]. Every other argument goes through as kbuild
/// wrote it.
#[must_use]
pub fn passed_on(args: &[String], delegated: bool) -> Vec<String> {
let refused = |a: &str| {
a.starts_with("-fgnuc-version=")
|| a.starts_with("-fgnu-as-version=")
|| a.starts_with("--target=")
|| NEWER_THAN_BRINGUP.iter().any(|f| a.starts_with(f))
};
args.iter()
Expand Down Expand Up @@ -183,6 +184,7 @@ mod tests {
let args: Vec<String> = [
"-fgnuc-version=14.2.0",
"-fgnu-as-version=2.44",
"--target=riscv64-linux-gnu",
"-m16",
"-c",
"-o",
Expand Down
7 changes: 6 additions & 1 deletion crates/rk/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,14 +544,19 @@ pub fn run(plan: &Plan) -> Result<Outcome, String> {
std::fs::write(bin.join(rk_shim::config::FILE_NAME), config.to_toml())
.map_err(|e| format!("writing the shim's settings: {e}"))?;

let persona = if plan.compiler.rucc {
let mut persona = if plan.compiler.rucc {
vec![
format!("-fgnuc-version={}", plan.era.gnuc),
format!("-fgnu-as-version={}", plan.era.gnu_as),
]
} else {
Vec::new()
};
// rucc takes its target from the name it is run as, and the shim runs it by its real path,
// so on a cross row it is told the target the way clang is.
if plan.compiler.rucc && !plan.row.cross.is_empty() && !host_is(&plan.row.arch) {
persona.push(format!("--target={}", plan.row.cross.trim_end_matches('-')));
}
let cc = std::iter::once(shim.display().to_string())
.chain(persona.iter().cloned())
.collect::<Vec<_>>()
Expand Down
3 changes: 2 additions & 1 deletion crates/rk/src/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ pub fn normalize(words: &[String], dirs: &[(&str, &str)]) -> Vec<String> {
}
if word.starts_with("-fgnuc-version=")
|| word.starts_with("-fgnu-as-version=")
|| word.starts_with("--target=")
|| word.starts_with("-Wp,-MD,")
|| word.starts_with("-Wp,-MMD,")
|| matches!(word.as_str(), "-MD" | "-MMD")
Expand Down Expand Up @@ -286,7 +287,7 @@ mod tests {

const GCC: &str = "savedcmd_kernel/fork.o := /g/rk-bin/rk-cc -Wp,-MMD,kernel/.fork.o.d -nostdinc -I/src/linux/include -mno-red-zone -fno-PIE -DKBUILD_MODFILE='\"kernel/fork\"' -DKBUILD_BASENAME='\"fork\"' -c -o kernel/fork.o /src/linux/kernel/fork.c ; ./tools/objtool/objtool --hacks=jump_label kernel/fork.o\n\nsource_kernel/fork.o := /src/linux/kernel/fork.c\n";

const RUCC: &str = "savedcmd_kernel/fork.o := /r/rk-bin/rk-cc -fgnuc-version=14.2.0 -Wp,-MMD,kernel/.fork.o.d -nostdinc -I/src/linux/include -fno-PIE -DKBUILD_MODFILE='\"kernel/fork\"' -DKBUILD_BASENAME='\"fork\"' -c -o kernel/fork.o /src/linux/kernel/fork.c\n";
const RUCC: &str = "savedcmd_kernel/fork.o := /r/rk-bin/rk-cc -fgnuc-version=14.2.0 --target=x86_64-linux-gnu -Wp,-MMD,kernel/.fork.o.d -nostdinc -I/src/linux/include -fno-PIE -DKBUILD_MODFILE='\"kernel/fork\"' -DKBUILD_BASENAME='\"fork\"' -c -o kernel/fork.o /src/linux/kernel/fork.c\n";

fn commands(text: &str, out: &str) -> Commands {
let (object, words) = parse_cmd(text).unwrap();
Expand Down
9 changes: 5 additions & 4 deletions crates/rk/src/probes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ use rk_shim::record::CompileRecord;
use std::collections::BTreeMap;
use std::fmt::Write as _;

/// What a probe asks, as its arguments without the compiler, the persona, the output and the
/// names of temporary files, which change from run to run, followed by what it read on standard
/// input after `<<<`. Every `as-instr` probe has the same arguments and differs only there.
/// What a probe asks, as its arguments without the compiler, the persona (with the `--target=` a
/// cross row gives rucc), the output and the names of temporary files, which change from run to
/// run, followed by what it read on standard input after `<<<`. Every `as-instr` probe has the same arguments and differs only there.
#[must_use]
pub fn question(record: &CompileRecord) -> String {
let mut words = Vec::new();
Expand All @@ -28,6 +28,7 @@ pub fn question(record: &CompileRecord) -> String {
}
if arg.starts_with("-fgnuc-version=")
|| arg.starts_with("-fgnu-as-version=")
|| arg.starts_with("--target=")
|| (arg.starts_with("-o") && arg.len() > 2)
{
continue;
Expand Down Expand Up @@ -190,7 +191,7 @@ mod tests {
{"started":1,"argv":["/o/rk-bin/rk-cc","-c","-o","a.o","a.c"],"compiler":"/g","cwd":"/o","wall-seconds":0.1,"exit":0}
"#;

const RUCC: &str = r#"{"started":1,"argv":["/p/rk-bin/rk-cc","-fgnuc-version=14.2.0","-Werror","-mno-red-zone","-c","-x","c","/dev/null","-o",".tmp_40/tmp"],"compiler":"/r","cwd":"/p","wall-seconds":0.1,"exit":0,"probe":true}
const RUCC: &str = r#"{"started":1,"argv":["/p/rk-bin/rk-cc","-fgnuc-version=14.2.0","--target=x86_64-linux-gnu","-Werror","-mno-red-zone","-c","-x","c","/dev/null","-o",".tmp_40/tmp"],"compiler":"/r","cwd":"/p","wall-seconds":0.1,"exit":0,"probe":true}
{"started":1,"argv":["/p/rk-bin/rk-cc","-fgnuc-version=14.2.0","-Werror","-fcf-protection=branch","-c","-x","c","/dev/null","-o",".tmp_41/tmp"],"compiler":"/r","cwd":"/p","wall-seconds":0.1,"exit":1,"stderr":"rucc: error: unsupported option '-fcf-protection=branch'\n","probe":true}
"#;

Expand Down
2 changes: 1 addition & 1 deletion docs/plan/10-architectures.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ Rows: X32 boots `i386` defconfig (`ARCH=i386 defconfig` → `i386_defconfig`) un

## 10.4 R64: riscv64

Blocked on rucc's M9 (the RISC-V back end, parent issue #10). When it exists, kernel specifics:
rucc's RISC-V back end landed with M9, and 7.2.8 built by rucc boots on `virt` and passes the same boot, smoke and KUnit tests as gcc. Kernel specifics:

| Item | Detail |
|---|---|
Expand Down
2 changes: 1 addition & 1 deletion rows.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ machine = "pc"
cpu = "max"
console = "ttyS0"

# Waits for rucc's RISC-V back end (K7). Listed so the name is taken.
# rucc runs as itself and takes its target from --target=, which rk adds to the persona on this row.
[[row]]
name = "R64"
arch = "riscv"
Expand Down
Loading