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
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.
This is a new experimental flag to make room at the end of PHDR
so that post-processing tools can add more entries as needed.
Fixes https://github.com/rui314/mold/issues/1148
--dynamic-list, --export-dynamic-symbol and --export-dynamic-symbol-list
have different semantics for executables and DSOs. If the output is an
executable, they specify a list of symbols that are to be exported.
If the output is a shared object, they specify the list of symbols that
are to be interposable.
mold havne't implemented the latter semantics. This commit fixes that
issue.
Fixes https://github.com/rui314/mold/issues/1071
.init_array/.fini_array haven't completely replace .ctors/.dtors, so
we need to convert .ctors/.dtors to .init_array/.fini_array.
Fixes https://github.com/rui314/mold/issues/1113
For --relocatable output, we need to pass through these attributes
for correctness. With this change, we'll have more .rodata sections
such as .rodata.str1.1, rodata.str1.4, etc. in the final executable,
but that should be fine because the runtime doesn't care about
section tables at all. The table isn't even loaded to memory at runtime.
IFUNC symbols are resolved at process startup by executing the function
that the symbol points to. This is used to select the "best" function at
runtime; for instance, the runtime may choose a faster version of memcpy
that uses SIMD instructions if they are available on the current system.
Thus, an IFUNC symbol has two addresses: the initial address (or the
resolver's address) and the resolved address, which is the return value of
the resolver.
In position-independent executables (PIEs), function pointers are loaded
from the GOT indirectly, and symbols are not directly referenced. In such
executables, the initial value of the GOT slot for an IFUNC symbol
contains the resolver address, and this is overwritten at runtime to the
resolved address upon process startup. When user code takes a pointer to
an IFUNC, it always reads the resolved address from GOT.
In contrast, position-dependent executables (PDEs) may have instructions
that directly refer to an IFUNC symbol, such as movabs on x86-64. The GOT
entry for an IFUNC holds the resolved address, so any direct reference
must also produce the resolved address to maintain pointer equality.
(C/C++ standards require that two pointers must be equal if and only if
they are taken for the same symbol.)
Previously, we emitted text relocations to modify instruction operands.
However, text relocations are undesirable and not always reliable. For
example, on ARM64, multiple instructions are used to materialize a
symbol's address, and it's not feasible to issue a dynamic relocation to
alter those instructions since the dynamic loader generally can only
modify 32-bit or 64-bit words.
In this commit, I have adopted a different strategy. An IFUNC symbol now
occupies two consecutive GOT slots in a PDE. The first slot holds the
symbol's PLT address, and the second slot holds the resolved address. The
PLT address is consistently used as the symbol's address throughout the
process, while the second slot is used only by the PLT entry to jump to
the resolved address.
This method ensures pointer equality without the need to emit text
relocations for IFUNC symbols in PDEs.
The test expects the output format given by `llvm-readelf`:
```
5: 0000000000010698 0 FUNC GLOBAL DEFAULT [VARIANT_PCS] 13 foo
```
However, in GNU's `readelf` implementation the symbol name comes first:
```
5: 0000000000010698 0 FUNC GLOBAL DEFAULT 13 foo [VARIANT_PCS]
```
Replace the regular expression with two `grep` calls piped together to
support both output formats.
Signed-off-by: Christoph Erhardt <github@sicherha.de>