Why MergeObjectFromObjects1 rule is needed?

MergeObjectFromObjects1 jam rule merge multiple object files (*.o) to one object files by using ld -r flag. This is quite irregular usage, why not use static library (*.a)? LLVM linker lld fails to merge object files with error “attempted static link of dynamic object”, so I hardcoded ld linker for MergeObjectFromObjects1 to build Haiku with clang/lld.

There are some differences in behavior between .a and .o files and how they are handled by the linker. But I don’t see anything that would be blocking us from doing that. Try it and see what happens, I guess?

No, you cannot do that, because static libraries only import the needed objects/symbols into the final library. Merged objects import all their symbols, which is obviously necessary in e.g. libroot, libbe, etc. where we need to export everything, not just whatever the start needs. It may not be done very often, but it is absolutely valid to use shared objects like this.

As for Clang, it does not have the right default flags for Haiku objects, ArchitectureRules adds them: https://xref.landonf.org/source/xref/haiku/build/jam/ArchitectureRules#50

I’ve successfully used lld to compile Haiku, so make sure those rules above are getting invoked.

This rules already included in https://github.com/haikuports/haikuports/pull/4813.

Well, as I said, I have successfully used lld to build Haiku (though the built Haiku crashed in runtime_loader when trying to start launch_daemon), so if you are getting errors, that patch seems not equivalent to the flags here.

The message itself (“attempted static link”) implies you are trying to statically link objects, not dynamically link them.

Did you build kernel with clang/lld too? Currently I am getting following errors when attempting to boot Haiku with EFI loader:

load kernel kernel_x86_64...
elf: rw already handled!
unhandled pheader type 0x6474e552
unhandled pheader type 0x6474e551
relocating kernel failed: ffffffff!

I think I had to build the kernel itself without lld, and maybe boot addons too, because strange issues like that would occur otherwise, yes.

I think that this can be fixed by adjusting Clang Haiku target. Currently lld produce program header entries that GNU ld do not produce:

readelf -l kernel_x86_64 

Elf file type is EXEC (Executable file)
Entry point 0xffffffff8006c710
There are 8 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0xffffffff80000040 0xffffffff80000040
                 0x00000000000001c0 0x00000000000001c0  R      0x8
  INTERP         0x0000000000000200 0xffffffff80000200 0xffffffff80000200
                 0x000000000000000a 0x000000000000000a  R      0x1
      [Requesting program interpreter: /dev/null]
  LOAD           0x0000000000000000 0xffffffff80000000 0xffffffff80000000
                 0x00000000001a8498 0x00000000001a8498  R E    0x1000
  LOAD           0x00000000001a9000 0xffffffff801a9000 0xffffffff801a9000
                 0x0000000000001bf8 0x0000000000001bf8  RW     0x1000
  LOAD           0x00000000001aac00 0xffffffff801aac00 0xffffffff801aac00
                 0x0000000000000000 0x000000000003c5e0  RW     0x1000
  DYNAMIC        0x00000000001aab38 0xffffffff801aab38 0xffffffff801aab38
                 0x00000000000000c0 0x00000000000000c0  RW     0x8
  GNU_RELRO      0x00000000001aa9c0 0xffffffff801aa9c0 0xffffffff801aa9c0
                 0x0000000000000238 0x0000000000001000  R      0x1
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x0

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp 
   02     .interp .hash .dynsym .dynstr .gnu.version .gnu.version_d .gnu.hash .text .rodata .altcodepatch 
   03     .data _haiku_revision .ctors .got .dynamic 
   04     .bss 
   05     .dynamic 
   06     .ctors .got .dynamic 
   07     

Regular Haiku kernel:

readelf -l kernel_x86_64 

