OSDev.org
https://forum.osdev.org/

[Solved] lld produces file with LMA=0 and no LOAD proghdr
https://forum.osdev.org/viewtopic.php?f=1&t=38284
Page 1 of 1

Author:  rooster [ Sun Dec 06, 2020 6:45 pm ]
Post subject:  [Solved] lld produces file with LMA=0 and no LOAD proghdr

I was tryna write a x86_64 kernel in Rust and the kernel I get has sections at LMA=VMA=0.
src/main.rs is very simple:
Code:
#![no_std]
#![no_main]
#![feature(global_asm)]

use core::panic::PanicInfo;

#[panic_handler]
fn on_panic(_info: &PanicInfo) -> ! {
   loop {}
}

global_asm!(r#"
.section ".mbhdr"
mb_header:
   .long 0xe85250d6
   .long 0
   .long mb_header_end - mb_header

   .long -(0xe85250d6 + 0 + (mb_header_end - mb_header))

   .short 0
   .short 0
   .long 8
mb_header_end:

.text
.globl start
.code32
start:
   movl $0x2f4b2f4f, 0xb8000
   hlt
"#);
JSON target config:
Code:
{
   "arch": "x86_64",
   "code-model": "kernel",
   "cpu": "x86-64",
   "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
   "disable-redzone": true,
   "eliminate-frame-pointer": false,

   "features": "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float",
   "is-builtin": true,

   "llvm-target": "x86_64-elf",
   "max-atomic-width": 64,

   "panic-strategy": "abort",

   "os": "none",
   "executables": true,
   "linker-flavor": "ld.lld",
   "linker": "rust-lld",
   "pre-link-args": {
      "ld.lld": ["-Tlinker.ld"]
   },
   "relocation-model": "static",


   "target-pointer-width": "64"
}
linker.ld
Code:
ENTRY(start)

SECTIONS {
   . = 1M;

   .boot :
   {
      *(.mbhdr)
   }

   .text :
   {
      *(.text)
   }

   /DISCARD/ :
   {
      *(.debug*)
   }
}
`cargo xbuild` produces an executable with LMA=0 and no LOAD program header
Code:
$ objdump -x target/x86_64_kernel/debug/rosd

target/x86_64_kernel/debug/rosd:     file format elf64-x86-64
target/x86_64_kernel/debug/rosd
architecture: i386:x86-64, flags 0x00000012:
EXEC_P, HAS_SYMS
start address 0x0000000000000030

Program Header:
   STACK off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**0
         filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .boot         00000018  0000000000000000  0000000000000000  000000e8  2**0
                  CONTENTS, READONLY
  1 .comment      00000013  0000000000000000  0000000000000000  00000100  2**0
                  CONTENTS, READONLY
  2 .text         0000000b  0000000000000030  0000000000000030  000001f0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
SYMBOL TABLE:
0000000000000000 l    df *ABS*   0000000000000000 2x5qyqlxdq6xy7n9
0000000000000000 l       .boot   0000000000000000 mb_header
0000000000000018 l       .boot   0000000000000000 mb_header_end
0000000000000030 g       .text   0000000000000000 start

I've tried rust bootloader project json target description, but got absolutely the same resulting binary. Is it LLD's fault?

Author:  iansjack [ Mon Dec 07, 2020 12:41 am ]
Post subject:  Re: [Rust] lld produces file with LMA=0 and no LOAD proghdr

If you've not already done so, I'd suggest that you read this blog: https://os.phil-opp.com/

Author:  xeyes [ Mon Dec 07, 2020 8:56 am ]
Post subject:  Re: [Rust] lld produces file with LMA=0 and no LOAD proghdr

It's always a huge pain to fight with the linker, a lot of times it is easier to manually copy code and fix up offsets on the fly.

Some general ideas to try (this is for the plain old ld though, not sure if applicable to the llvm one):

1. name your code input sections
Code:
.text.whatever
instead of plain
Code:
.whatever
, this can trigger some undocumented magical behaviors that usually results in more desirable outcome
2. specify memories and phdrs explicitly
3. use lots of AT(LMA)

good luck!

Author:  rooster [ Mon Dec 07, 2020 9:41 am ]
Post subject:  Re: [Rust] lld produces file with LMA=0 and no LOAD proghdr

iansjack wrote:
If you've not already done so, I'd suggest that you read this blog: https://os.phil-opp.com/
I've done so, but I don't get how this should solve my issue.

Author:  iansjack [ Mon Dec 07, 2020 10:54 am ]
Post subject:  Re: [Rust] lld produces file with LMA=0 and no LOAD proghdr

I only mention it because it produces a kernel that boots, so it might be a good starting point. In particular, take note of the requirement that the entry function be named "_start".

Author:  rooster [ Mon Dec 07, 2020 10:59 am ]
Post subject:  Re: [Rust] lld produces file with LMA=0 and no LOAD proghdr

iansjack wrote:
I only mention it because it produces a kernel that boots, so it might be a good starting point. In particular, take note of the requirement that the entry function be named "_start".
You can use any name for the entrypoint, as long as you specify it in the linker script.

Author:  linuxyne [ Mon Dec 07, 2020 11:13 am ]
Post subject:  Re: [Rust] lld produces file with LMA=0 and no LOAD proghdr

Tested with ld.lld, and saw a similar behaviour.

Try making .mbhdr allocatable:

Code:
.section ".mbhdr", "a"

Author:  rooster [ Mon Dec 07, 2020 11:35 am ]
Post subject:  Re: [Rust] lld produces file with LMA=0 and no LOAD proghdr

Now I have a LOAD program header and proper LMA, but .mbhdr section (and its content) disappeared from the executable:
Code:
user@host $ objdump -x target/x86_64_kernel/debug/rosd

target/x86_64_kernel/debug/rosd:     file format elf64-x86-64
target/x86_64_kernel/debug/rosd
architecture: i386:x86-64, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x0000000000100000

Program Header:
    LOAD off    0x0000000000001000 vaddr 0x0000000000100000 paddr 0x0000000000100000 align 2**12
         filesz 0x000000000000000b memsz 0x000000000000000b flags r-x
   STACK off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**0
         filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         0000000b  0000000000100000  0000000000100000  00001000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .comment      00000013  0000000000000000  0000000000000000  0000100b  2**0
                  CONTENTS, READONLY
SYMBOL TABLE:
0000000000000000 l    df *ABS*   0000000000000000 2x5qyqlxdq6xy7n9
0000000000100000 g       .text   0000000000000000 start

Code:
user@host $ objdump --disassemble-all -m i386 target/x86_64_kernel/debug/rosd

target/x86_64_kernel/debug/rosd:     file format elf64-x86-64


Disassembly of section .text:

0000000000100000 <start>:
  100000:   c7 05 00 80 0b 00 4f    movl   $0x2f4b2f4f,0xb8000
  100007:   2f 4b 2f
  10000a:   f4                      hlt   

Disassembly of section .comment:

0000000000000000 <.comment>:
   0:   4c                      dec    %esp
   1:   69 6e 6b 65 72 3a 20    imul   $0x203a7265,0x6b(%esi),%ebp
   8:   4c                      dec    %esp
   9:   4c                      dec    %esp
   a:   44                      inc    %esp
   b:   20 31                   and    %dh,(%ecx)
   d:   31 2e                   xor    %ebp,(%esi)
   f:   30 2e                   xor    %ch,(%esi)
  11:   30 00                   xor    %al,(%eax)

(And also .text now has file offset of 0x1000, which means if one move multiboot header to .text, GRUB won't find it that far).

Author:  linuxyne [ Mon Dec 07, 2020 12:04 pm ]
Post subject:  Re: [Rust] lld produces file with LMA=0 and no LOAD proghdr

You may want to test with ld.lld directly.

No idea why the linker dropped the mbhdr section; ld.lld on my machine didn't.

One can place mbhdr as shown in [1].

The 0x1000 offset is because ld page-aligned the sections. One can disable that by -n.

Following iansjack's comment, you may want to look at [2].




[1] https://wiki.osdev.org/Multiboot
[2] https://os.phil-opp.com/multiboot-kernel

Author:  rooster [ Mon Dec 07, 2020 12:54 pm ]
Post subject:  Re: [Rust] lld produces file with LMA=0 and no LOAD proghdr

linuxyne wrote:
Following iansjack's comment, you may want to look at [2].
I've already done a multiboot-bootable executable with nasm and ld. I wanted to do smth like in https://lowenware.com/blog/osdev/aarch6 ... m-in-rust/, but for x86_64 with GRUB2.

Author:  Octocontrabass [ Mon Dec 07, 2020 7:11 pm ]
Post subject:  Re: [Rust] lld produces file with LMA=0 and no LOAD proghdr

rooster wrote:
I wanted to do smth like in https://lowenware.com/blog/osdev/aarch6 ... m-in-rust/, but for x86_64 with GRUB2.

The author of that page notes that they had to put their assembly in a separate file to get their project to link correctly. Have you tried doing that?

Author:  rooster [ Mon Dec 07, 2020 7:17 pm ]
Post subject:  Re: [Rust] lld produces file with LMA=0 and no LOAD proghdr

Octocontrabass wrote:
rooster wrote:
I wanted to do smth like in https://lowenware.com/blog/osdev/aarch6 ... m-in-rust/, but for x86_64 with GRUB2.

The author of that page notes that they had to put their assembly in a separate file to get their project to link correctly. Have you tried doing that?
Could you plz cite the exact sentence(s)? Because what I've found is that the author tells they had to keep the panic handler in a separate file so that linker script is not ignored.
But in my case, linker script is definitely not ignored. I had a bunch of `.debug.xxx` sections before I started /DISCARD/ing them.

Author:  Octocontrabass [ Mon Dec 07, 2020 7:26 pm ]
Post subject:  Re: [Rust] lld produces file with LMA=0 and no LOAD proghdr

Whoops, my mistake - they are indeed talking about the panic handler.

But, have you tried putting the panic handler in a separate file anyway, just to see if it makes a difference?

Author:  rooster [ Tue Dec 08, 2020 1:14 am ]
Post subject:  Re: [Rust] lld produces file with LMA=0 and no LOAD proghdr

Solved by changing the linker to ld:
Code:
@@ -16,10 +16,10 @@

   "os": "none",
   "executables": true,
-   "linker-flavor": "ld.lld",
-   "linker": "rust-lld",
+   "linker-flavor": "ld",
+
   "pre-link-args": {
-      "ld.lld": ["-Tlinker.ld"]
+      "ld": ["-n", "-Tlinker.ld"]
   },
   "relocation-model": "static",
(Also, the multiboot header shall be aligned to 8 bytes).

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/