Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
mariux64
/
linux
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
2
Pull requests
0
Actions
Projects
0
Wiki
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Wiki
Security
Insights
Files
284a3ac
Documentation
LICENSES
arch
block
certs
crypto
drivers
fs
include
init
io_uring
ipc
kernel
lib
mm
net
rust
samples
scripts
atomic
basic
clang-tools
coccinelle
dtc
dummy-tools
gcc-plugins
gdb
genksyms
include
kconfig
ksymoops
mod
package
selinux
tracing
.gitignore
Kbuild.include
Kconfig.include
Lindent
Makefile
Makefile.asm-headers
Makefile.btf
Makefile.build
Makefile.clang
Makefile.clean
Makefile.compiler
Makefile.debug
Makefile.defconf
Makefile.dtbinst
Makefile.extrawarn
Makefile.gcc-plugins
Makefile.headersinst
Makefile.host
Makefile.kasan
Makefile.kcov
Makefile.kcsan
Makefile.kmsan
Makefile.lib
Makefile.modfinal
Makefile.modinst
Makefile.modpost
Makefile.package
Makefile.randstruct
Makefile.ubsan
Makefile.userprogs
Makefile.vdsoinst
Makefile.vmlinux
Makefile.vmlinux_o
as-version.sh
asn1_compiler.c
bloat-o-meter
bootgraph.pl
bpf_doc.py
build-version
cc-can-link.sh
cc-version.sh
check-git
check-sysctl-docs
check-uapi.sh
check-variable-fonts.sh
check_extable.sh
checkdeclares.pl
checkincludes.pl
checkkconfigsymbols.py
checkpatch.pl
checkstack.pl
checksyscalls.sh
checktransupdate.py
checkversion.pl
cleanfile
cleanpatch
coccicheck
config
const_structs.checkpatch
decode_stacktrace.sh
decodecode
depmod.sh
dev-needs.sh
diffconfig
documentation-file-ref-check
export_report.pl
extract-ikconfig
extract-module-sig.pl
extract-sys-certs.pl
extract-vmlinux
extract_xc3028.pl
faddr2line
file-size.sh
find-unused-docs.sh
gcc-x86_32-has-stack-protector.sh
gcc-x86_64-has-stack-protector.sh
gen-randstruct-seed.sh
generate_initcall_order.pl
generate_rust_analyzer.py
generate_rust_target.rs
get_abi.pl
get_dvb_firmware
get_feat.pl
get_maintainer.pl
gfp-translate
git.orderFile
head-object-list.txt
headerdep.pl
headers_install.sh
insert-sys-cert.c
install.sh
jobserver-exec
kallsyms.c
kernel-doc
ld-version.sh
leaking_addresses.pl
link-vmlinux.sh
make_fit.py
makelst
markup_oops.pl
min-tool-version.sh
misc-check
mkcompile_h
mksysmap
mkuboot.sh
module.lds.S
modules-check.sh
nsdeps
objdiff
objdump-func
orc_hash.sh
pahole-version.sh
parse-maintainers.pl
patch-kernel
profile2linkerlist.pl
prune-kernel
recordmcount.c
recordmcount.h
recordmcount.pl
relocs_check.sh
remove-stale-files
rust_is_available.sh
rust_is_available_bindgen_0_66.h
rust_is_available_bindgen_libclang.h
rust_is_available_test.py
rustdoc_test_builder.rs
rustdoc_test_gen.rs
setlocalversion
show_delta
sign-file.c
sorttable.c
sorttable.h
spdxcheck-test.sh
spdxcheck.py
spdxexclude
spelling.txt
sphinx-pre-install
split-man.pl
stackdelta
stackusage
subarch.include
syscall.tbl
syscallhdr.sh
syscallnr.sh
syscalltbl.sh
tags.sh
test_fortify.sh
tools-support-relr.sh
unifdef.c
ver_linux
xen-hypercalls.sh
xz_wrap.sh
security
sound
tools
usr
virt
.clang-format
.cocciconfig
.editorconfig
.get_maintainer.ignore
.gitattributes
.gitignore
.mailmap
.rustfmt.toml
COPYING
CREDITS
Kbuild
Kconfig
MAINTAINERS
Makefile
README
Breadcrumbs
linux
/
scripts
/
generate_rust_target.rs
Blame
Blame
Latest commit
History
History
216 lines (188 loc) · 6.97 KB
Breadcrumbs
linux
/
scripts
/
generate_rust_target.rs
Top
File metadata and controls
Code
Blame
216 lines (188 loc) · 6.97 KB
Raw
// SPDX-License-Identifier: GPL-2.0 //! The custom target specification file generator for `rustc`. //! //! To configure a target from scratch, a JSON-encoded file has to be passed //! to `rustc` (introduced in [RFC 131]). These options and the file itself are //! unstable. Eventually, `rustc` should provide a way to do this in a stable //! manner. For instance, via command-line arguments. Therefore, this file //! should avoid using keys which can be set via `-C` or `-Z` options. //! //! [RFC 131]: https://rust-lang.github.io/rfcs/0131-target-specification.html use std::{ collections::HashMap, fmt::{Display, Formatter, Result}, io::BufRead, }; enum Value { Boolean(bool), Number(i32), String(String), Object(Object), } type Object = Vec<(String, Value)>; /// Minimal "almost JSON" generator (e.g. no `null`s, no arrays, no escaping), /// enough for this purpose. impl Display for Value { fn fmt(&self, formatter: &mut Formatter<'_>) -> Result { match self { Value::Boolean(boolean) => write!(formatter, "{}", boolean), Value::Number(number) => write!(formatter, "{}", number), Value::String(string) => write!(formatter, "\"{}\"", string), 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)?; } formatter.write_str("}") } } } } struct TargetSpec(Object); impl TargetSpec { fn new() -> TargetSpec { TargetSpec(Vec::new()) } } trait Push<T> { fn push(&mut self, key: &str, value: T); } impl Push<bool> for TargetSpec { fn push(&mut self, key: &str, value: bool) { self.0.push((key.to_string(), Value::Boolean(value))); } } impl Push<i32> for TargetSpec { fn push(&mut self, key: &str, value: i32) { self.0.push((key.to_string(), Value::Number(value))); } } impl Push<String> for TargetSpec { fn push(&mut self, key: &str, value: String) { self.0.push((key.to_string(), Value::String(value))); } } impl Push<&str> for TargetSpec { fn push(&mut self, key: &str, value: &str) { self.push(key, value.to_string()); } } impl Push<Object> for TargetSpec { fn push(&mut self, key: &str, value: Object) { self.0.push((key.to_string(), Value::Object(value))); } } impl Display for TargetSpec { fn fmt(&self, formatter: &mut Formatter<'_>) -> Result { // We add some newlines for clarity. formatter.write_str("{\n")?; if let [ref rest @ .., ref last] = self.0[..] { for (key, value) in rest { write!(formatter, " \"{}\": {},\n", key, value)?; } write!(formatter, " \"{}\": {}\n", last.0, last.1)?; } formatter.write_str("}") } } struct KernelConfig(HashMap<String, String>); impl KernelConfig { /// Parses `include/config/auto.conf` from `stdin`. fn from_stdin() -> KernelConfig { let mut result = HashMap::new(); let stdin = std::io::stdin(); let mut handle = stdin.lock(); let mut line = String::new(); loop { line.clear(); if handle.read_line(&mut line).unwrap() == 0 { break; } if line.starts_with('#') { continue; } let (key, value) = line.split_once('=').expect("Missing `=` in line."); result.insert(key.to_string(), value.trim_end_matches('\n').to_string()); } KernelConfig(result) } /// Does the option exist in the configuration (any value)? /// /// The argument must be passed without the `CONFIG_` prefix. /// This avoids repetition and it also avoids `fixdep` making us /// depend on it. fn has(&self, option: &str) -> bool { let option = "CONFIG_".to_owned() + option; self.0.contains_key(&option) } } fn main() { let cfg = KernelConfig::from_stdin(); let mut ts = TargetSpec::new(); // `llvm-target`s are taken from `scripts/Makefile.clang`. if cfg.has("ARM64") { panic!("arm64 uses the builtin rustc aarch64-unknown-none target"); } else if cfg.has("RISCV") { if cfg.has("64BIT") { panic!("64-bit RISC-V uses the builtin rustc riscv64-unknown-none-elf target"); } else { panic!("32-bit RISC-V is an unsupported architecture"); } } else if cfg.has("X86_64") { ts.push("arch", "x86_64"); ts.push( "data-layout", "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", ); 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"; } ts.push("features", features); ts.push("llvm-target", "x86_64-linux-gnu"); 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 if !cfg.has("UML") { panic!("32-bit x86 only works under UML"); } ts.push("arch", "x86"); ts.push( "data-layout", "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128", ); let mut features = "-mmx,+soft-float".to_string(); if cfg.has("MITIGATION_RETPOLINE") { features += ",+retpoline-external-thunk"; } ts.push("features", features); ts.push("llvm-target", "i386-unknown-linux-gnu"); ts.push("target-pointer-width", "32"); } else if cfg.has("LOONGARCH") { panic!("loongarch uses the builtin rustc loongarch64-unknown-none-softfloat target"); } else { panic!("Unsupported architecture"); } ts.push("emit-debug-gdb-scripts", false); ts.push("frame-pointer", "may-omit"); ts.push( "stack-probes", vec![("kind".to_string(), Value::String("none".to_string()))], ); // Everything else is LE, whether `CPU_LITTLE_ENDIAN` is declared or not // (e.g. x86). It is also `rustc`'s default. if cfg.has("CPU_BIG_ENDIAN") { ts.push("target-endian", "big"); } println!("{}", ts); }
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
You can’t perform that action at this time.