To process version scriots, we have to match glob patterns against
symbol strings. Sometimes, we have hundreds or thousands of glob
patterns and have to match them against millions of mangled long
C++ symbol names. This step can be very slow.
In this patch, I implemented the Aho-Corasick algorithm to match glob
patterns to symbol strings as quickly as possible. For the details
of the algorithm, see https://en.wikipedia.org/wiki/Glob_(programming).
This patch improves mold's performance for programs that uses large
version scripts. For example, linking libQt6Gui.so.6.3.0 reduced from
1.10s to 0.05s with this patch.
This patch also changes how symbol versions are applied if two or more
version patterns match to a single symbol string. Previously, the last
one in a script file took precedence. Now, the first one takes
precedence. I believe the new behavior is compatible with GNU ld.
Fixes https://github.com/rui314/mold/issues/156
Fixed https://github.com/rui314/mold/issues/287
Previously, we didn't handle version scripts like this correctly:
ver {
global: *;
local: foo*;
}
We didn't handle `local:` part correctly except for `*`.
Fixes https://github.com/rui314/mold/issues/277
.relr.dyn is a new section that has been implemented in other linkers
recently. That section contains only the RELATIVE-type dynamic
relocations (i.e. base relocations). Compared to the regular
.rela.dyn, a .relr.dyn's size is typically less than 1/10 because the
section is compressed.
Since PIEs (position-independent executables) tend to contain lots of
RELATIVE-type relocations and PIEs are now the default on many Linux
distributions for security reasons, .relr.dyn is more effective than
it was. It can reduce binary size by a few percent or more.
Note that the runtime support is catching up, so binaries built with
`-pack-dyn-relocs=relr` may not work on your system unless you are
running a very recent version of Linux.
gdb uses this field only if it is an executable. Having an extra
dynamic entry is usually harmless, but unfortunately, RPM's `rpmdeps`
tool uses the presence of this entry to distinguish executables from
shared object files. So, it is better not to create a DT_DEBUG entry
for shared object files.
Fixes https://github.com/rui314/mold/issues/254
That substring was introduced in de7ba9014f
to appease Gentoo's dev-libs/jansson-2.13.1-r1 package. But I think I
shouldn't done that from the beginning to avoid the sitaution of the
"User-Agent" string of the web browser, which everybody claims they
are Mozilla, AppleWebKit, Chrome and Safari simultaneously.
Previously, the `bnd jmp` instruction in a IBTPLT entry jumps to the
middle of an instruction due to an incorrect GOTPLT value. That happened
to work because a value that was there after the jump can be interpreted
as an `add` instruction and the control falled through the next `pushq`.
Previously, mold ignored common symbols in an archive when resolving
symbols. As a result, even if an undefined symbol could be resolved
using a common symbol in an archive, mold would end up with an undefined
symbol error.
This commit changes the behavior. Now, an undefined symbol is resolved
to a common symbol in an archive if exists.
Fixes https://github.com/rui314/mold/issues/256
The .ctors section contains a list of pointers that have to be run
before `main`. It usually contains pointers to global constructors.
The .dtors are for global destructors.
The .init_array and .fini_array serve the same purpose as .ctors and
.dtors. The former sections are newer than the latter sections, and
most programs have already migrated to .{init,fini}_array.
.ctors/.dtors are very similar to .{init,fini}_array, but the order
in which pointers are executed is different. .ctors/.dtors are executed
from the end to the beginning, while .{init,fini}_array are executed
from the beginning to the end.
Previously, we converted .ctors/.dtors sections into .{init,fini}_array
sections. In order to do that, we not only merge .ctors/.dtors to
.{init,fini}_array but also reverse their section contents, so that
the initialization order remains the same.
However, there was a bug in that logic. We forgot to reverse the
locations of dynamic relocations for the converted sections.
So, .ctors/.dtors sections converted to .{init,fini}_array were executed
in a wrong order.
We have two choices to "fix" the issue: (1) reverse not only section
contents but also dynamic relocations, or (2) stop converting .ctors/.dtors.
In this patch, I chose (2).
Since LLVM lld doesn't convert .ctors/.dtors, it shouldn't cause an
issue for most programs.
Previously, mold crashes due to an invalid regex pattern exception
when `[...]` is given as a version script pattern.
Fixes https://github.com/rui314/mold/issues/258
Previously, mold put all global symbols into .gnu.hash. Although I
believe it was not an error, it bloated the size of .gnu.hash because
.gnu.hash needs only exported symbols.
https://github.com/rui314/mold/issues/255
This is very hacky but highly practical, so I couldn't resist to not
implement this. We should support LTO natively in the future. In the
meantime, this feature should work as a poor-man's replacement.
Fixes https://github.com/rui314/mold/issues/242