Skip to content

Commit 99862d1

Browse files
authored
Merge pull request raspberrypi#706 from ojeda/ts-clean
Target specification cleanup
2 parents 526a83b + 257d449 commit 99862d1

File tree

4 files changed

+53
-119
lines changed

4 files changed

+53
-119
lines changed

Makefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,9 +553,11 @@ KBUILD_CFLAGS := -Wall -Wundef -Werror=strict-prototypes -Wno-trigraphs \
553553
KBUILD_CPPFLAGS := -D__KERNEL__
554554
KBUILD_RUSTFLAGS := $(rust_common_flags) \
555555
--target=$(objtree)/rust/target.json \
556-
-Cpanic=abort -Cembed-bitcode=n -Clto=n -Crpath=n \
556+
-Cpanic=abort -Cembed-bitcode=n -Clto=n \
557557
-Cforce-unwind-tables=n -Ccodegen-units=1 \
558558
-Csymbol-mangling-version=v0 \
559+
-Crelocation-model=static \
560+
-Zfunction-sections=n \
559561
-Dclippy::float_arithmetic
560562

561563
KBUILD_AFLAGS_KERNEL :=
@@ -887,6 +889,8 @@ else
887889
# select FRAME_POINTER. However, FUNCTION_TRACER adds -pg, and this is
888890
# incompatible with -fomit-frame-pointer with current GCC, so we don't use
889891
# -fomit-frame-pointer with FUNCTION_TRACER.
892+
# In the Rust target specification, "frame-pointer" is set explicitly
893+
# to "may-omit".
890894
ifndef CONFIG_FUNCTION_TRACER
891895
KBUILD_CFLAGS += -fomit-frame-pointer
892896
endif
@@ -951,8 +955,10 @@ ifdef CONFIG_DEBUG_SECTION_MISMATCH
951955
KBUILD_CFLAGS += -fno-inline-functions-called-once
952956
endif
953957

958+
# `rustc`'s `-Zfunction-sections` applies to data too (as of 1.59.0).
954959
ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION
955960
KBUILD_CFLAGS_KERNEL += -ffunction-sections -fdata-sections
961+
KBUILD_RUSTFLAGS_KERNEL += -Zfunction-sections=y
956962
LDFLAGS_vmlinux += --gc-sections
957963
endif
958964

arch/riscv/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,18 @@ ifeq ($(CONFIG_ARCH_RV64I),y)
2626
KBUILD_CFLAGS += -mabi=lp64
2727
KBUILD_AFLAGS += -mabi=lp64
2828

29+
KBUILD_RUSTFLAGS += -Ctarget-cpu=generic-rv64
30+
2931
KBUILD_LDFLAGS += -melf64lriscv
3032
else
3133
BITS := 32
3234
UTS_MACHINE := riscv32
3335

3436
KBUILD_CFLAGS += -mabi=ilp32
3537
KBUILD_AFLAGS += -mabi=ilp32
38+
39+
KBUILD_RUSTFLAGS += -Ctarget-cpu=generic-rv32
40+
3641
KBUILD_LDFLAGS += -melf32lriscv
3742
endif
3843

arch/x86/Makefile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ ifdef CONFIG_CC_IS_CLANG
2121
RETPOLINE_CFLAGS := -mretpoline-external-thunk
2222
RETPOLINE_VDSO_CFLAGS := -mretpoline
2323
endif
24+
RETPOLINE_RUSTFLAGS := -Ctarget-feature=+retpoline-external-thunk
25+
2426
export RETPOLINE_CFLAGS
2527
export RETPOLINE_VDSO_CFLAGS
2628

@@ -61,6 +63,8 @@ export BITS
6163
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53383
6264
#
6365
KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx
66+
KBUILD_RUSTFLAGS += -Ctarget-feature=-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2
67+
KBUILD_RUSTFLAGS += -Ctarget-feature=-3dnow,-3dnowa,-avx,-avx2,+soft-float
6468

6569
# Intel CET isn't enabled in the kernel
6670
KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none)
@@ -136,8 +140,17 @@ else
136140
cflags-$(CONFIG_GENERIC_CPU) += -mtune=generic
137141
KBUILD_CFLAGS += $(cflags-y)
138142

