1
1
mirror of https://github.com/rui314/mold.git synced 2024-11-20 20:37:49 +03:00
This commit is contained in:
Rui Ueyama 2024-09-17 13:46:27 +09:00
parent 1efbe3f141
commit f1739bffd0
3 changed files with 38 additions and 28 deletions

View File

@ -2432,6 +2432,8 @@ public:
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

View File

@ -2463,6 +2463,16 @@ void CopyrelSection<E>::add_symbol(Context<E> &ctx, Symbol<E> *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<E> &file = *(SharedFile<E> *)sym->file;

View File

@ -312,9 +312,9 @@ void resolve_symbols(Context<E> &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<E> *file) {
@ -336,25 +336,25 @@ void resolve_symbols(Context<E> &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 <typename E>
void do_lto(Context<E> &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<ObjectFile<E> *> 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 <typename E>
void sort_init_fini(Context<E> &ctx) {
Timer t(ctx, "sort_init_fini");
struct Entry {
InputSection<E> *sect;
i64 prio;
};
for (Chunk<E> *chunk : ctx.chunks) {
if (OutputSection<E> *osec = chunk->to_osec()) {
if (osec->name == ".init_array" || osec->name == ".preinit_array" ||
@ -1168,8 +1173,7 @@ void sort_init_fini(Context<E> &ctx) {
if (ctx.arg.shuffle_sections == SHUFFLE_SECTIONS_REVERSE)
std::reverse(osec->members.begin(), osec->members.end());
typedef std::pair<InputSection<E> *, i64> P;
std::vector<P> vec;
std::vector<Entry> vec;
for (InputSection<E> *isec : osec->members) {
std::string_view name = isec->name();
@ -1179,10 +1183,10 @@ void sort_init_fini(Context<E> &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 <typename E>
void sort_ctor_dtor(Context<E> &ctx) {
Timer t(ctx, "sort_ctor_dtor");
struct Entry {
InputSection<E> *sect;
i64 prio;
};
for (Chunk<E> *chunk : ctx.chunks) {
if (OutputSection<E> *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<InputSection<E> *, i64> P;
std::vector<P> vec;
std::vector<Entry> vec;
for (InputSection<E> *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<E> &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<E> *)sym->file)->is_readonly(sym))
ctx.copyrel_relro->add_symbol(ctx, sym);
else