Linking Linux kernel with LLD

- D28094 (Implemented support for R_386_PC8/R_386_8 relocations)

Do you remember where it was used ?

setup.elf:
     ld.lld -m elf_i386 -T arch/x86/boot/setup.ld arch/x86/boot/a20.o arch/x86/boot/bioscall.o arch/x86/boot/cmdline.o arch/x86/boot/copy.o arch/x86/boot/cpu.o >arch/x86/boot/cpuflags.o arch/x86/boot/cpucheck.o arch/x86/boot/early_serial_console.o arch/x86/boot/edd.o arch/x86/boot/header.o arch/x86/boot/main.o >arch/x86/boot/mca.o arch/x86/boot/memory.o arch/x86/boot/pm.o arch/x86/boot/pmjump.o arch/x86/boot/printf.o arch/x86/boot/regs.o arch/x86/boot/string.o >arch/x86/boot/tty.o arch/x86/boot/video.o arch/x86/boot/video-mode.o arch/x86/boot/version.o arch/x86/boot/video-vga.o arch/x86/boot/video-vesa.o arch/x86/boot/video->bios.o -o arch/x86/boot/setup.elf
   ld.lld: error: do not know how to handle relocation 'R_386_PC8' (23)

Thanks, I'll take a look and probably resurrect that abandoned patch then.

I still didn't do anything with "Setup too big!" problem, just commented out the assert.

I did not get to that step yet, but just as a guess: you probably can try to add -N option for that place.

Tried booting the resulting bzImage and vmlinux with qemu. The bzImage only did reboot over and over, but the vmlinux did show an adorable picture (attached).

That is interesting information, thanks.
I am not familar with linux kernel, but testing with qemu helped a lot when we worked on booting freebsd loaders.
I hope to get to that step soon, after finishing with other already known issues.

George.

Thanks for merging the patches into upstream. Now there are only two left: D28094 and D28612.

just as a guess: you probably can try to add -N option for that place

The "-N" option (whatever it is) doesn't help. I can compare the object files produced by bfd, gold and lld.

I have attached my kernel config and kernel patch for upstream version. You can also examine my vmlinux and run it with

    qemu-system-x86_64 -kernel linux -append 'console=ttyS0' -serial stdio

Regards,
Dmitry

vmlinux (3.15 MB)

lld-support.patch (2.48 KB)

linux-config (23.5 KB)

Hi !

I am observing next issue when linking with WIP patches applied:

ld: warning: cannot find entry symbol _start; defaulting to 0x1000
  RELOCS arch/x86/realmode/rm/realmode.relocs
  OBJCOPY arch/x86/realmode/rm/realmode.bin
objcopy:arch/x86/realmode/rm/realmode.elf: Bad value
arch/x86/realmode/rm/Makefile:61: recipe for target 'arch/x86/realmode/rm/realmode.bin' failed
make[5]: *** [arch/x86/realmode/rm/realmode.bin] Error 1

It seems to be objcopy version specific.

With GNU objcopy (GNU Binutils for Ubuntu) 2.26.1 and GNU objcopy (GNU Binutils) 2.27 I have the same errors,
GNU objcopy (GNU Binutils) 2.17.50.20070806 produces output fine.

What version of binutils do you use ?

Also I am observing that we do not produce correct output for realmode.elf anyways.
It has next script:
(arch/x86/realmode/rm/realmode.lds.S)

.rodata : {
  *(.rodata)
  *(.rodata.*)
  . = ALIGN(16);
  video_cards = .;
  *(.videocards)
  video_cards_end = .;
}

But symbols video_cards == video_cards_end in LLD output (realmode.elf),
what does not seems to be correct.

So I believe realmode.elf, bin are broken, even if objcopy runs fine.

I am investigating it now.

George.

Hi!

I used objcopy from GNU Binutils 2.27 and I didn't have this error. Maybe it's something new, so I will build a new version of LLD and try to reproduce.

Sorry, I accidentally used "Reply" instead of "Reply all", so the message didn't get to the mailing list.

Regards,
Dmitry

I still didn't do anything with "Setup too big!" problem, just commented out the assert.

So I investigated this today.
(It is about linux/setup.ld at master · torvalds/linux · GitHub)

Script ends with:
.bss :
{
  __bss_start = .;
  *(.bss)
  __bss_end = .;
}
. = ALIGN(16);
_end = .;

/DISCARD/ : { *(.note*) }

. = ASSERT(_end <= 0x8000, "Setup too big!");

And what LLD do here. It makes command list to be:
Place .bss, Place non-allocated orphans, Assign _end.
So places command "_end = " after commands for orphan sections.
There are plenty of them: debug_*, .comment, .shstrtab, .symtab, .strtab.
And _end value is set to not what expected finally.

Fix on script side can be very easy, just add one more line before "/DISCARD/":
.debug_info : { *(.debug_info) }
That way LLD will attach that non-allocated orphans after .debug_info section.
And _end will be calculated earlier and be correct.

I just had a quick look about how to fix that. We have shouldSkip(const BaseCommand &Cmd) with comment:
// We don't want to go over alignments, since doing so in
// rx_sec : { *(rx_sec) }
// . = ALIGN(0x1000);
// /* The RW PT_LOAD starts here*/
// rw_sec : { *(rw_sec) }
// would mean that the RW PT_LOAD would become unaligned.

I think probably fix could be to allow go over alignments if we placing non-allocatable orphans,
them are placed the last and should not cause such issue to happen.

George.

I think probably fix could be to allow go over alignments if we placing non-allocatable orphans,
them are placed the last and should not cause such issue to happen.

George.

That will not work so simple. I'll take another look.

George.