Elf file type is EXEC (Executable file)
Entry point 0xffffffff80062980
There are 5 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0xffffffff80000040 0xffffffff80000040
                 0x0000000000000118 0x0000000000000118  R      0x8
  INTERP         0x0000000000000158 0xffffffff80000158 0xffffffff80000158
                 0x0000000000000009 0x0000000000000009  R      0x1
      [Requesting program interpreter: /foo/bar]
  LOAD           0x0000000000000000 0xffffffff80000000 0xffffffff80000000
                 0x00000000001b2480 0x00000000001b2480  R E    0x1000
  LOAD           0x00000000001b3000 0xffffffff801b3000 0xffffffff801b3000
                 0x00000000000020c0 0x000000000003ecc0  RW     0x1000
  DYNAMIC        0x00000000001b4fc0 0xffffffff801b4fc0 0xffffffff801b4fc0
                 0x0000000000000100 0x0000000000000100  RW     0x8

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp 
   02     .interp .hash .dynsym .dynstr .text .rodata .gnu.version_d .gnu.version .altcodepatch 
   03     .data _haiku_revision .ctors .dtors .dynamic .bss 
   04     .dynamic 

Relocation table is empty in both cases.

No, that’s not the issue, the “unrecognized pheader type…” is just a warning, I added that. The “relocating kernel failed” is the real problem; actually I don’t remember that error, so it may be related to your MergeObject and shared problems.

Currently I use GNU ld for MergeObjectFromObjects1 rule. Userland applications and libraries are working fine.

Did you mean this?

error mapping file data: Invalid Argument!
error starting "/boot/system/servers/launch_daemon" error = -1 

2 RW LOAD entries in program header table may be an issue.

No, I mean it completely seg-faulted and userland did not start at all. But perhaps that we due to some other problem which has since been resolved.

It seems that ELF loader of haiku_loader don’t support multiple LOAD segments with same type: https://git.haiku-os.org/haiku/tree/src/system/boot/loader/elf.cpp#n204. I can’t find lld option to disable multiple LOAD segments of same type, so ELF loader need to adjusted to support multiple LOAD segments of same type.

“attempted static link of dynamic object” error was caused by using HAIKU_LD_x86_64=clang at first attempts of compiling. After changing it to HAIKU_LD_x86_64=ld.lld, haiku.hpkg is compiled fine with clang/lld without GNU ld at all.

1 Like

I found lld flags that produce same segment layout as GNU ld: -Wl,--no-rosegment -Wl,-znorelro.

Possibly related https://dev.haiku-os.org/ticket/10198#comment:8

I used --no-rosegment -znorelro flags to kernel, kernel add-ons and runtime_loader and now kernel and kernel add-ons built with clang/lld successfully load and run, but runtime_loader still fail:

vm_soft_fault: va 0x7fe8400c2000 not covered by area in address space
vm_page_fault: vm_soft_fault returned error 'Bad address' on fault at 0x7fe8400c2ff8, ip 0x3dd5ed56b4, write 1, user 1, thread 0x11a
thread_hit_serious_debug_event(): Failed to install debugger: thread: 282: Bad port ID
error starting "/boot/system/servers/launch_daemon" error = -1 
1 Like

I tried to add panic call to vm_page_fault and get following output:

vm_soft_fault: va 0x7f8214849000 not covered by area in address space
vm_page_fault: vm_soft_fault returned error 'Bad address' on fault at 0x7f8214849ff8, ip 0xbc843ec6b4, write 1, user 1, thread 0x11a
PANIC: vm_page_fault: page fault in user space at 0x7f8214849ff8, ip 0xbc843ec6b4

Welcome to Kernel Debugging Land...
Thread 282 "launch_daemon" running on CPU 0
stack trace for thread 282 "launch_daemon"
    kernel stack: 0xffffffff820ed000 to 0xffffffff820f2000
      user stack: 0x00007f821484a000 to 0x00007f821584a000
