x86/vmlinux: Fix linker fill bytes for ld.lld
PATCH 1/1 x86/vmlinux: Fix linker fill bytes for ld.lld
With ":text =0xcccc", ld.lld fills unused text area with 0xcccc0000. Example objdump -D output:
ffffffff82b04203: 00 00 add %al,(%rax) ffffffff82b04205: cc int3 ffffffff82b04206: cc int3 ffffffff82b04207: 00 00 add %al,(%rax) ffffffff82b04209: cc int3 ffffffff82b0420a: cc int3
Replace it with ":text =0xcccccccc", so we get the following instead:
ffffffff82b04203: cc int3 ffffffff82b04204: cc int3 ffffffff82b04205: cc int3 ffffffff82b04206: cc int3 ffffffff82b04207: cc int3 ffffffff82b04208: cc int3
gcc/ld doesn't seem to have the same issue. The generated code stays the same for gcc/ld.
--- arch/x86/kernel/vmlinux.lds.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/vmlinux.lds.S +1 -1
@@ -156,7 +156,7 @@ SECTIONS ALIGN_ENTRY_TEXT_END *(.gnu.warning) - } :text =0xcccc + } :text =0xcccccccc /* End of text section, which should occupy whole number of pages */ _etext = .;
Signature · 1 line
2.34.1
Quoted 19 lines · Song Liu
With ":text =0xcccc", ld.lld fills unused text area with
0xcccc0000. Example objdump -D output:ffffffff82b04203: 00 00 add %al,(%rax) ffffffff82b04205: cc int3 ffffffff82b04206: cc int3 ffffffff82b04207: 00 00 add %al,(%rax) ffffffff82b04209: cc int3 ffffffff82b0420a: cc int3Replace it with ":text =0xcccccccc", so we get the following instead:
ffffffff82b04203: cc int3 ffffffff82b04204: cc int3 ffffffff82b04205: cc int3 ffffffff82b04206: cc int3 ffffffff82b04207: cc int3 ffffffff82b04208: cc int3
Quoted 6 lines
gcc/ld doesn't seem to have the same issue. The generated code stays the same for gcc/ld.
Ah! Thanks for the catch... I wonder if ld.lld should be fixed too? My understanding was that ":text =...." was defined as being explicitly u16?
Signature · 1 line
Kees Cook
Quoted 27 lines · Kees Cook
Quoted 22 lines · Song Liu
With ":text =0xcccc", ld.lld fills unused text area with
0xcccc0000. Example objdump -D output:ffffffff82b04203: 00 00 add %al,(%rax) ffffffff82b04205: cc int3 ffffffff82b04206: cc int3 ffffffff82b04207: 00 00 add %al,(%rax) ffffffff82b04209: cc int3 ffffffff82b0420a: cc int3Replace it with ":text =0xcccccccc", so we get the following instead:
ffffffff82b04203: cc int3 ffffffff82b04204: cc int3 ffffffff82b04205: cc int3 ffffffff82b04206: cc int3 ffffffff82b04207: cc int3 ffffffff82b04208: cc int3gcc/ld doesn't seem to have the same issue. The generated code stays the same for gcc/ld.
Quoted 7 lines
Quoted 3 lines
Ah! Thanks for the catch... I wonder if ld.lld should be fixed too? My understanding was that ":text =...." was defined as being explicitly u16?
Per my experiment, gcc/ld gives same output for :text =0xcc, :text =0xcccc, and :text =0xcccccccc; while ld.lld handles :text = as u32, so :text =0xcc with ld.lld gives:
ffffffff82b042a1: 00 cc add %cl,%ah ffffffff82b042a3: 00 00 add %al,(%rax) ffffffff82b042a5: 00 cc add %cl,%ah ffffffff82b042a7: 00 00 add %al,(%rax) ffffffff82b042a9: 00 cc add %cl,%ah ffffffff82b042ab: 00 00 add %al,(%rax)
I am not sure what the right behavior is per specification.
Thanks,
Song
Quoted 47 lines · Song Liu
Quoted 28 lines · Kees Cook
Quoted 22 lines · Song Liu
With ":text =0xcccc", ld.lld fills unused text area with
0xcccc0000. Example objdump -D output:ffffffff82b04203: 00 00 add %al,(%rax) ffffffff82b04205: cc int3 ffffffff82b04206: cc int3 ffffffff82b04207: 00 00 add %al,(%rax) ffffffff82b04209: cc int3 ffffffff82b0420a: cc int3Replace it with ":text =0xcccccccc", so we get the following instead:
ffffffff82b04203: cc int3 ffffffff82b04204: cc int3 ffffffff82b04205: cc int3 ffffffff82b04206: cc int3 ffffffff82b04207: cc int3 ffffffff82b04208: cc int3gcc/ld doesn't seem to have the same issue. The generated code stays the same for gcc/ld.
Quoted 7 lines
Quoted 3 lines
Ah! Thanks for the catch... I wonder if ld.lld should be fixed too? My understanding was that ":text =...." was defined as being explicitly u16?
Per my experiment, gcc/ld gives same output for :text =0xcc, :text =0xcccc, and :text =0xcccccccc; while ld.lld handles :text = as u32, so :text =0xcc with ld.lld gives:
ffffffff82b042a1: 00 cc add %cl,%ah ffffffff82b042a3: 00 00 add %al,(%rax) ffffffff82b042a5: 00 cc add %cl,%ah ffffffff82b042a7: 00 00 add %al,(%rax) ffffffff82b042a9: 00 cc add %cl,%ah ffffffff82b042ab: 00 00 add %al,(%rax)
Quoted 4 lines
I am not sure what the right behavior is per specification.
Thanks,
Song
AFAIK GNU ld's behavior is not documented here
https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html
The Output Section Fill syntax allows an expression. It seems that if you use =0xcc+0, GNU ld will use a 4-byte filler as well, similar to gold and ld.lld.
Frankly, I feel that GNU ld behavior should not be relied upon. lld's comment states that it is a deliberate choice to follow gold instead of GNU ld here.
I'll elaborate a bit and add this discrepancy to my
https://maskray.me/blog/2020-12-19-lld-and-gnu-linker-incompatibilities
:)
Signature · 1 line
宋方睿
Quoted 19 lines · Song Liu
With ":text =0xcccc", ld.lld fills unused text area with
0xcccc0000. Example objdump -D output:ffffffff82b04203: 00 00 add %al,(%rax) ffffffff82b04205: cc int3 ffffffff82b04206: cc int3 ffffffff82b04207: 00 00 add %al,(%rax) ffffffff82b04209: cc int3 ffffffff82b0420a: cc int3Replace it with ":text =0xcccccccc", so we get the following instead:
ffffffff82b04203: cc int3 ffffffff82b04204: cc int3 ffffffff82b04205: cc int3 ffffffff82b04206: cc int3 ffffffff82b04207: cc int3 ffffffff82b04208: cc int3
Quoted 6 lines
gcc/ld doesn't seem to have the same issue. The generated code stays the same for gcc/ld.
Please provide a Fixes tag, I'm thinking this (otherwise trivial commit) wants to be backported for sanity.
Quoted 20 lines
--- arch/x86/kernel/vmlinux.lds.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)arch/x86/kernel/vmlinux.lds.S +1
-1@@ -156,7 +156,7 @@ SECTIONS ALIGN_ENTRY_TEXT_END *(.gnu.warning) - } :text =0xcccc + } :text =0xcccccccc /* End of text section, which should occupy whole number of pages */ _etext = .;Signature · 1 line
2.34.1
Quoted 24 lines · Peter Zijlstra
Quoted 22 lines · Song Liu
With ":text =0xcccc", ld.lld fills unused text area with
0xcccc0000. Example objdump -D output:ffffffff82b04203: 00 00 add %al,(%rax) ffffffff82b04205: cc int3 ffffffff82b04206: cc int3 ffffffff82b04207: 00 00 add %al,(%rax) ffffffff82b04209: cc int3 ffffffff82b0420a: cc int3Replace it with ":text =0xcccccccc", so we get the following instead:
ffffffff82b04203: cc int3 ffffffff82b04204: cc int3 ffffffff82b04205: cc int3 ffffffff82b04206: cc int3 ffffffff82b04207: cc int3 ffffffff82b04208: cc int3gcc/ld doesn't seem to have the same issue. The generated code stays the same for gcc/ld.
Quoted 6 lines
Quoted 3 lines
Please provide a Fixes tag, I'm thinking this (otherwise trivial commit) wants to be backported for sanity.
I guess we need:
fill bytes")
Thanks,
Song
Quoted 2 lines
[tip: x86/urgent] x86/build: Fix linker fill bytes quirk/incompatibility for ld.lld
In reply to Song LiuThe following commit has been merged into the x86/urgent branch of tip:
The following commit has been merged into the x86/urgent branch of tip:
Commit-ID: 65e710899fd19f435f40268f3a92dfaa11f14470 Gitweb: https://git.kernel.org/tip/65e710899fd19f435f40268f3a92dfaa11f14470 Author: Song Liu <[email protected]> AuthorDate: Wed, 06 Sep 2023 10:52:15 -07:00 Committer: Ingo Molnar <[email protected]> CommitterDate: Wed, 06 Sep 2023 23:49:12 +02:00
x86/build: Fix linker fill bytes quirk/incompatibility for ld.lld
With ":text =0xcccc", ld.lld fills unused text area with 0xcccc0000. Example objdump -D output:
ffffffff82b04203: 00 00 add %al,(%rax) ffffffff82b04205: cc int3 ffffffff82b04206: cc int3 ffffffff82b04207: 00 00 add %al,(%rax) ffffffff82b04209: cc int3 ffffffff82b0420a: cc int3
Replace it with ":text =0xcccccccc", so we get the following instead:
ffffffff82b04203: cc int3 ffffffff82b04204: cc int3 ffffffff82b04205: cc int3 ffffffff82b04206: cc int3 ffffffff82b04207: cc int3 ffffffff82b04208: cc int3
gcc/ld doesn't seem to have the same issue. The generated code stays the same for gcc/ld.
--- arch/x86/kernel/vmlinux.lds.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/vmlinux.lds.S +1 -1
@@ -156,7 +156,7 @@ SECTIONS ALIGN_ENTRY_TEXT_END *(.gnu.warning) - } :text =0xcccc + } :text = 0xcccccccc /* End of text section, which should occupy whole number of pages */ _etext = .;