It is not clearly defined when undefined weak symbols are resolved.
It looks like there are two possible approaches:
1. Promote all weak undefined symbols to dynamic ones so that they'll
have another chance to be resolved at load-time, or
2. Promote weak undefined symbols to dynamic ones only when there are
definitions in other DSOs at link-time.
(1) provides the maximum flexibility. For example, consider a main program
that has a weak undefined symbol `foo` and there's no DSO that defines it
at link-time. In (1), `foo` gets promoted to a dynamic symbol, so that one
of its depending DSO is upgraded to define `foo`, the main executable's
`foo` is resolved to that symbol at load-time. On the other hand, in (2),
`foo` would have already been converted to an absolute symbol at address
zero at link-time, so you need to rebuild the main executable to use the
new definition of `foo` in the shared library.
However, (1) is not compatible with copy relocations. This is because we
need to know the size of the symbol when creating a copy relocation, but
that information is not available unless we have a definition. It's also
not compatible with canonical PLTs because canonical PLTs have non-zero
addresses and therefore weak undefined symbols would always be resolved to
non-zero addresses.
As a workaround, GNU ld promotes weak undefs to dynamic symbols only when
they don't need copy relocations or canonical PLTs. In other words, weak
undef's behavior is different between -fPIC and -fno-PIC. In the former
case, they become dynamic symbols, and vice versa.
I don't think that workaround is a good one. So, mold took the second
approach.
There is, however, another thing to consider. What if we can find a
defined symbol in a DSO that is specified as `-as-needed`? Previously,
mold did not mark the library as "needed" and converted the weak undef
into an absolute symbol.
However, libstdc++ assumes that if weak undef symbol
`__pthread_key_create` is not resolved, it assumes that multi-threading is
not used in the executable, which resulted in a mis-detection with mold.
Therefore, this patch changes the mold's behavior so that it makes weak
undefs to keep DSOs "needed".
Fixes https://github.com/rui314/mold/issues/1286
Use $CXX instead of $CC to detect whether C++ programs could be built
statically. Add function test_cxxflags for convenience.
Fix test error in an environment where C++ programs cannot be built
statically, with error like:
mold: fatal: library not found: c++
Signed-off-by: Yao Zi <ziyao@disroot.org>
The interaction between these flags are unnecessarily complicated,
but it looks like `--undefined=ignore-in-object-files` needs to
share the same internal flag as `-z defs` so that they override
each other.
Fixes https://github.com/rui314/mold/issues/1270
Teaching the compiler that `buflen` cannot be negative and also doesn't
take a large value allows it to optimize code a little bit more than
it currently does.
I couldn't find any report that the reduced round version is broken
despite being used at a lot of places (e.g. Rust's hash table uses
SipHash-1-3). So I assume it's secure.