LLD not emiting sections correctly

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

LLD not emiting sections correctly

Post by nexos »

Hello,
I am currently working on a kernel that can be built with both a GNU build system and an LLVM system. It currently works with GNU, but not LLVM. Here is my linker script

Code: Select all

ENTRY(_start)

SECTIONS 
{
    . = 0x100000;
    .stivale2hdr : {
        *(.stivale2hdr)
    }
    .text : ALIGN(4096) {
        KEEP(*(.text*))
    }
    .data : ALIGN(4096) {
        KEEP(*(.data*))
    }
    .rodata : ALIGN(4096) {
        KEEP(*(.rodata*))
    }
    .bss : ALIGN(4096) {
        KEEP(*(COMMON))
        KEEP(*(.bss*))
    }
    /DISCARD/ : { 
        *(.comment) 
        *(.gnu*) 
        *(.note*)
        *(.interp)
        *(.dynsym)
        *(.dynstr)
        *(.dynamic)
        *(.eh_frame*) 
    }
    _end = .;
}
And here is my bootstrap code

Code: Select all

// start-i386-mb2.s  - contains start code for Multiboot 2 on i386
// Distributed with NexNix, licensed under the MIT license
// See LICENSE

.section .stivale2hdr
.align 8
header_start:
    .quad 0                 // Use ELF header entry
    .long stack_top         // Stack address
    .long 0
    .quad 0                 // Flags
    .long framebuffer_tag   // Pointer to tags
    .long 0

// Start of nexldr

.section .text
.global _start
_start:
    cli
    hlt

.section .data
framebuffer_tag:
    .quad 0x3ecc1bc43d0f7971    // Framebuffer tag
    .quad 0                     // Only tag in list
    .word 0                     // Let bootloader pick values
    .word 0
    .word 0

.section .bss
.align 16
stack:
    .skip 8192
stack_top:
And yet it appears that LLD is ignoring the . = 0x100000; line and offseting everything to 0.
But if I move the .stivale2hdr section after the .text section, .text get placed at the correct address, but everything else is offset from 0!
And here is my readelf output
https://gist.github.com/nexos-dev/a0797 ... 89e749f3c5

EDIT: I just looked at it again, and it is making a shared library! Why is that? My linker line is

Code: Select all

clang --target=i386-elf -fuse-ld=lld -nostdlib -Tarch/x86/i386-stivale2-link.ld arch/x86/start-i386-stivale2.o   -o nldr,
Thanks,
nexos
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: LLD not emiting sections correctly

Post by bzt »

nexos wrote:Hello,
I am currently working on a kernel that can be built with both a GNU build system and an LLVM system. It currently works with GNU, but not LLVM.
I also had problems with the LLVM lld and address calculation in the linker scripts. I've managed to create a workaround that works for both GNU ld and LLVM lld by using the SEGMENT_START macro and placing the section at "." (watch the second line below carefully, there's an extra "." before the colon). I don't know if that matters, but I also always use a PHDRS block in the linker scripts.

Code: Select all

    . = SEGMENT_START("text-segment", LOAD_ADDRESS) + SIZEOF_HEADERS;
    .text . : {
Hopefully this helps.

You could also try

Code: Select all

    . = 0x100000;
    .text : ALIGN(4096) {
        KEEP(*(.stivale2hdr))
        *(.text*)
    }
(There's not much point in using KEEP if you only have one block in the section definition. It tells the linker not to reorder those parts within the section when there are more. So in this example above it makes sense as the section has two definitons it's used to keep ".stivale2hdr" at the beginning of the text section)

Cheers,
bzt
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: LLD not emiting sections correctly

Post by nexos »

Unfortunately, the workaround didn't work. The second option won't work, as my kernel boots with Multiboot2 and Stivale2 (the boot protocol of Limine), and stivale2 requires the header in its own section. I guess I won't allow compiling with LLVM when using Stivale2 :( .
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: LLD not emiting sections correctly

Post by bzt »

nexos wrote:Unfortunately, the workaround didn't work. The second option won't work, as my kernel boots with Multiboot2 and Stivale2 (the boot protocol of Limine), and stivale2 requires the header in its own section. I guess I won't allow compiling with LLVM when using Stivale2 :( .
Ah, I see. Does the workaround work if you specify a PHDRS block in which you put both the stivale2 and text section into the same segment? It should, but this is just a well educated guess.

Cheers,
bzt
linuxyne
Member
Member
Posts: 211
Joined: Sat Jul 02, 2016 7:02 am

Re: LLD not emiting sections correctly

Post by linuxyne »

Does marking stivale2hdr as allocatable make any difference in the situation?

Code: Select all

.section .stivale2hdr, "a"
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: LLD not emiting sections correctly

Post by nexos »

linuxyne wrote:Does marking stivale2hdr as allocatable make any difference in the situation?

Code: Select all

.section .stivale2hdr, "a"
That fixed it! Thanks!
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
Post Reply