* [PATCH 5.4] x86/boot/compressed: Relax sed symbol type regex for LLVM ld.lld
@ 2020-06-22 19:56 Nathan Chancellor
2020-06-22 21:51 ` Sasha Levin
0 siblings, 1 reply; 2+ messages in thread
From: Nathan Chancellor @ 2020-06-22 19:56 UTC (permalink / raw)
To: Greg Kroah-Hartman, Sasha Levin
Cc: stable, clang-built-linux, Ard Biesheuvel, Ingo Molnar,
Nathan Chancellor
From: Ard Biesheuvel <ardb@kernel.org>
commit bc310baf2ba381c648983c7f4748327f17324562 upstream.
The final build stage of the x86 kernel captures some symbol
addresses from the decompressor binary and copies them into zoffset.h.
It uses sed with a regular expression that matches the address, symbol
type and symbol name, and mangles the captured addresses and the names
of symbols of interest into #define directives that are added to
zoffset.h
The symbol type is indicated by a single letter, which we match
strictly: only letters in the set 'ABCDGRSTVW' are matched, even
though the actual symbol type is relevant and therefore ignored.
Commit bc7c9d620 ("efi/libstub/x86: Force 'hidden' visibility for
extern declarations") made a change to the way external symbol
references are classified, resulting in 'startup_32' now being
emitted as a hidden symbol. This prevents the use of GOT entries to
refer to this symbol via its absolute address, which recent toolchains
(including Clang based ones) already avoid by default, making this
change a no-op in the majority of cases.
However, as it turns out, the LLVM linker classifies such hidden
symbols as symbols with static linkage in fully linked ELF binaries,
causing tools such as NM to output a lowercase 't' rather than an upper
case 'T' for the type of such symbols. Since our sed expression only
matches upper case letters for the symbol type, the line describing
startup_32 is disregarded, resulting in a build error like the following
arch/x86/boot/header.S:568:18: error: symbol 'ZO_startup_32' can not be
undefined in a subtraction expression
init_size: .long (0x00000000008fd000 - ZO_startup_32 +
(((0x0000000001f6361c + ((0x0000000001f6361c >> 8) + 65536)
- 0x00000000008c32e5) + 4095) & ~4095)) # kernel initialization size
Given that we are only interested in the value of the symbol, let's match
any character in the set 'a-zA-Z' instead.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Tested-by: Nathan Chancellor <natechancellor@gmail.com>
Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
---
Hi all,
Please apply this patch to 5.4 (and older releases if you feel it
necessary), as it fixes a build error that I see when linking with
ld.lld on certain distribution configurations after upstream commit
5214028dd89e ("x86/boot: Correct relocation destination on old linkers")
was applied in 5.4.48.
$ make -skj"$(nproc)" CC=clang LD=ld.lld O=out/x86_64 olddefconfig bzImage
...
ld.lld: error: undefined symbol: ZO__end
>>> referenced by arch/x86/boot/header.o:(.header+0x71)
...
While the commit message references bc7c9d620 as the first problematic
commit, I see the same behavior of capital versus lowercase letters from
nm here too. I assume this is not seen in mainline because this commit
was already in the tree when 5214028dd89e was applied.
v5.4.47:
$ nm -S out/x86_64/arch/x86/boot/compressed/vmlinux | grep " _end"
000000000094b000 B _end
$ cat out/x86_64/arch/x86/boot/zoffset.h
#define ZO__ehead 0x00000000000003b1
#define ZO__end 0x000000000094b000
#define ZO__text 0x000000000090ce50
#define ZO_efi32_stub_entry 0x0000000000000190
#define ZO_efi64_stub_entry 0x0000000000000390
#define ZO_efi_pe_entry 0x00000000000002f0
#define ZO_input_data 0x00000000000003b1
#define ZO_startup_32 0x0000000000000000
#define ZO_startup_64 0x0000000000000200
#define ZO_z_input_len 0x000000000090ca9e
#define ZO_z_output_len 0x0000000002eeb42c
v5.4.48:
$ nm -S out/x86_64/arch/x86/boot/compressed/vmlinux | grep " _end"
000000000094b000 b _end
$ cat out/x86_64/arch/x86/boot/zoffset.h
#define ZO__ehead 0x00000000000003b1
#define ZO__text 0x000000000090ccf0
#define ZO_efi32_stub_entry 0x0000000000000190
#define ZO_efi64_stub_entry 0x0000000000000390
#define ZO_efi_pe_entry 0x00000000000002f0
#define ZO_input_data 0x00000000000003b1
#define ZO_startup_32 0x0000000000000000
#define ZO_startup_64 0x0000000000000200
#define ZO_z_input_len 0x000000000090c93b
#define ZO_z_output_len 0x0000000002eeb4c8
v5.4.48 with this patch:
$ nm -S out/x86_64/arch/x86/boot/compressed/vmlinux | grep " _end"
000000000094b000 b _end
$ cat out/x86_64/arch/x86/boot/zoffset.h
#define ZO__ehead 0x00000000000003b1
#define ZO__end 0x000000000094b000
#define ZO__text 0x000000000090cd60
#define ZO_efi32_stub_entry 0x0000000000000190
#define ZO_efi64_stub_entry 0x0000000000000390
#define ZO_efi_pe_entry 0x00000000000002f0
#define ZO_input_data 0x00000000000003b1
#define ZO_startup_32 0x0000000000000000
#define ZO_startup_64 0x0000000000000200
#define ZO_z_input_len 0x000000000090c9af
#define ZO_z_output_len 0x0000000002eeb4c8
Hopefully this clears things up.
Cheers,
Nathan
arch/x86/boot/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index e2839b5c246c..6539c50fb9aa 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -87,7 +87,7 @@ $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
SETUP_OBJS = $(addprefix $(obj)/,$(setup-y))
-sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|input_data\|_end\|_ehead\|_text\|z_.*\)$$/\#define ZO_\2 0x\1/p'
+sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [a-zA-Z] \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|input_data\|_end\|_ehead\|_text\|z_.*\)$$/\#define ZO_\2 0x\1/p'
quiet_cmd_zoffset = ZOFFSET $@
cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@
base-commit: 67cb016870e2fa9ffc8d34cf20db5331e6f2cf4d
--
2.27.0
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH 5.4] x86/boot/compressed: Relax sed symbol type regex for LLVM ld.lld
2020-06-22 19:56 [PATCH 5.4] x86/boot/compressed: Relax sed symbol type regex for LLVM ld.lld Nathan Chancellor
@ 2020-06-22 21:51 ` Sasha Levin
0 siblings, 0 replies; 2+ messages in thread
From: Sasha Levin @ 2020-06-22 21:51 UTC (permalink / raw)
To: Nathan Chancellor
Cc: Greg Kroah-Hartman, stable, clang-built-linux, Ard Biesheuvel,
Ingo Molnar
On Mon, Jun 22, 2020 at 07:56:39PM +0000, Nathan Chancellor wrote:
>From: Ard Biesheuvel <ardb@kernel.org>
>
>commit bc310baf2ba381c648983c7f4748327f17324562 upstream.
>
>The final build stage of the x86 kernel captures some symbol
>addresses from the decompressor binary and copies them into zoffset.h.
>It uses sed with a regular expression that matches the address, symbol
>type and symbol name, and mangles the captured addresses and the names
>of symbols of interest into #define directives that are added to
>zoffset.h
>
>The symbol type is indicated by a single letter, which we match
>strictly: only letters in the set 'ABCDGRSTVW' are matched, even
>though the actual symbol type is relevant and therefore ignored.
>
>Commit bc7c9d620 ("efi/libstub/x86: Force 'hidden' visibility for
>extern declarations") made a change to the way external symbol
>references are classified, resulting in 'startup_32' now being
>emitted as a hidden symbol. This prevents the use of GOT entries to
>refer to this symbol via its absolute address, which recent toolchains
>(including Clang based ones) already avoid by default, making this
>change a no-op in the majority of cases.
>
>However, as it turns out, the LLVM linker classifies such hidden
>symbols as symbols with static linkage in fully linked ELF binaries,
>causing tools such as NM to output a lowercase 't' rather than an upper
>case 'T' for the type of such symbols. Since our sed expression only
>matches upper case letters for the symbol type, the line describing
>startup_32 is disregarded, resulting in a build error like the following
>
> arch/x86/boot/header.S:568:18: error: symbol 'ZO_startup_32' can not be
> undefined in a subtraction expression
> init_size: .long (0x00000000008fd000 - ZO_startup_32 +
> (((0x0000000001f6361c + ((0x0000000001f6361c >> 8) + 65536)
> - 0x00000000008c32e5) + 4095) & ~4095)) # kernel initialization size
>
>Given that we are only interested in the value of the symbol, let's match
>any character in the set 'a-zA-Z' instead.
>
>Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
>Signed-off-by: Ingo Molnar <mingo@kernel.org>
>Tested-by: Nathan Chancellor <natechancellor@gmail.com>
>Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
>---
>
>Hi all,
>
>Please apply this patch to 5.4 (and older releases if you feel it
>necessary), as it fixes a build error that I see when linking with
>ld.lld on certain distribution configurations after upstream commit
>5214028dd89e ("x86/boot: Correct relocation destination on old linkers")
>was applied in 5.4.48.
>
>$ make -skj"$(nproc)" CC=clang LD=ld.lld O=out/x86_64 olddefconfig bzImage
>...
>ld.lld: error: undefined symbol: ZO__end
>>>> referenced by arch/x86/boot/header.o:(.header+0x71)
>...
>
>While the commit message references bc7c9d620 as the first problematic
>commit, I see the same behavior of capital versus lowercase letters from
>nm here too. I assume this is not seen in mainline because this commit
>was already in the tree when 5214028dd89e was applied.
I've queued this for 5.4-4.9, thanks!
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2020-06-22 21:51 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-06-22 19:56 [PATCH 5.4] x86/boot/compressed: Relax sed symbol type regex for LLVM ld.lld Nathan Chancellor
2020-06-22 21:51 ` Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox