~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/generate_rust_target.rs

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /scripts/generate_rust_target.rs (Version linux-6.12-rc7) and /scripts/generate_rust_target.rs (Version linux-6.8.12)


  1 // SPDX-License-Identifier: GPL-2.0                 1 // SPDX-License-Identifier: GPL-2.0
  2                                                     2 
  3 //! The custom target specification file gener      3 //! The custom target specification file generator for `rustc`.
  4 //!                                                 4 //!
  5 //! To configure a target from scratch, a JSON      5 //! To configure a target from scratch, a JSON-encoded file has to be passed
  6 //! to `rustc` (introduced in [RFC 131]). Thes      6 //! to `rustc` (introduced in [RFC 131]). These options and the file itself are
  7 //! unstable. Eventually, `rustc` should provi      7 //! unstable. Eventually, `rustc` should provide a way to do this in a stable
  8 //! manner. For instance, via command-line arg      8 //! manner. For instance, via command-line arguments. Therefore, this file
  9 //! should avoid using keys which can be set v      9 //! should avoid using keys which can be set via `-C` or `-Z` options.
 10 //!                                                10 //!
 11 //! [RFC 131]: https://rust-lang.github.io/rfc     11 //! [RFC 131]: https://rust-lang.github.io/rfcs/0131-target-specification.html
 12                                                    12 
 13 use std::{                                         13 use std::{
 14     collections::HashMap,                          14     collections::HashMap,
 15     fmt::{Display, Formatter, Result},             15     fmt::{Display, Formatter, Result},
 16     io::BufRead,                                   16     io::BufRead,
 17 };                                                 17 };
 18                                                    18 
 19 enum Value {                                       19 enum Value {
 20     Boolean(bool),                                 20     Boolean(bool),
 21     Number(i32),                                   21     Number(i32),
 22     String(String),                                22     String(String),
 23     Array(Vec<Value>),                         << 
 24     Object(Object),                                23     Object(Object),
 25 }                                                  24 }
 26                                                    25 
 27 type Object = Vec<(String, Value)>;                26 type Object = Vec<(String, Value)>;
 28                                                    27 
 29 fn comma_sep<T>(                               !!  28 /// Minimal "almost JSON" generator (e.g. no `null`s, no arrays, no escaping),
 30     seq: &[T],                                 << 
 31     formatter: &mut Formatter<'_>,             << 
 32     f: impl Fn(&mut Formatter<'_>, &T) -> Resu << 
 33 ) -> Result {                                  << 
 34     if let [ref rest @ .., ref last] = seq[..] << 
 35         for v in rest {                        << 
 36             f(formatter, v)?;                  << 
 37             formatter.write_str(",")?;         << 
 38         }                                      << 
 39         f(formatter, last)?;                   << 
 40     }                                          << 
 41     Ok(())                                     << 
 42 }                                              << 
 43                                                << 
 44 /// Minimal "almost JSON" generator (e.g. no ` << 
 45 /// enough for this purpose.                       29 /// enough for this purpose.
 46 impl Display for Value {                           30 impl Display for Value {
 47     fn fmt(&self, formatter: &mut Formatter<'_     31     fn fmt(&self, formatter: &mut Formatter<'_>) -> Result {
 48         match self {                               32         match self {
 49             Value::Boolean(boolean) => write!(     33             Value::Boolean(boolean) => write!(formatter, "{}", boolean),
 50             Value::Number(number) => write!(fo     34             Value::Number(number) => write!(formatter, "{}", number),
 51             Value::String(string) => write!(fo     35             Value::String(string) => write!(formatter, "\"{}\"", string),
 52             Value::Array(values) => {          << 
 53                 formatter.write_str("[")?;     << 
 54                 comma_sep(&values[..], formatt << 
 55                 formatter.write_str("]")       << 
 56             }                                  << 
 57             Value::Object(object) => {             36             Value::Object(object) => {
 58                 formatter.write_str("{")?;         37                 formatter.write_str("{")?;
 59                 comma_sep(&object[..], formatt !!  38                 if let [ref rest @ .., ref last] = object[..] {
 60                     write!(formatter, "\"{}\": !!  39                     for (key, value) in rest {
 61                 })?;                           !!  40                         write!(formatter, "\"{}\": {},", key, value)?;
                                                   >>  41                     }
                                                   >>  42                     write!(formatter, "\"{}\": {}", last.0, last.1)?;
                                                   >>  43                 }
 62                 formatter.write_str("}")           44                 formatter.write_str("}")
 63             }                                      45             }
 64         }                                          46         }
 65     }                                              47     }
 66 }                                                  48 }
 67                                                    49 
 68 impl From<bool> for Value {                    !!  50 struct TargetSpec(Object);
 69     fn from(value: bool) -> Self {             << 
 70         Self::Boolean(value)                   << 
 71     }                                          << 
 72 }                                              << 
 73                                                    51 
 74 impl From<i32> for Value {                     !!  52 impl TargetSpec {
 75     fn from(value: i32) -> Self {              !!  53     fn new() -> TargetSpec {
 76         Self::Number(value)                    !!  54         TargetSpec(Vec::new())
 77     }                                              55     }
 78 }                                                  56 }
 79                                                    57 
 80 impl From<String> for Value {                  !!  58 trait Push<T> {
 81     fn from(value: String) -> Self {           !!  59     fn push(&mut self, key: &str, value: T);
 82         Self::String(value)                    << 
 83     }                                          << 
 84 }                                                  60 }
 85                                                    61 
 86 impl From<&str> for Value {                    !!  62 impl Push<bool> for TargetSpec {
 87     fn from(value: &str) -> Self {             !!  63     fn push(&mut self, key: &str, value: bool) {
 88         Self::String(value.to_string())        !!  64         self.0.push((key.to_string(), Value::Boolean(value)));
 89     }                                              65     }
 90 }                                                  66 }
 91                                                    67 
 92 impl From<Object> for Value {                  !!  68 impl Push<i32> for TargetSpec {
 93     fn from(object: Object) -> Self {          !!  69     fn push(&mut self, key: &str, value: i32) {
 94         Self::Object(object)                   !!  70         self.0.push((key.to_string(), Value::Number(value)));
 95     }                                              71     }
 96 }                                                  72 }
 97                                                    73 
 98 impl<T: Into<Value>, const N: usize> From<[T;  !!  74 impl Push<String> for TargetSpec {
 99     fn from(i: [T; N]) -> Self {               !!  75     fn push(&mut self, key: &str, value: String) {
100         Self::Array(i.into_iter().map(|v| v.in !!  76         self.0.push((key.to_string(), Value::String(value)));
101     }                                              77     }
102 }                                                  78 }
103                                                    79 
104 struct TargetSpec(Object);                     !!  80 impl Push<&str> for TargetSpec {
105                                                !!  81     fn push(&mut self, key: &str, value: &str) {
106 impl TargetSpec {                              !!  82         self.push(key, value.to_string());
107     fn new() -> TargetSpec {                   << 
108         TargetSpec(Vec::new())                 << 
109     }                                              83     }
                                                   >>  84 }
110                                                    85 
111     fn push(&mut self, key: &str, value: impl  !!  86 impl Push<Object> for TargetSpec {
112         self.0.push((key.to_string(), value.in !!  87     fn push(&mut self, key: &str, value: Object) {
                                                   >>  88         self.0.push((key.to_string(), Value::Object(value)));
113     }                                              89     }
114 }                                                  90 }
115                                                    91 
116 impl Display for TargetSpec {                      92 impl Display for TargetSpec {
117     fn fmt(&self, formatter: &mut Formatter<'_     93     fn fmt(&self, formatter: &mut Formatter<'_>) -> Result {
118         // We add some newlines for clarity.       94         // We add some newlines for clarity.
119         formatter.write_str("{\n")?;               95         formatter.write_str("{\n")?;
120         if let [ref rest @ .., ref last] = sel     96         if let [ref rest @ .., ref last] = self.0[..] {
121             for (key, value) in rest {             97             for (key, value) in rest {
122                 write!(formatter, "    \"{}\":     98                 write!(formatter, "    \"{}\": {},\n", key, value)?;
123             }                                      99             }
124             write!(formatter, "    \"{}\": {}\    100             write!(formatter, "    \"{}\": {}\n", last.0, last.1)?;
125         }                                         101         }
126         formatter.write_str("}")                  102         formatter.write_str("}")
127     }                                             103     }
128 }                                                 104 }
129                                                   105 
130 struct KernelConfig(HashMap<String, String>);     106 struct KernelConfig(HashMap<String, String>);
131                                                   107 
132 impl KernelConfig {                               108 impl KernelConfig {
133     /// Parses `include/config/auto.conf` from    109     /// Parses `include/config/auto.conf` from `stdin`.
134     fn from_stdin() -> KernelConfig {             110     fn from_stdin() -> KernelConfig {
135         let mut result = HashMap::new();          111         let mut result = HashMap::new();
136                                                   112 
137         let stdin = std::io::stdin();             113         let stdin = std::io::stdin();
138         let mut handle = stdin.lock();            114         let mut handle = stdin.lock();
139         let mut line = String::new();             115         let mut line = String::new();
140                                                   116 
141         loop {                                    117         loop {
142             line.clear();                         118             line.clear();
143                                                   119 
144             if handle.read_line(&mut line).unw    120             if handle.read_line(&mut line).unwrap() == 0 {
145                 break;                            121                 break;
146             }                                     122             }
147                                                   123 
148             if line.starts_with('#') {            124             if line.starts_with('#') {
149                 continue;                         125                 continue;
150             }                                     126             }
151                                                   127 
152             let (key, value) = line.split_once    128             let (key, value) = line.split_once('=').expect("Missing `=` in line.");
153             result.insert(key.to_string(), val    129             result.insert(key.to_string(), value.trim_end_matches('\n').to_string());
154         }                                         130         }
155                                                   131 
156         KernelConfig(result)                      132         KernelConfig(result)
157     }                                             133     }
158                                                   134 
159     /// Does the option exist in the configura    135     /// Does the option exist in the configuration (any value)?
160     ///                                           136     ///
161     /// The argument must be passed without th    137     /// The argument must be passed without the `CONFIG_` prefix.
162     /// This avoids repetition and it also avo    138     /// This avoids repetition and it also avoids `fixdep` making us
163     /// depend on it.                             139     /// depend on it.
164     fn has(&self, option: &str) -> bool {         140     fn has(&self, option: &str) -> bool {
165         let option = "CONFIG_".to_owned() + op    141         let option = "CONFIG_".to_owned() + option;
166         self.0.contains_key(&option)              142         self.0.contains_key(&option)
167     }                                             143     }
168 }                                                 144 }
169                                                   145 
170 fn main() {                                       146 fn main() {
171     let cfg = KernelConfig::from_stdin();         147     let cfg = KernelConfig::from_stdin();
172     let mut ts = TargetSpec::new();               148     let mut ts = TargetSpec::new();
173                                                   149 
174     // `llvm-target`s are taken from `scripts/    150     // `llvm-target`s are taken from `scripts/Makefile.clang`.
175     if cfg.has("ARM64") {                      !! 151     if cfg.has("X86_64") {
176         panic!("arm64 uses the builtin rustc a << 
177     } else if cfg.has("RISCV") {               << 
178         if cfg.has("64BIT") {                  << 
179             panic!("64-bit RISC-V uses the bui << 
180         } else {                               << 
181             panic!("32-bit RISC-V is an unsupp << 
182         }                                      << 
183     } else if cfg.has("X86_64") {              << 
184         ts.push("arch", "x86_64");                152         ts.push("arch", "x86_64");
185         ts.push(                                  153         ts.push(
186             "data-layout",                        154             "data-layout",
187             "e-m:e-p270:32:32-p271:32:32-p272: !! 155             "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
188         );                                        156         );
189         let mut features = "-mmx,+soft-float". !! 157         let mut features = "-3dnow,-3dnowa,-mmx,+soft-float".to_string();
190         if cfg.has("MITIGATION_RETPOLINE") {   !! 158         if cfg.has("RETPOLINE") {
191             // The kernel uses `-mretpoline-ex << 
192             // target feature of the same name << 
193             // `clang/lib/Driver/ToolChains/Ar << 
194             // `-Ctarget-feature` when `rustc` << 
195             // flag); see https://github.com/r << 
196             features += ",+retpoline-external-    159             features += ",+retpoline-external-thunk";
197             features += ",+retpoline-indirect- << 
198             features += ",+retpoline-indirect- << 
199         }                                      << 
200         if cfg.has("MITIGATION_SLS") {         << 
201             // The kernel uses `-mharden-sls=a << 
202             // `clang/lib/Driver/ToolChains/Ar << 
203             // `-Ctarget-feature` when `rustc` << 
204             // flag); see https://github.com/r << 
205             features += ",+harden-sls-ijmp";   << 
206             features += ",+harden-sls-ret";    << 
207         }                                         160         }
208         ts.push("features", features);            161         ts.push("features", features);
209         ts.push("llvm-target", "x86_64-linux-g    162         ts.push("llvm-target", "x86_64-linux-gnu");
210         ts.push("supported-sanitizers", ["kcfi << 
211         ts.push("target-pointer-width", "64");    163         ts.push("target-pointer-width", "64");
212     } else if cfg.has("X86_32") {              << 
213         // This only works on UML, as i386 oth << 
214         if !cfg.has("UML") {                   << 
215             panic!("32-bit x86 only works unde << 
216         }                                      << 
217         ts.push("arch", "x86");                << 
218         ts.push(                               << 
219             "data-layout",                     << 
220             "e-m:e-p:32:32-p270:32:32-p271:32: << 
221         );                                     << 
222         let mut features = "-mmx,+soft-float". << 
223         if cfg.has("MITIGATION_RETPOLINE") {   << 
224             features += ",+retpoline-external- << 
225         }                                      << 
226         ts.push("features", features);         << 
227         ts.push("llvm-target", "i386-unknown-l << 
228         ts.push("target-pointer-width", "32"); << 
229     } else if cfg.has("LOONGARCH") {              164     } else if cfg.has("LOONGARCH") {
230         panic!("loongarch uses the builtin rus !! 165         ts.push("arch", "loongarch64");
                                                   >> 166         ts.push("data-layout", "e-m:e-p:64:64-i64:64-i128:128-n64-S128");
                                                   >> 167         ts.push("features", "-f,-d");
                                                   >> 168         ts.push("llvm-target", "loongarch64-linux-gnusf");
                                                   >> 169         ts.push("llvm-abiname", "lp64s");
                                                   >> 170         ts.push("target-pointer-width", "64");
231     } else {                                      171     } else {
232         panic!("Unsupported architecture");       172         panic!("Unsupported architecture");
233     }                                             173     }
234                                                   174 
235     ts.push("emit-debug-gdb-scripts", false);     175     ts.push("emit-debug-gdb-scripts", false);
236     ts.push("frame-pointer", "may-omit");         176     ts.push("frame-pointer", "may-omit");
237     ts.push(                                      177     ts.push(
238         "stack-probes",                           178         "stack-probes",
239         vec![("kind".to_string(), Value::Strin    179         vec![("kind".to_string(), Value::String("none".to_string()))],
240     );                                            180     );
241                                                   181 
242     // Everything else is LE, whether `CPU_LIT    182     // Everything else is LE, whether `CPU_LITTLE_ENDIAN` is declared or not
243     // (e.g. x86). It is also `rustc`'s defaul    183     // (e.g. x86). It is also `rustc`'s default.
244     if cfg.has("CPU_BIG_ENDIAN") {                184     if cfg.has("CPU_BIG_ENDIAN") {
245         ts.push("target-endian", "big");          185         ts.push("target-endian", "big");
246     }                                             186     }
247                                                   187 
248     println!("{}", ts);                           188     println!("{}", ts);
249 }                                                 189 }
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php