arch/x86/boot/setup.ld | 1 + 1 file changed, 1 insertion(+)
With the --dynamic-linker flag added, either manually or via a
toolchain wrapper, the ld.lld linker generates a .interp section at
address 0x1f1 which is normally reserved for the hdr, causing an
assertion error to occur:
. = ASSERT(hdr == 0x1f1, "The setup header has the wrong offset!");
This does not happen with other linkers like ld.bfd.
We can see the difference by inspecting the generated .elf file:
ld.lld:
Section Headers:
[Nr] Name Type Addr Off Size
[ 1] .bstext PROGBITS 00000000 001000 0001ef
[ 2] .interp PROGBITS 000001ef 0011ef 000053
[ 3] .header PROGBITS 00000242 001242 00007d
ld.bfd:
Section Headers:
[Nr] Name Type Addr Off Size
[ 1] .bstext PROGBITS 00000000 001000 0001ef
[ 2] .header PROGBITS 000001ef 0011ef 00007d
[ 3] .entrytext PROGBITS 0000026c 00126c 000069
Adding .interp to the DISCARD section ensures it's not included in
the final .elf file.
Signed-off-by: Nam Le <lehoangnamtep@gmail.com>
---
arch/x86/boot/setup.ld | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/x86/boot/setup.ld b/arch/x86/boot/setup.ld
index e1d594a60204..daffd876e94d 100644
--- a/arch/x86/boot/setup.ld
+++ b/arch/x86/boot/setup.ld
@@ -61,6 +61,7 @@ SECTIONS
/DISCARD/ : {
*(.note*)
+ *(.interp)
}
/*
--
2.53.0
On Wed, Apr 08, 2026 at 12:39:57AM +0100, Nam Le wrote:
> With the --dynamic-linker flag added, either manually or via a
> toolchain wrapper, the ld.lld linker generates a .interp section at
> address 0x1f1 which is normally reserved for the hdr, causing an
> assertion error to occur:
>
> . = ASSERT(hdr == 0x1f1, "The setup header has the wrong offset!");
>
> This does not happen with other linkers like ld.bfd.
>
> We can see the difference by inspecting the generated .elf file:
>
> ld.lld:
> Section Headers:
> [Nr] Name Type Addr Off Size
> [ 1] .bstext PROGBITS 00000000 001000 0001ef
> [ 2] .interp PROGBITS 000001ef 0011ef 000053
> [ 3] .header PROGBITS 00000242 001242 00007d
>
> ld.bfd:
> Section Headers:
> [Nr] Name Type Addr Off Size
> [ 1] .bstext PROGBITS 00000000 001000 0001ef
> [ 2] .header PROGBITS 000001ef 0011ef 00007d
> [ 3] .entrytext PROGBITS 0000026c 00126c 000069
>
> Adding .interp to the DISCARD section ensures it's not included in
> the final .elf file.
>
> Signed-off-by: Nam Le <lehoangnamtep@gmail.com>
> ---
> arch/x86/boot/setup.ld | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/arch/x86/boot/setup.ld b/arch/x86/boot/setup.ld
> index e1d594a60204..daffd876e94d 100644
> --- a/arch/x86/boot/setup.ld
> +++ b/arch/x86/boot/setup.ld
> @@ -61,6 +61,7 @@ SECTIONS
>
> /DISCARD/ : {
> *(.note*)
> + *(.interp)
> }
>
> /*
Sounds to me like you're shooting yourself in the foot on purpose:
--dynamic-linker=value
Specify the dynamic linker to be used for a dynamically linked executable.
This is recorded in an ELF segment of type PT_INTERP.
So don't do that then.
:-)
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
On Wed, Apr 08, 2026 at 11:52:02AM +0200, Borislav Petkov wrote: > Sounds to me like you're shooting yourself in the foot on purpose: And no matter what this needs to add a comment there saying this is to work around, hrm, imperfections in LLVM! So that people who hit problems here later have something to start with. Segher
On Wed, Apr 08, 2026 at 04:58:08AM -0500, Segher Boessenkool wrote:
> On Wed, Apr 08, 2026 at 11:52:02AM +0200, Borislav Petkov wrote:
> > Sounds to me like you're shooting yourself in the foot on purpose:
>
> And no matter what this needs to add a comment there saying this is to
> work around, hrm, imperfections in LLVM! So that people who hit
> problems here later have something to start with.
Right, I see --dynamic-linker=file in ld.bfd too. Why isn't that one slapping
a section too?
:-)
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
Hello, On Wed, 8 Apr 2026, Borislav Petkov wrote: > On Wed, Apr 08, 2026 at 04:58:08AM -0500, Segher Boessenkool wrote: > > On Wed, Apr 08, 2026 at 11:52:02AM +0200, Borislav Petkov wrote: > > > Sounds to me like you're shooting yourself in the foot on purpose: > > > > And no matter what this needs to add a comment there saying this is to > > work around, hrm, imperfections in LLVM! So that people who hit > > problems here later have something to start with. > > Right, I see --dynamic-linker=file in ld.bfd too. Why isn't that one slapping > a section too? It does normally. (See any random executable file in /bin/) But section layout can and does differ between ld.bfd and ld.lld (and for bfd it depends on the linker script), so it's probably simply not getting in the way of your explicitely placed sections with ld.bfd. You might be interested in --no-dynamic-linker or -static, no idea what the current needs of the kernel vmlinux image are. Ciao, Michael.
On 08/04/2026 11:09, Borislav Petkov wrote: > On Wed, Apr 08, 2026 at 04:58:08AM -0500, Segher Boessenkool wrote: >> On Wed, Apr 08, 2026 at 11:52:02AM +0200, Borislav Petkov wrote: >>> Sounds to me like you're shooting yourself in the foot on purpose: >> >> And no matter what this needs to add a comment there saying this is to >> work around, hrm, imperfections in LLVM! So that people who hit >> problems here later have something to start with. > > Right, I see --dynamic-linker=file in ld.bfd too. Why isn't that one slapping > a section too? > > :-) > I am not sure why ld.bfd doesn't add the section in, but it seems the LLVM maintainers have no plans of making ld.lld behave the same as ld.bfd according to the comments made here: Link: https://github.com/llvm/llvm-project/issues/78873#issuecomment-1902794108 > Sounds to me like you're shooting yourself in the foot on purpose: > > --dynamic-linker=value > Specify the dynamic linker to be used for a dynamically linked executable. > This is recorded in an ELF segment of type PT_INTERP. > > So don't do that then. Normally I would never add this flag, but some package manager (specifically Nix) adds --dynamic-linker as a default when building any applications. Ideally this should be a fix on LLVM's side of things since its a pretty significant difference in behavior between ld.lld and ld.bfd, but for the meantime I believe this is a minimal enough change to fix the issue. > And no matter what this needs to add a comment there saying this is to > work around, hrm, imperfections in LLVM! So that people who hit > problems here later have something to start with. Thank you for the advice! Should I add a comment and submit a v2 patch for the change?
On Wed, Apr 08, 2026 at 01:01:24PM +0100, Nam Le wrote:
> Link: https://github.com/llvm/llvm-project/issues/78873#issuecomment-1902794108
From that page:
"I guess the only choice is patching the kernel then."
People better delete this thinking from their heads! The kernel doesn't mop up
for everyone else's silliness.
> Normally I would never add this flag, but some package manager (specifically
> Nix) adds --dynamic-linker as a default when building any applications.
> Ideally this should be a fix on LLVM's side of things since its a pretty
> significant difference in behavior between ld.lld and ld.bfd, but for the
> meantime I believe this is a minimal enough change to fix the issue.
I'd like for your commit message to explain why *exactly* your patch exists.
I.e., the Nix use case.
> Thank you for the advice! Should I add a comment and submit a v2 patch for
> the change?
Michael's suggestion of using --no-dynamic-linker makes more sense to me. We
usually protect ourselves this way from the toolchain - by turning off flags
explicitly.
Thx.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
On 08/04/2026 13:49, Borislav Petkov wrote: > On Wed, Apr 08, 2026 at 01:01:24PM +0100, Nam Le wrote: > >> Link: https://github.com/llvm/llvm-project/issues/78873#issuecomment-1902794108 > > From that page: > > "I guess the only choice is patching the kernel then." > > People better delete this thinking from their heads! The kernel doesn't mop up > for everyone else's silliness. > >> Normally I would never add this flag, but some package manager (specifically >> Nix) adds --dynamic-linker as a default when building any applications. >> Ideally this should be a fix on LLVM's side of things since its a pretty >> significant difference in behavior between ld.lld and ld.bfd, but for the >> meantime I believe this is a minimal enough change to fix the issue. > > I'd like for your commit message to explain why *exactly* your patch exists. > I.e., the Nix use case. > >> Thank you for the advice! Should I add a comment and submit a v2 patch for >> the change? > > Michael's suggestion of using --no-dynamic-linker makes more sense to me. We > usually protect ourselves this way from the toolchain - by turning off flags > explicitly. > > Thx. > I am hesitant on modifying the Makefile to add the --no-dynamic-linker flag since a previous kernel patch proposed this exact change but was rejected a while back: Link: https://lore.kernel.org/CAFP8O3Kqx-gdTBFn_hesWzd-6NCpGEz1=fMoJXuX+n4c7sp0Bw@mail.gmail.com/ Should I still go for the --no-dynamic-linker change regardless? Seems like progress on this issue has stalled on all ends (Nix, LLVM, and the kernel) ever since 2024, and I just happened to stumble on it again recently. I'd be happy to amend the commit message to include more context on the Nix use case.
On Wed, Apr 08, 2026 at 02:30:06PM +0100, Nam Le wrote:
> I am hesitant on modifying the Makefile to add the --no-dynamic-linker
> flag since a previous kernel patch proposed this exact change but was
> rejected a while back:
Ok, so how is Nix building kernels then?
It sounds like they have some local fix for building the kernel.
And if so, why does the upstream kernel care?
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
On 08/04/2026 16:21, Borislav Petkov wrote: > On Wed, Apr 08, 2026 at 02:30:06PM +0100, Nam Le wrote: >> I am hesitant on modifying the Makefile to add the --no-dynamic-linker >> flag since a previous kernel patch proposed this exact change but was >> rejected a while back: > > Ok, so how is Nix building kernels then? > > It sounds like they have some local fix for building the kernel. > I just double-checked and it seems Nix has a workaround to remove the --dynamic-linker flag before building the kernel. As I was hand-compiling the kernel rather than installing it from Nix, the workaround did not get applied. > And if so, why does the upstream kernel care? Regarding this, I just think the difference in behavior between ld.lld and ld.bfd is severe enough that handling this edge case is warranted. I am happy to leave this patch out though, or add something minimal like a conditional check to add --no-dynamic-linker if the linker is ld.lld.
On Wed, Apr 08, 2026 at 04:57:41PM +0100, Nam Le wrote:
> I just double-checked and it seems Nix has a workaround to remove the
> --dynamic-linker flag before building the kernel. As I was
> hand-compiling the kernel rather than installing it from Nix, the
> workaround did not get applied.
You could use their workaround to build the kernel on Nix. I don't see
a persuasive enough reason to care for this in the upstream kernel.
Thx.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
© 2016 - 2026 Red Hat, Inc.