[llvm-dev] Linking Linux kernel with LLD

Sean Silva via llvm-dev llvm-dev at lists.llvm.org
Wed Feb 8 16:54:15 PST 2017

On Wed, Feb 8, 2017 at 7:59 AM, George Rimar <grimar at accesssoftek.com>

> >I have just checked it, the startup.elf and realmode.elf are fine. Only
> few changes are required for mainline kernel and one >commit has to be
> reverted from lld and a few patches have to be applied.
> >
> >The only step when I have used BFD is linking vmlinux. I have manually
> set LD variable in vmlinux_link() function. The vmlinux >produced by lld
> doesn't work yet. I will compare it to the one produced by GNU ld and try
> to figure out what is wrong (maybe >you can suggest some useful objdump
> flags?)
> >
> >Regards,
> >Dmitry
> Just want to share latest results of investigation from my side.
> I traced kernel linked with LLD to find where it fails.
> LLD linked kernel starts execution and then I came up to
> protected_mode_jump​ function, which intention to jump to startup_64:
>     jmpl *%eax # Jump to the 32-bit entrypoint
> (https://github.com/torvalds/linux/blob/5924bbecd0267d87c24110cbe2041b
> 5075173a25/arch/x86/boot/pmjump.S#L76)
> (https://github.com/torvalds/linux/blob/5924bbecd0267d87c24110cbe2041b
> 5075173a25/arch/x86/kernel/head_64.S#L48)
> It does not happen. Code executes right before jmpl and then fail on this
> call for me, so startup_64 never called.

That address seems to come from here:

   (u32)&boot_params + (ds() << 4));

That boot_params.hdr.code32_start field is probably either invalid (bad
reloc or something else causing the bootloader to calculate the wrong
address) or valid but the thing it thinks it is pointing to wasn't loaded
(missing PT_LOAD etc.).

Btw, how did you narrow it down to that specific instruction? That's pretty

> startup_64 is a part of vmlinux binary. So as you said vmlinux has
> troubles and after doing readelf -a on LLD linked and bfd linked ones, I
> found that LLD outputs vmlinux as executable and bfd output is DSO. Had
> no chance to investigate why that happens, but pretty sure that is the not
> fine.

> Invocation line for us does not contain -shared:
> -m elf_x86_64
> --script home/umb/linux_kernel/linux/linux/arch/x86/boot/
> compressed/vmlinux.lds
> home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/head_64.o
> home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/misc.o
> home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/string.o
> home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/cmdline.o
> home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/error.o
> home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/piggy.o
> home/umb/linux_kernel/linux/linux/arch/x86/boot/compressed/cpuflags.o
> -o vmlinux

I think you can also get DSO with -pie I think, but I don't see that
either. This is quite mysterious. I also did a quick look at the linker
script and didn't see anything at first glance that would cause DSO output
(can linker scripts even control EType?). The bootloader might not even
look at the EType though.

-- Sean Silva

> George.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170208/762750e6/attachment.html>

More information about the llvm-dev mailing list