143+
rustflags-$(CONFIG_MK8) += -Ctarget-cpu=k8
144+
rustflags-$(CONFIG_MPSC) += -Ctarget-cpu=nocona
145+
rustflags-$(CONFIG_MCORE2) += -Ctarget-cpu=core2
146+
rustflags-$(CONFIG_MATOM) += -Ctarget-cpu=atom
147+
rustflags-$(CONFIG_GENERIC_CPU) += -Ztune-cpu=generic
148+
KBUILD_RUSTFLAGS += $(rustflags-y)
149+
139150
KBUILD_CFLAGS += -mno-red-zone
140151
KBUILD_CFLAGS += -mcmodel=kernel
152+
KBUILD_RUSTFLAGS += -Cno-redzone=y
153+
KBUILD_RUSTFLAGS += -Ccode-model=kernel
141154
endif
142155

143156
ifdef CONFIG_X86_X32
@@ -189,6 +202,7 @@ ifdef CONFIG_RETPOLINE
189202
ifndef CONFIG_CC_IS_CLANG
190203
KBUILD_CFLAGS += -fno-jump-tables
191204
endif
205+
KBUILD_RUSTFLAGS += $(RETPOLINE_RUSTFLAGS)
192206
endif
193207

194208
ifdef CONFIG_SLS

scripts/generate_rust_target.rs

Lines changed: 27 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
//! To configure a target from scratch, a JSON-encoded file has to be passed
66
//! to `rustc` (introduced in [RFC 131]). These options and the file itself are
77
//! unstable. Eventually, `rustc` should provide a way to do this in a stable
8-
//! manner. For instance, via command-line arguments.
8+
//! manner. For instance, via command-line arguments. Therefore, this file
9+
//! should avoid using keys which can be set via `-C` or `-Z` options.
910
//!
1011
//! [RFC 131]: https://rust-lang.github.io/rfcs/0131-target-specification.html
1112
@@ -19,38 +20,26 @@ enum Value {
1920
Boolean(bool),
2021
Number(i32),
2122
String(String),
22-
Array(Array),
2323
Object(Object),
2424
}
2525

26-
type Array = Vec<Value>;
2726
type Object = Vec<(String, Value)>;
2827