frame                       caller             <image>:function + offset
 0 ffffffff820f1a38 (+  24) ffffffff8014709c   <kernel_x86_64> arch_debug_call_with_fault_handler + 0x16
 1 ffffffff820f1a50 (+ 176) ffffffff800b2c9c   <kernel_x86_64> kernel_debugger_internal(char const*, char const*, __va_list_tag*, int) + 0x38c
 2 ffffffff820f1b00 (+ 240) ffffffff800b3927   <kernel_x86_64> panic + 0xb7
 3 ffffffff820f1bf0 (+ 240) ffffffff8012d797   <kernel_x86_64> vm_page_fault + 0x117
 4 ffffffff820f1ce0 (+  64) ffffffff80151ccb   <kernel_x86_64> x86_page_fault_exception + 0x23b
 5 ffffffff820f1d20 (+ 536) ffffffff80148a1d   <kernel_x86_64> int_bottom_user + 0xb2
user iframe at 0xffffffff820f1f38 (end = 0xffffffff820f2000)
 rax 0x7290410b60          rbx 0x7290410b60          rcx 0x0
 rdx 0x4                   rsi 0x0                   rdi 0x7290410b60
 rbp 0x7f821484a000         r8 0x7f8215848d70         r9 0x7f8215848d70
 r10 0x6480                r11 0x7ff8                r12 0x729040ae98
 r13 0x13                  r14 0x7290407008          r15 0x3
 rip 0xbc843ec6b4          rsp 0x7f821484a000     rflags 0x13202
 vector: 0xe, error code: 0x6
 6 ffffffff820f1f38 (+140198779650248) 000000bc843ec6b4   </boot/system/runtime_loader@0x000000bc843cf000> <unknown> + 0x1d6b4
 7 00007f821484a000 (+  32) 000000bc843ec787   </boot/system/runtime_loader@0x000000bc843cf000> <unknown> + 0x1d787
 8 00007f821484a020 (+  32) 000000bc843ec787   </boot/system/runtime_loader@0x000000bc843cf000> <unknown> + 0x1d787
 9 00007f821484a040 (+  32) 000000bc843ec787   </boot/system/runtime_loader@0x000000bc843cf000> <unknown> + 0x1d787
10 00007f821484a060 (+  32) 000000bc843ec787   </boot/system/runtime_loader@0x000000bc843cf000> <unknown> + 0x1d787
11 00007f821484a080 (+  32) 000000bc843ec787   </boot/system/runtime_loader@0x000000bc843cf000> <unknown> + 0x1d787
12 00007f821484a0a0 (+  32) 000000bc843ec787   </boot/system/runtime_loader@0x000000bc843cf000> <unknown> + 0x1d787
13 00007f821484a0c0 (+  32) 000000bc843ec787   </boot/system/runtime_loader@0x000000bc843cf000> <unknown> + 0x1d787
14 00007f821484a0e0 (+  32) 000000bc843ec787   </boot/system/runtime_loader@0x000000bc843cf000> <unknown> + 0x1d787
15 00007f821484a100 (+  32) 000000bc843ec787   </boot/system/runtime_loader@0x000000bc843cf000> <unknown> + 0x1d787
16 00007f821484a120 (+  32) 000000bc843ec787   </boot/system/runtime_loader@0x000000bc843cf000> <unknown> + 0x1d787
17 00007f821484a140 (+  32) 000000bc843ec787   </boot/system/runtime_loader@0x000000bc843cf000> <unknown> + 0x1d787
18 00007f821484a160 (+  32) 000000bc843ec787   </boot/system/runtime_loader@0x000000bc843cf000> <unknown> + 0x1d787
19 00007f821484a180 (+  32) 000000bc843ec787   </boot/system/runtime_loader@0x000000bc843cf000> <unknown> + 0x1d787
20 00007f821484a1a0 (+  32) 000000bc843ec787   </boot/system/runtime_loader@0x000000bc843cf000> <unknown> + 0x1d787

Ending part infinitely repeats.

Yep, this is identical behavior to what I saw when I built Haiku with Clang + binutils ld. I didn’t manage to debut the “infinite repeat” any further.