diff options
Diffstat (limited to 'scripts/generate_rust_target.rs')
-rw-r--r-- | scripts/generate_rust_target.rs | 98 |
1 files changed, 69 insertions, 29 deletions
diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs index 404edf7587e0..0d00ac3723b5 100644 --- a/scripts/generate_rust_target.rs +++ b/scripts/generate_rust_target.rs @@ -20,12 +20,28 @@ enum Value { Boolean(bool), Number(i32), String(String), + Array(Vec<Value>), Object(Object), } type Object = Vec<(String, Value)>; -/// Minimal "almost JSON" generator (e.g. no `null`s, no arrays, no escaping), +fn comma_sep<T>( + seq: &[T], + formatter: &mut Formatter<'_>, + f: impl Fn(&mut Formatter<'_>, &T) -> Result, +) -> Result { + if let [ref rest @ .., ref last] = seq[..] { + for v in rest { + f(formatter, v)?; + formatter.write_str(",")?; + } + f(formatter, last)?; + } + Ok(()) +} + +/// Minimal "almost JSON" generator (e.g. no `null`s, no escaping), /// enough for this purpose. impl Display for Value { fn fmt(&self, formatter: &mut Formatter<'_>) -> Result { @@ -33,59 +49,67 @@ impl Display for Value { Value::Boolean(boolean) => write!(formatter, "{}", boolean), Value::Number(number) => write!(formatter, "{}", number), Value::String(string) => write!(formatter, "\"{}\"", string), + Value::Array(values) => { + formatter.write_str("[")?; + comma_sep(&values[..], formatter, |formatter, v| v.fmt(formatter))?; + formatter.write_str("]") + } Value::Object(object) => { formatter.write_str("{")?; - if let [ref rest @ .., ref last] = object[..] { - for (key, value) in rest { - write!(formatter, "\"{}\": {},", key, value)?; - } - write!(formatter, "\"{}\": {}", last.0, last.1)?; - } + comma_sep(&object[..], formatter, |formatter, v| { + write!(formatter, "\"{}\": {}", v.0, v.1) + })?; formatter.write_str("}") } } } } -struct TargetSpec(Object); - -impl TargetSpec { - fn new() -> TargetSpec { - TargetSpec(Vec::new()) +impl From<bool> for Value { + fn from(value: bool) -> Self { + Self::Boolean(value) } } -trait Push<T> { - fn push(&mut self, key: &str, value: T); +impl From<i32> for Value { + fn from(value: i32) -> Self { + Self::Number(value) + } } -impl Push<bool> for TargetSpec { - fn push(&mut self, key: &str, value: bool) { - self.0.push((key.to_string(), Value::Boolean(value))); +impl From<String> for Value { + fn from(value: String) -> Self { + Self::String(value) } } -impl Push<i32> for TargetSpec { - fn push(&mut self, key: &str, value: i32) { - self.0.push((key.to_string(), Value::Number(value))); +impl From<&str> for Value { + fn from(value: &str) -> Self { + Self::String(value.to_string()) } } -impl Push<String> for TargetSpec { - fn push(&mut self, key: &str, value: String) { - self.0.push((key.to_string(), Value::String(value))); +impl From<Object> for Value { + fn from(object: Object) -> Self { + Self::Object(object) } } -impl Push<&str> for TargetSpec { - fn push(&mut self, key: &str, value: &str) { - self.push(key, value.to_string()); +impl<T: Into<Value>, const N: usize> From<[T; N]> for Value { + fn from(i: [T; N]) -> Self { + Self::Array(i.into_iter().map(|v| v.into()).collect()) } } -impl Push<Object> for TargetSpec { - fn push(&mut self, key: &str, value: Object) { - self.0.push((key.to_string(), Value::Object(value))); +struct TargetSpec(Object); + +impl TargetSpec { + fn new() -> TargetSpec { + TargetSpec(Vec::new()) + } + + fn push(&mut self, key: &str, value: impl Into<Value>) { + self.0.push((key.to_string(), value.into())); } } @@ -164,10 +188,26 @@ fn main() { ); let mut features = "-mmx,+soft-float".to_string(); if cfg.has("MITIGATION_RETPOLINE") { + // The kernel uses `-mretpoline-external-thunk` (for Clang), which Clang maps to the + // target feature of the same name plus the other two target features in + // `clang/lib/Driver/ToolChains/Arch/X86.cpp`. These should be eventually enabled via + // `-Ctarget-feature` when `rustc` starts recognizing them (or via a new dedicated + // flag); see https://github.com/rust-lang/rust/issues/116852. features += ",+retpoline-external-thunk"; + features += ",+retpoline-indirect-branches"; + features += ",+retpoline-indirect-calls"; + } + if cfg.has("MITIGATION_SLS") { + // The kernel uses `-mharden-sls=all`, which Clang maps to both these target features in + // `clang/lib/Driver/ToolChains/Arch/X86.cpp`. These should be eventually enabled via + // `-Ctarget-feature` when `rustc` starts recognizing them (or via a new dedicated + // flag); see https://github.com/rust-lang/rust/issues/116851. + features += ",+harden-sls-ijmp"; + features += ",+harden-sls-ret"; } ts.push("features", features); ts.push("llvm-target", "x86_64-linux-gnu"); + ts.push("supported-sanitizers", ["kcfi", "kernel-address"]); ts.push("target-pointer-width", "64"); } else if cfg.has("X86_32") { // This only works on UML, as i386 otherwise needs regparm support in rustc |