diff --git a/src/mold.h b/src/mold.h index b49806d038..a4a3bab2d8 100644 --- a/src/mold.h +++ b/src/mold.h @@ -2432,6 +2432,8 @@ class Symbol { bool has_copyrel : 1 = false; bool is_copyrel_readonly : 1 = false; + // For symbol resolution. This flag is used rarely. See a comment in + // resolve_symbols(). bool skip_dso : 1 = false; // For --gc-sections diff --git a/src/output-chunks.cc b/src/output-chunks.cc index 7450465485..95c111619c 100644 --- a/src/output-chunks.cc +++ b/src/output-chunks.cc @@ -2463,6 +2463,16 @@ void CopyrelSection::add_symbol(Context &ctx, Symbol *sym) { assert(!ctx.arg.shared); assert(sym->file->is_dso); + if (sym->esym().st_visibility == STV_PROTECTED) + Error(ctx) << *sym->file + << ": cannot create a copy relocation for protected symbol '" + << *sym << "'; recompile with -fPIC"; + + if (!ctx.arg.z_copyreloc) + Error(ctx) << "-z nocopyreloc: " << *sym->file + << ": cannot create a copy relocation for symbol '" << *sym + << "'; recompile with -fPIC"; + symbols.push_back(sym); SharedFile &file = *(SharedFile *)sym->file; diff --git a/src/passes.cc b/src/passes.cc index 4e5f59b4d6..6e54841b37 100644 --- a/src/passes.cc +++ b/src/passes.cc @@ -312,9 +312,9 @@ void resolve_symbols(Context &ctx) { }); // Symbols with hidden visibility need to be resolved within the - // output file. If as a result of symbol resolution, a hidden symbol - // was resolved to a DSO, we'll redo symbol resolution from scratch - // with the flag to skip that symbol next time. This should be rare. + // output file. If a hidden symbol was resolved to a DSO, we'll redo + // symbol resolution from scratch with the flag to skip that symbol + // next time. This should be rare. std::atomic_bool flag = false; tbb::parallel_for_each(ctx.dsos, [&](SharedFile *file) { @@ -336,25 +336,25 @@ void resolve_symbols(Context &ctx) { } } +// Do link-time optimization. We pass all IR object files to the compiler +// backend to compile them into a few ELF object files. template void do_lto(Context &ctx) { Timer t(ctx, "do_lto"); - // Do link-time optimization. We pass all IR object files to the - // compiler backend to compile them into a few ELF object files. - // - // The compiler backend needs to know how symbols are resolved, - // so compute symbol visibility, import/export bits, etc early. + // The compiler backend needs to know how symbols are resolved, so + // compute symbol visibility, import/export bits, etc early. mark_live_objects(ctx); apply_version_script(ctx); parse_symbol_version(ctx); compute_import_export(ctx); - // Do LTO. It compiles IR object files into a few big ELF files. + // Invoke the LTO plugin. This step compiles IR object files into a few + // big ELF files. std::vector *> lto_objs = run_lto_plugin(ctx); append(ctx.objs, lto_objs); - // Redo name resolution from scratch. + // Redo name resolution. clear_symbols(ctx); // Remove IR object files. @@ -1161,6 +1161,11 @@ template void sort_init_fini(Context &ctx) { Timer t(ctx, "sort_init_fini"); + struct Entry { + InputSection *sect; + i64 prio; + }; + for (Chunk *chunk : ctx.chunks) { if (OutputSection *osec = chunk->to_osec()) { if (osec->name == ".init_array" || osec->name == ".preinit_array" || @@ -1168,8 +1173,7 @@ void sort_init_fini(Context &ctx) { if (ctx.arg.shuffle_sections == SHUFFLE_SECTIONS_REVERSE) std::reverse(osec->members.begin(), osec->members.end()); - typedef std::pair *, i64> P; - std::vector

vec; + std::vector vec; for (InputSection *isec : osec->members) { std::string_view name = isec->name(); @@ -1179,10 +1183,10 @@ void sort_init_fini(Context &ctx) { vec.emplace_back(isec, get_init_fini_priority(isec)); } - sort(vec, [&](const P &a, const P &b) { return a.second < b.second; }); + sort(vec, [&](const Entry &a, const Entry &b) { return a.prio < b.prio; }); for (i64 i = 0; i < vec.size(); i++) - osec->members[i] = vec[i].first; + osec->members[i] = vec[i].sect; } } } @@ -1192,22 +1196,25 @@ template void sort_ctor_dtor(Context &ctx) { Timer t(ctx, "sort_ctor_dtor"); + struct Entry { + InputSection *sect; + i64 prio; + }; + for (Chunk *chunk : ctx.chunks) { if (OutputSection *osec = chunk->to_osec()) { if (osec->name == ".ctors" || osec->name == ".dtors") { if (ctx.arg.shuffle_sections != SHUFFLE_SECTIONS_REVERSE) std::reverse(osec->members.begin(), osec->members.end()); - typedef std::pair *, i64> P; - std::vector

vec; - + std::vector vec; for (InputSection *isec : osec->members) vec.emplace_back(isec, get_ctor_dtor_priority(isec)); - sort(vec, [&](const P &a, const P &b) { return a.second < b.second; }); + sort(vec, [&](const Entry &a, const Entry &b) { return a.prio < b.prio; }); for (i64 i = 0; i < vec.size(); i++) - osec->members[i] = vec[i].first; + osec->members[i] = vec[i].sect; } } } @@ -1513,15 +1520,6 @@ void scan_relocations(Context &ctx) { ctx.got->add_tlsdesc_symbol(ctx, sym); if (sym->flags & NEEDS_COPYREL) { - if (sym->esym().st_visibility == STV_PROTECTED) - Error(ctx) << *sym->file - << ": cannot create a copy relocation for protected symbol '" - << *sym << "'; recompile with -fPIC"; - if (!ctx.arg.z_copyreloc) - Error(ctx) << "-z nocopyreloc: " << *sym->file - << ": cannot create a copy relocation for symbol '" << *sym - << "'; recompile with -fPIC"; - if (ctx.arg.z_relro && ((SharedFile *)sym->file)->is_readonly(sym)) ctx.copyrel_relro->add_symbol(ctx, sym); else