-
-
Notifications
You must be signed in to change notification settings - Fork 531
Description
There are two cases where I think the --no-allow-shlib-undefined option does not behave as intended.
I suspect the visibility of symbols from object files not to be considered properly.
The attached .sh shows the two cases, one where the option leads to an error where I think it shouldn't
and one where I think it should've raised an error but it doesn't.
Unpacking the most recent mold-2.40.4-x86_64-linux next to that script should make it runnable and it prints
my suspicions to the console.
build.sh
Hopefully my initial investigation can be helpful:
1. Symbol Resolution (src/input-files.cc, line 985)
void ObjectFile<E>::resolve_symbols(Context<E> &ctx) {
for (i64 i = this->first_global; i < this->elf_syms.size(); i++) {
// ...
if (get_rank(this, esym, !this->is_reachable) < get_rank(sym)) {
sym.file = this; // ← Sets sym.file WITHOUT checking visibility
// ...
}
}
}Key Point: sym.file is set based purely on symbol priority/rank. Visibility is NOT checked.
2. The Check (src/passes.cc, line 1162)
void check_shlib_undefined(Context<E> &ctx) {
// ...
tbb::parallel_for_each(ctx.dsos, [&](SharedFile<E> *file) {
for (i64 i = 0; i < file->elf_syms.size(); i++) {
const ElfSym<E> &esym = file->elf_syms[i];
Symbol<E> &sym = *file->symbols[i];
if (esym.is_undef() && !esym.is_weak() && !sym.file && // ← Checks existence of resolved-to file
!is_sparc_register(esym))
Error(ctx) << *file << ": --no-allow-shlib-undefined: undefined symbol: " << sym;
}
});
}3. DSO Hidden Symbol Handling (src/passes.cc, line 306)
template <typename E>
void resolve_symbols(Context<E> &ctx) {
// ...
// Special handling exists for hidden symbols from DSOs
tbb::parallel_for_each(ctx.dsos, [&](SharedFile<E> *file) {
if (file->is_reachable) {
for (Symbol<E> *sym : file->symbols) {
if (sym->file == file && sym->visibility == STV_HIDDEN) {
sym->skip_dso = true; // ← Only for DSO hidden symbols
redo = true;
}
}
}
});Key Point: This special handling applies only to DSOs, not object files.
I'm not 100% sure but this looks like hidden symbols from object files are never filtered because:
- Symbol resolution sets
sym.filewithout checking visibility - The undefined check only verifies
sym.fileexists - Special visibility handling exists only for DSO symbols
Result: Runtime undefined symbol error when the shared library tries to resolve references that were satisfied by
hidden object file symbols during linking.