]>
Commit | Line | Data |
---|---|---|
7ae4cf4c SL |
1 | From ecddda193bb9c060f05b70c215f3874919a42abc Mon Sep 17 00:00:00 2001 |
2 | From: George Rimar <grimar@accesssoftek.com> | |
3 | Date: Fri, 11 Jan 2019 12:10:12 -0800 | |
4 | Subject: x86/build: Specify elf_i386 linker emulation explicitly for i386 | |
5 | objects | |
6 | ||
7 | commit 927185c124d62a9a4d35878d7f6d432a166b74e3 upstream. | |
8 | ||
9 | The kernel uses the OUTPUT_FORMAT linker script command in it's linker | |
10 | scripts. Most of the time, the -m option is passed to the linker with | |
11 | correct architecture, but sometimes (at least for x86_64) the -m option | |
12 | contradicts the OUTPUT_FORMAT directive. | |
13 | ||
14 | Specifically, arch/x86/boot and arch/x86/realmode/rm produce i386 object | |
15 | files, but are linked with the -m elf_x86_64 linker flag when building | |
16 | for x86_64. | |
17 | ||
18 | The GNU linker manpage doesn't explicitly state any tie-breakers between | |
19 | -m and OUTPUT_FORMAT. But with BFD and Gold linkers, OUTPUT_FORMAT | |
20 | overrides the emulation value specified with the -m option. | |
21 | ||
22 | LLVM lld has a different behavior, however. When supplied with | |
23 | contradicting -m and OUTPUT_FORMAT values it fails with the following | |
24 | error message: | |
25 | ||
26 | ld.lld: error: arch/x86/realmode/rm/header.o is incompatible with elf_x86_64 | |
27 | ||
28 | Therefore, just add the correct -m after the incorrect one (it overrides | |
29 | it), so the linker invocation looks like this: | |
30 | ||
31 | ld -m elf_x86_64 -z max-page-size=0x200000 -m elf_i386 --emit-relocs -T \ | |
32 | realmode.lds header.o trampoline_64.o stack.o reboot.o -o realmode.elf | |
33 | ||
34 | This is not a functional change for GNU ld, because (although not | |
35 | explicitly documented) OUTPUT_FORMAT overrides -m EMULATION. | |
36 | ||
37 | Tested by building x86_64 kernel with GNU gcc/ld toolchain and booting | |
38 | it in QEMU. | |
39 | ||
40 | [ bp: massage and clarify text. ] | |
41 | ||
42 | Suggested-by: Dmitry Golovin <dima@golovin.in> | |
43 | Signed-off-by: George Rimar <grimar@accesssoftek.com> | |
44 | Signed-off-by: Tri Vo <trong@android.com> | |
45 | Signed-off-by: Borislav Petkov <bp@suse.de> | |
46 | Tested-by: Tri Vo <trong@android.com> | |
47 | Tested-by: Nick Desaulniers <ndesaulniers@google.com> | |
48 | Cc: "H. Peter Anvin" <hpa@zytor.com> | |
49 | Cc: Ingo Molnar <mingo@redhat.com> | |
50 | Cc: Michael Matz <matz@suse.de> | |
51 | Cc: Thomas Gleixner <tglx@linutronix.de> | |
52 | Cc: morbo@google.com | |
53 | Cc: ndesaulniers@google.com | |
54 | Cc: ruiu@google.com | |
55 | Cc: x86-ml <x86@kernel.org> | |
56 | Link: https://lkml.kernel.org/r/20190111201012.71210-1-trong@android.com | |
57 | [nc: Fix conflicts due to lack of commit 58ab5e0c2c40 ("Kbuild: arch: | |
58 | look for generated headers in obtree") in this tree] | |
59 | Signed-off-by: Nathan Chancellor <natechancellor@gmail.com> | |
60 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
61 | --- | |
62 | arch/x86/boot/Makefile | 2 +- | |
63 | arch/x86/realmode/rm/Makefile | 2 +- | |
64 | 2 files changed, 2 insertions(+), 2 deletions(-) | |
65 | ||
66 | diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile | |
67 | index 6da2cd0897f3..e94745321cac 100644 | |
68 | --- a/arch/x86/boot/Makefile | |
69 | +++ b/arch/x86/boot/Makefile | |
70 | @@ -100,7 +100,7 @@ $(obj)/zoffset.h: $(obj)/compressed/vmlinux FORCE | |
71 | AFLAGS_header.o += -I$(obj) | |
72 | $(obj)/header.o: $(obj)/voffset.h $(obj)/zoffset.h | |
73 | ||
74 | -LDFLAGS_setup.elf := -T | |
75 | +LDFLAGS_setup.elf := -m elf_i386 -T | |
76 | $(obj)/setup.elf: $(src)/setup.ld $(SETUP_OBJS) FORCE | |
77 | $(call if_changed,ld) | |
78 | ||
79 | diff --git a/arch/x86/realmode/rm/Makefile b/arch/x86/realmode/rm/Makefile | |
80 | index 2730d775ef9a..228cb16962ba 100644 | |
81 | --- a/arch/x86/realmode/rm/Makefile | |
82 | +++ b/arch/x86/realmode/rm/Makefile | |
83 | @@ -43,7 +43,7 @@ $(obj)/pasyms.h: $(REALMODE_OBJS) FORCE | |
84 | targets += realmode.lds | |
85 | $(obj)/realmode.lds: $(obj)/pasyms.h | |
86 | ||
87 | -LDFLAGS_realmode.elf := --emit-relocs -T | |
88 | +LDFLAGS_realmode.elf := -m elf_i386 --emit-relocs -T | |
89 | CPPFLAGS_realmode.lds += -P -C -I$(obj) | |
90 | ||
91 | targets += realmode.elf | |
92 | -- | |
93 | 2.19.1 | |
94 |