Previously, if two or more VERSION clauses match to the same symbol,
the first one took precedence. This was incompatible with GNU ld, which
gives the last one the highesth priority.
This change inverted the priority so that the last one will take
precedence other the others.
Fixes https://github.com/rui314/mold/issues/1158
Using ftruncate() creates holes inside files, that on first (write) page
fault gets allocated an actual disk block. There are several
disadvantages with this:
- Allocating block one-by-one is slower than doing it all at once.
- As we write to the output in parallel the write order is not exactly
sequential. The allocated blocks can also be out-of-order and make the
on-disk representation fragmented.
Instead, use posix_fallocate() which allocates a contiguous on-disk block
(if possible). It's arguably a better fit for linker output, since holes
are unlikely to be present after writing all the output (any contiguous
zeroes should just go into .bss).
I benchmarked this by linking mold with debug symbols. On an 8-core
desktop, it is 5% (1.0s -> 0.95s) faster, but on a 64-core workstation it
is actually 40% slower (0.37s -> 0.52s). The total amount of System time
is reduced (6.7s -> 5.2s), however. I suspect that the reduced page fault
work ends up causing more lock contention.
Despite potential regression on high-core systems I still think this
change is justified because of the better on-disk layout.
Signed-off-by: Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
Previously, we always tried to demangle a symbol name as a Rust
symbol first and then attempted to demangle it as a C++ symbol.
This resulted in an incorrect demangled result, as the Rust legacy
mangling scheme is not distinguishable from C++.
This patch fix the issue by adding the "is_rust_obj" flag to the
ObjectFile. We try to demangle a symbol as a Rust one before as a C++
only if the flag is true.
Fixes https://github.com/rui314/mold/issues/1159
A `.eh_frame` section contains data for exception handling. Usually,
an object file contains only one `.eh_frame` section, which explains
how to handle exceptions for all text sections in the same object file.
However, it appears that, in rare cases, we need to handle object
files containing multiple `.eh_frame` sections. An example of this is
the `/usr/lib/clang/17/lib/x86_64-redhat-linux-gnu/clang_rt.crtbegin.o`
file, which is provided by the `compiler-rt` package of Fedora 39.
Specifically, I'm using the `quay.io/fedora/fedora:39` Docker image.
The file contains two `.eh_frame` sections.
One `.eh_frame` in the file is of type `STT_X86_64_UNWIND` and the
other is of `STT_PROGBITS`. It's possible that the file was created
with `ld -r`, and the linker failed to merge the two incoming
`.eh_frame` sections into one output section due to the difference in
section types.
We did not expect such inputs and consequently produced corrupted
output files.
This commit improves our linker so that mold can handle multiple
`.eh_frame` sections in a single object file.
Fixes https://github.com/rui314/mold/issues/1157
Previously, symbol names or wildcard patterns in version script files
were processed strictly from top to bottom. When a single symbol
matches two or more patterns, the first one was given precedence.
However, GNU ld appears to treat exact matches differently, assigning
them higher precedence over wildcard patterns. This discrepancy led to
programs linked with Qt 6.6.1 using mold failing to launch.
Fixes https://github.com/rui314/mold/issues/1158
It had been assumed that the TLSDESC code seqeunce looks like this:
lea 0(%rip), %rax
R_X86_64_GOTPC32_TLSDESC foo
call *(%rax)
R_X86_64_TLSDESC_CALL foo
However, LLVM seems to also emit something like this:
lea 0(%rip), %reg
R_X86_64_GOTPC32_TLSDESC foo
...
mov %reg, %rax
...
call *(%rax)
R_X86_64_TLSDESC_CALL foo
That means when we rewrite the LEA instruction to relax the code
sequence, we need to handle destination registers other than %rax.
The wrong assumption caused a program crash as reported as
https://bugs.gentoo.org/914849.