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 clang: add lld support for Haiku target [WIP] by X547 · Pull Request #4813 · haikuports/haikuports · GitHub.
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: elf.cpp « loader « boot « system « src - haiku - Haiku's main repository. 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.
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
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.