29-
/// Minimal "almost JSON" generator (e.g. no `null`s, no escaping), enough
30-
/// for this purpose.
28+
/// Minimal "almost JSON" generator (e.g. no `null`s, no arrays, no escaping),
29+
/// enough for this purpose.
3130
impl Display for Value {
3231
fn fmt(&self, formatter: &mut Formatter<'_>) -> Result {
3332
match self {
3433
Value::Boolean(boolean) => write!(formatter, "{}", boolean),
3534
Value::Number(number) => write!(formatter, "{}", number),
3635
Value::String(string) => write!(formatter, "\"{}\"", string),
37-
Value::Array(array) => {
38-
formatter.write_str("[")?;
39-
if let [ref rest @ .., ref last] = array[..] {
40-
for value in rest {
41-
write!(formatter, "{},", value)?;
42-
}
43-
write!(formatter, "{}", last)?;
44-
}
45-
formatter.write_str("]")
46-
}
4736
Value::Object(object) => {
4837
formatter.write_str("{")?;
4938
if let [ref rest @ .., ref last] = object[..] {
5039
for (key, value) in rest {
51-
write!(formatter, "\"{}\":{},", key, value)?;
40+
write!(formatter, "\"{}\": {},", key, value)?;
5241
}
53-
write!(formatter, "\"{}\":{}", last.0, last.1)?;
42+
write!(formatter, "\"{}\": {}", last.0, last.1)?;
5443
}
5544
formatter.write_str("}")
5645
}
@@ -106,9 +95,9 @@ impl Display for TargetSpec {
10695
formatter.write_str("{\n")?;
10796
if let [ref rest @ .., ref last] = self.0[..] {
10897
for (key, value) in rest {
109-
write!(formatter, "\"{}\":{},\n", key, value)?;
98+
write!(formatter, " \"{}\": {},\n", key, value)?;
11099
}
111-
write!(formatter, "\"{}\":{}\n", last.0, last.1)?;
100+
write!(formatter, " \"{}\": {}\n", last.0, last.1)?;
112101
}
113102
formatter.write_str("}")
114103
}
@@ -147,7 +136,7 @@ impl KernelConfig {
147136
///
148137
/// The argument must be passed without the `CONFIG_` prefix.
149138
/// This avoids repetition and it also avoids `fixdep` making us
150-
/// depending on it.
139+
/// depend on it.
151140
fn has(&self, option: &str) -> bool {
152141
let option = "CONFIG_".to_owned() + option;
153142
self.0.contains_key(&option)
@@ -158,50 +147,15 @@ fn main() {
158147
let cfg = KernelConfig::from_stdin();
159148
let mut ts = TargetSpec::new();
160149

161-
let pre_link_args = vec![(
162-
"gcc".to_string(),
163-
Value::Array(vec![
164-
Value::String("-Wl,--as-needed".to_string()),
165-
Value::String("-Wl,-z,noexecstack".to_string()),
166-
]),
167-
)];
168-
169-
let pre_link_args_32 = vec![(
170-
"gcc".to_string(),
171-
Value::Array(vec![
172-
Value::String("-Wl,--as-needed".to_string()),
173-
Value::String("-Wl,-z,noexecstack".to_string()),
174-
Value::String("-m32".to_string()),
175-
]),
176-
)];
177-
178-
let pre_link_args_64 = vec![(
179-
"gcc".to_string(),
180-
Value::Array(vec![
181-
Value::String("-Wl,--as-needed".to_string()),
182-
Value::String("-Wl,-z,noexecstack".to_string()),
183-
Value::String("-m64".to_string()),
184-
]),
185-
)];
186-
187-
let stack_probes = vec![("kind".to_string(), Value::String("none".to_string()))];
188-
189150
if cfg.has("ARM") {
190151
ts.push("arch", "arm");
191152
ts.push(
192153
"data-layout",
193154
"e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
194155
);
195-
ts.push("dynamic-linking", true);
196-
ts.push("crt-static-respected", true);
197-
ts.push("executables", true);
198156
ts.push("features", "+strict-align,+v6");
199-
ts.push("has-elf-tls", true);
200-
ts.push("has-rpath", true);
201-
ts.push("llvm-target", "arm-unknown-linux-gnueabi");
157+
ts.push("llvm-target", "arm-linux-gnueabi");
202158
ts.push("max-atomic-width", 64);
203-
ts.push("pre-link-args", pre_link_args);
204-
ts.push("target-family", "unix");
205159
ts.push("target-mcount", "\\u0001__gnu_mcount_nc");
206160
ts.push("target-pointer-width", "32");
207161
} else if cfg.has("ARM64") {
@@ -211,106 +165,61 @@ fn main() {
211165
"e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
212166
);
213167
ts.push("disable-redzone", true);
214-
ts.push("emit-debug-gdb-scripts", false);
215-
ts.push("features", "+strict-align,+neon,+fp-armv8");
216-
ts.push("frame-pointer", "always");
217-
ts.push("llvm-target", "aarch64-unknown-none");
168+
ts.push("features", "+strict-align,-neon,-fp-armv8");
169+
ts.push("llvm-target", "aarch64-linux-gnu");
218170
ts.push("max-atomic-width", 128);
219-
ts.push("needs-plt", true);
220-
ts.push("pre-link-args", pre_link_args_64);
221-
ts.push("stack-probes", stack_probes);
222-
ts.push("target-c-int-width", "32");
223171
ts.push("target-pointer-width", "64");
224-
ts.push("vendor", "");
225172
} else if cfg.has("PPC") {
226173
ts.push("arch", "powerpc64");
227174
ts.push("code-model", "large");
228-
ts.push("cpu", "ppc64le");
229175
ts.push("data-layout", "e-m:e-i64:64-n32:64");
230176
ts.push("features", "-altivec,-vsx,-hard-float");
231-
ts.push("llvm-target", "powerpc64le-elf");
177+
ts.push("llvm-target", "powerpc64le-linux-gnu");
232178
ts.push("max-atomic-width", 64);
233-
ts.push("pre-link-args", pre_link_args_64);
234-
ts.push("target-family", "unix");
235179
ts.push("target-mcount", "_mcount");
236180
ts.push("target-pointer-width", "64");
237181
} else if cfg.has("RISCV") {
238182
if cfg.has("64BIT") {
239183
ts.push("arch", "riscv64");
240-
ts.push("cpu", "generic-rv64");
241184
ts.push("data-layout", "e-m:e-p:64:64-i64:64-i128:128-n64-S128");
242-
ts.push("llvm-target", "riscv64");
243-
ts.push("max-atomic-width", 64);
244-
ts.push("pre-link-args", pre_link_args_64);
185+
ts.push("llvm-target", "riscv64-linux-gnu");
245186
ts.push("target-pointer-width", "64");
246187
} else {
247188
ts.push("arch", "riscv32");
248-
ts.push("cpu", "generic-rv32");
249189
ts.push("data-layout", "e-m:e-p:32:32-i64:64-n32-S128");
250-
ts.push("llvm-target", "riscv32");
251-
ts.push("max-atomic-width", 32);
252-
ts.push("pre-link-args", pre_link_args_32);
190+
ts.push("llvm-target", "riscv32-linux-gnu");
253191
ts.push("target-pointer-width", "32");
254192
}
255193
ts.push("code-model", "medium");
256194
ts.push("disable-redzone", true);
257-
ts.push("emit-debug-gdb-scripts", false);
258195
let mut features = "+m,+a".to_string();
259196
if cfg.has("RISCV_ISA_C") {
260197
features += ",+c";
261198
}
262199
ts.push("features", features);
263-
ts.push("frame-pointer", "always");
264-
ts.push("needs-plt", true);
265-
ts.push("target-c-int-width", "32");
266-
ts.push("stack-probes", stack_probes);
267-
ts.push("vendor", "");
268200
} else if cfg.has("X86") {
269201
ts.push("arch", "x86_64");
270-
ts.push("code-model", "kernel");
271-
ts.push("cpu", "x86-64");
272202
ts.push(
273203
"data-layout",
274204
"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
275205
);
276-
ts.push("disable-redzone", true);
277-
ts.push("emit-debug-gdb-scripts", false);
278-
ts.push(
279-
"features",
280-
"-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float",
281-
);
282-
ts.push("frame-pointer", "always");
283-
ts.push("llvm-target", "x86_64-elf");
284-
ts.push("max-atomic-width", 64);
285-
ts.push("needs-plt", true);
286-
ts.push("pre-link-args", pre_link_args_64);
287-
ts.push("stack-probes", stack_probes);
288-
ts.push("target-c-int-width", "32");
206+
ts.push("llvm-target", "x86_64-linux-gnu");
289207
ts.push("target-pointer-width", "64");
290-
ts.push("vendor", "unknown");
291208
} else {
292209
panic!("Unsupported architecture");
293210
}
294211

295-
ts.push("env", "gnu");
296-
ts.push("function-sections", false);
297-
ts.push("linker-is-gnu", true);
298-
ts.push("os", if cfg.has("ARM") { "linux" } else { "none" });
299-
ts.push("position-independent-executables", true);
300-
ts.push("relocation-model", "static");
301-
302-
if !cfg.has("ARM") {
303-
ts.push("linker-flavor", "gcc");
304-
ts.push("panic-strategy", "abort");
305-
ts.push("relro-level", "full");
306-
307-
if cfg.has("CPU_BIG_ENDIAN") {
308-
ts.push("target-endian", "big");
309-
} else {
310-
// Everything else is LE, whether `CPU_LITTLE_ENDIAN`
311-
// is declared or not (e.g. x86).
312-
ts.push("target-endian", "little");
313-
}
212+
ts.push("emit-debug-gdb-scripts", false);
213+
ts.push("frame-pointer", "may-omit");
214+
ts.push(
215+
"stack-probes",
216+
vec![("kind".to_string(), Value::String("none".to_string()))],
217+
);
218+
219+
// Everything else is LE, whether `CPU_LITTLE_ENDIAN` is declared or not
220+
// (e.g. x86). It is also `rustc`'s default.
221+
if cfg.has("CPU_BIG_ENDIAN") {
222+
ts.push("target-endian", "big");
314223
}
315224

316225
println!("{}", ts);

0 commit comments

Comments
 (0)