1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
/// Generate rust constants for linux riscv syscall numbers.
///
/// Syscall numbers are parsed from the `linux/unistd.h` header.
/// This script uses the `riscv64-linux-gnu-*` tools to find to header, make sure those tools are
/// in the PATH.
///
/// For simplicity, this script unwraps any Option/Result because we want to fail in case of any
/// error.
fn main() {
// Get sysroot to find header location.
let out = std::process::Command::new("riscv64-linux-gnu-gcc")
.arg("-print-sysroot")
.output()
.unwrap();
let sysroot = std::str::from_utf8(&out.stdout).unwrap();
let header = format!("{}/include/linux/unistd.h", sysroot.trim_end());
// The header should "basically" never change.
println!("cargo:rerun-if-changed={}", header);
// Run header through preprocessor and dump macro definitions.
let out = std::process::Command::new("riscv64-linux-gnu-cpp")
.arg("-dM")
.arg(header)
.output()
.unwrap();
let defines = std::str::from_utf8(&out.stdout).unwrap();
let mut output = String::with_capacity(256);
// Parse out lines of the format
// #define __NR_<syscall> <nr>
// and generate output strings.
for line in defines.lines() {
let line = match line.strip_prefix("#define __NR_") {
Some(line) => line,
None => continue,
};
let (sys, nr) = match line.split_once(' ') {
Some(split) => split,
None => continue,
};
let nr = match nr.parse::<usize>() {
Ok(nr) => nr,
Err(_) => continue,
};
output.push_str(&format!(
"#[allow(unused)] const SYS_{}: usize = {};\n",
sys.to_uppercase(),
nr
));
}
// Write out rust file with syscall numbers.
let outfile = format!("{}/syscalls.rs", std::env::var("OUT_DIR").unwrap());
std::fs::write(outfile, output).unwrap();
}
|