diff --git a/elf/input-files.cc b/elf/input-files.cc index 4fd9fdb5c3..4d1a0aee21 100644 --- a/elf/input-files.cc +++ b/elf/input-files.cc @@ -1224,7 +1224,6 @@ void SharedFile::parse(Context &ctx) { this->symbol_strtab = this->get_string(ctx, symtab_sec->sh_link); soname = get_soname(ctx); - dt_needed = read_dt_needed(ctx); version_strings = read_verdef(ctx); // Read a symbol table. @@ -1267,16 +1266,13 @@ void SharedFile::parse(Context &ctx) { } template -std::vector SharedFile::read_dt_needed(Context &ctx) { - // Get the contents of a .dynamic seciton +std::vector SharedFile::get_dt_needed(Context &ctx) { + // Get the contents of the dynamic segment std::span> dynamic; - for (ElfPhdr &phdr : this->get_phdrs()) { - if (phdr.p_type == PT_DYNAMIC) { + for (ElfPhdr &phdr : this->get_phdrs()) + if (phdr.p_type == PT_DYNAMIC) dynamic = {(Word *)(this->mf->data + phdr.p_offset), phdr.p_memsz / sizeof(Word)}; - break; - } - } // Find a string table char *strtab = nullptr; diff --git a/elf/mold.h b/elf/mold.h index 36a40b7483..6556424183 100644 --- a/elf/mold.h +++ b/elf/mold.h @@ -1301,6 +1301,7 @@ class SharedFile : public InputFile { void resolve_symbols(Context &ctx) override; std::span *> get_symbols_at(Symbol *sym); i64 get_alignment(Symbol *sym); + std::vector get_dt_needed(Context &ctx); bool is_readonly(Symbol *sym); void mark_live_objects(Context &ctx, @@ -1311,7 +1312,6 @@ class SharedFile : public InputFile { std::string soname; std::vector version_strings; - std::vector dt_needed; std::vector> elf_syms2; private: diff --git a/elf/passes.cc b/elf/passes.cc index 2527631b26..e57f38279f 100644 --- a/elf/passes.cc +++ b/elf/passes.cc @@ -1094,22 +1094,6 @@ template void check_shlib_undefined(Context &ctx) { Timer t(ctx, "check_shlib_undefined"); - // Obtain a list of DSOs whose all DT_NEEDED files are known to us. - // If a DSO depends on an unknown library, that library may provide - // definitions for missing symbols, so we ignore such libraries. - std::vector *> dsos = ctx.dsos; - std::unordered_set sonames; - - for (SharedFile *file : dsos) - sonames.insert(file->soname); - - std::erase_if(dsos, [&](SharedFile *file) { - for (std::string_view needed : file->dt_needed) - if (sonames.count(needed) == 0) - return true; - return false; - }); - auto is_sparc_register = [](const ElfSym &esym) { // Dynamic symbol table for SPARC contains bogus entries which // we need to ignore @@ -1118,17 +1102,28 @@ void check_shlib_undefined(Context &ctx) { return false; }; - // Check if all undefined symbols have been resolved. - for (SharedFile *file : dsos) { + // Obtain a list of known shared library names. + std::unordered_set sonames; + for (SharedFile *file : ctx.dsos) + sonames.insert(file->soname); + + tbb::parallel_for_each(ctx.dsos, [&](SharedFile *file) { + // Skip the file if it depends on a file that we know nothing about. + // This is because missing symbols may be provided by that unknown file. + for (std::string_view needed : file->get_dt_needed(ctx)) + if (sonames.count(needed) == 0) + return; + + // Check if all undefined symbols have been resolved. for (i64 i = 0; i < file->elf_syms.size(); i++) { const ElfSym &esym = file->elf_syms[i]; Symbol &sym = *file->symbols[i]; - if (esym.is_undef() && !esym.is_weak() && !is_sparc_register(esym) && - !sym.file) + if (esym.is_undef() && !esym.is_weak() && !sym.file && + !is_sparc_register(esym)) Error(ctx) << *file << ": --no-allow-shlib-undefined: undefined symbol: " << sym; } - } + }); } template