Skip to contentSkip to conversation

x86/vmlinux: Fix linker fill bytes for ld.lld

PATCH Applied Song Liu 6 participants 7 messages Sep 6, 2023 x86

lore
Share & tools
lore

Song Liu

author
#0 lore raw

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
index 83d41c2601d7..41d56fb9bf92 100644
@@ -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
Reviewed-by on v1 1/1
#1 lore raw
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                      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
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
#2 lore raw
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                      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.

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

#3 lore raw
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                      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.

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
宋方睿
Acked-by on v1 1/1
#4 lore raw
In reply to Song Liu
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                      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
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
index 83d41c2601d7..41d56fb9bf92 100644
@@ -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
author
#5 lore raw
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                      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.

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:

Fixes 7705dc855797 ("x86/vmlinux: Use INT3 instead of NOP for linker

fill bytes")

Thanks,
Song

Quoted 2 lines
merge bot Applied
#6 lore raw

[tip: x86/urgent] x86/build: Fix linker fill bytes quirk/incompatibility for ld.lld

In reply to Song Liu
The 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.

Fixes 7705dc855797 ("x86/vmlinux: Use INT3 instead of NOP for linker fill bytes")
---
 arch/x86/kernel/vmlinux.lds.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/vmlinux.lds.S +1 -1
index 83d41c2..f15fb71 100644
@@ -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 = .;