OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Apr 18, 2024 1:28 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 14 posts ] 
Author Message
 Post subject: [Solved] lld produces file with LMA=0 and no LOAD proghdr
PostPosted: Sun Dec 06, 2020 6:45 pm 
Offline

Joined: Sun Dec 06, 2020 6:03 pm
Posts: 9
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?


Last edited by rooster on Tue Dec 08, 2020 1:14 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: [Rust] lld produces file with LMA=0 and no LOAD proghdr
PostPosted: Mon Dec 07, 2020 12:41 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4594
Location: Chichester, UK
If you've not already done so, I'd suggest that you read this blog: https://os.phil-opp.com/


Top
 Profile  
 
 Post subject: Re: [Rust] lld produces file with LMA=0 and no LOAD proghdr
PostPosted: Mon Dec 07, 2020 8:56 am 
Offline
Member
Member

Joined: Mon Dec 07, 2020 8:09 am
Posts: 212
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!


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

Joined: Sun Dec 06, 2020 6:03 pm
Posts: 9
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.


Top
 Profile  
 
 Post subject: Re: [Rust] lld produces file with LMA=0 and no LOAD proghdr
PostPosted: Mon Dec 07, 2020 10:54 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4594
Location: Chichester, UK
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".


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

Joined: Sun Dec 06, 2020 6:03 pm
Posts: 9
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.


Top
 Profile  
 
 Post subject: Re: [Rust] lld produces file with LMA=0 and no LOAD proghdr
PostPosted: Mon Dec 07, 2020 11:13 am 
Offline
Member
Member

Joined: Sat Jul 02, 2016 7:02 am
Posts: 210
Tested with ld.lld, and saw a similar behaviour.

Try making .mbhdr allocatable:

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


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

Joined: Sun Dec 06, 2020 6:03 pm
Posts: 9
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).


Top
 Profile  
 
 Post subject: Re: [Rust] lld produces file with LMA=0 and no LOAD proghdr
PostPosted: Mon Dec 07, 2020 12:04 pm 
Offline
Member
Member

Joined: Sat Jul 02, 2016 7:02 am
Posts: 210
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


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

Joined: Sun Dec 06, 2020 6:03 pm
Posts: 9
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.


Top
 Profile  
 
 Post subject: Re: [Rust] lld produces file with LMA=0 and no LOAD proghdr
PostPosted: Mon Dec 07, 2020 7:11 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5137
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?


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

Joined: Sun Dec 06, 2020 6:03 pm
Posts: 9
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.


Top
 Profile  
 
 Post subject: Re: [Rust] lld produces file with LMA=0 and no LOAD proghdr
PostPosted: Mon Dec 07, 2020 7:26 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5137
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?


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

Joined: Sun Dec 06, 2020 6:03 pm
Posts: 9
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).


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 128 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group