1
1
mirror of https://github.com/rui314/mold.git synced 2024-11-14 07:18:42 +03:00
This commit is contained in:
Rui Ueyama 2021-04-06 14:36:31 +09:00
parent 32ca7046cf
commit d03e4c9a17
7 changed files with 52 additions and 48 deletions

View File

@ -90,8 +90,8 @@ collect_root_set(Context<E> &ctx) {
// Add sections that are not subject to garbage collection. // Add sections that are not subject to garbage collection.
tbb::parallel_for_each(ctx.objs, [&](ObjectFile<E> *file) { tbb::parallel_for_each(ctx.objs, [&](ObjectFile<E> *file) {
for (InputSection<E> *isec : file->sections) { for (std::unique_ptr<InputSection<E>> &isec : file->sections) {
if (!isec) if (!isec || !isec->is_alive)
continue; continue;
// -gc-sections discards only SHF_ALLOC sections. If you want to // -gc-sections discards only SHF_ALLOC sections. If you want to
@ -102,7 +102,7 @@ collect_root_set(Context<E> &ctx) {
isec->is_visited = true; isec->is_visited = true;
if (is_init_fini(*isec) || isec->shdr.sh_type == SHT_NOTE) if (is_init_fini(*isec) || isec->shdr.sh_type == SHT_NOTE)
enqueue_section(isec); enqueue_section(isec.get());
} }
}); });
@ -150,7 +150,7 @@ static void sweep(Context<E> &ctx) {
tbb::parallel_for_each(ctx.objs, [&](ObjectFile<E> *file) { tbb::parallel_for_each(ctx.objs, [&](ObjectFile<E> *file) {
for (i64 i = 0; i < file->sections.size(); i++) { for (i64 i = 0; i < file->sections.size(); i++) {
InputSection<E> *isec = file->sections[i]; std::unique_ptr<InputSection<E>> &isec = file->sections[i];
if (isec && isec->is_alive && !isec->is_visited) { if (isec && isec->is_alive && !isec->is_visited) {
if (ctx.arg.print_gc_sections) if (ctx.arg.print_gc_sections)

34
icf.cc
View File

@ -184,8 +184,8 @@ static void merge_leaf_nodes(Context<E> &ctx) {
LeafHasher<E>, LeafEq<E>> map; LeafHasher<E>, LeafEq<E>> map;
tbb::parallel_for((i64)0, (i64)ctx.objs.size(), [&](i64 i) { tbb::parallel_for((i64)0, (i64)ctx.objs.size(), [&](i64 i) {
for (InputSection<E> *isec : ctx.objs[i]->sections) { for (std::unique_ptr<InputSection<E>> &isec : ctx.objs[i]->sections) {
if (!isec) if (!isec || !isec->is_alive)
continue; continue;
if (!is_eligible(*isec)) { if (!is_eligible(*isec)) {
@ -196,9 +196,9 @@ static void merge_leaf_nodes(Context<E> &ctx) {
if (is_leaf(ctx, *isec)) { if (is_leaf(ctx, *isec)) {
leaf++; leaf++;
isec->icf_leaf = true; isec->icf_leaf = true;
auto [it, inserted] = map.insert({isec, isec}); auto [it, inserted] = map.insert({isec.get(), isec.get()});
if (!inserted && isec->get_priority() < it->second->get_priority()) if (!inserted && isec->get_priority() < it->second->get_priority())
it->second = isec; it->second = isec.get();
} else { } else {
eligible++; eligible++;
isec->icf_eligible = true; isec->icf_eligible = true;
@ -207,9 +207,9 @@ static void merge_leaf_nodes(Context<E> &ctx) {
}); });
tbb::parallel_for((i64)0, (i64)ctx.objs.size(), [&](i64 i) { tbb::parallel_for((i64)0, (i64)ctx.objs.size(), [&](i64 i) {
for (InputSection<E> *isec : ctx.objs[i]->sections) { for (std::unique_ptr<InputSection<E>> &isec : ctx.objs[i]->sections) {
if (isec && isec->icf_leaf) { if (isec && isec->is_alive && isec->icf_leaf) {
auto it = map.find(isec); auto it = map.find(isec.get());
assert(it != map.end()); assert(it != map.end());
isec->leader = it->second; isec->leader = it->second;
} }
@ -307,8 +307,8 @@ static std::vector<InputSection<E> *> gather_sections(Context<E> &ctx) {
std::vector<i64> num_sections(ctx.objs.size()); std::vector<i64> num_sections(ctx.objs.size());
tbb::parallel_for((i64)0, (i64)ctx.objs.size(), [&](i64 i) { tbb::parallel_for((i64)0, (i64)ctx.objs.size(), [&](i64 i) {
for (InputSection<E> *isec : ctx.objs[i]->sections) for (std::unique_ptr<InputSection<E>> &isec : ctx.objs[i]->sections)
if (isec && isec->icf_eligible) if (isec && isec->is_alive && isec->icf_eligible)
num_sections[i]++; num_sections[i]++;
}); });
@ -322,9 +322,9 @@ static std::vector<InputSection<E> *> gather_sections(Context<E> &ctx) {
// Fill `sections` contents. // Fill `sections` contents.
tbb::parallel_for((i64)0, (i64)ctx.objs.size(), [&](i64 i) { tbb::parallel_for((i64)0, (i64)ctx.objs.size(), [&](i64 i) {
i64 idx = section_indices[i]; i64 idx = section_indices[i];
for (InputSection<E> *isec : ctx.objs[i]->sections) for (std::unique_ptr<InputSection<E>> &isec : ctx.objs[i]->sections)
if (isec && isec->icf_eligible) if (isec && isec->is_alive && isec->icf_eligible)
sections[idx++] = isec; sections[idx++] = isec.get();
}); });
tbb::parallel_for((i64)0, (i64)sections.size(), [&](i64 i) { tbb::parallel_for((i64)0, (i64)sections.size(), [&](i64 i) {
@ -444,12 +444,12 @@ static void print_icf_sections(Context<E> &ctx) {
tbb::concurrent_unordered_multimap<InputSection<E> *, InputSection<E> *> map; tbb::concurrent_unordered_multimap<InputSection<E> *, InputSection<E> *> map;
tbb::parallel_for_each(ctx.objs, [&](ObjectFile<E> *file) { tbb::parallel_for_each(ctx.objs, [&](ObjectFile<E> *file) {
for (InputSection<E> *isec : file->sections) { for (std::unique_ptr<InputSection<E>> &isec : file->sections) {
if (isec && isec->leader) { if (isec && isec->is_alive && isec->leader) {
if (isec == isec->leader) if (isec.get() == isec->leader)
leaders.push_back(isec); leaders.push_back(isec.get());
else else
map.insert({isec->leader, isec}); map.insert({isec->leader, isec.get()});
} }
} }
}); });

View File

@ -139,7 +139,6 @@ void InputSection<E>::kill() {
is_alive = false; is_alive = false;
for (FdeRecord<E> &fde : fdes) for (FdeRecord<E> &fde : fdes)
fde.is_alive = false; fde.is_alive = false;
file.sections[section_idx] = nullptr;
} }
} }

View File

@ -219,7 +219,7 @@ static void show_stats(Context<E> &ctx) {
static Counter undefined("undefined_syms"); static Counter undefined("undefined_syms");
undefined += obj->symbols.size() - obj->first_global; undefined += obj->symbols.size() - obj->first_global;
for (InputSection<E> *sec : obj->sections) { for (std::unique_ptr<InputSection<E>> &sec : obj->sections) {
if (!sec || !sec->is_alive) if (!sec || !sec->is_alive)
continue; continue;

4
mold.h
View File

@ -862,7 +862,7 @@ public:
inline std::span<Symbol<E> *> get_global_syms(); inline std::span<Symbol<E> *> get_global_syms();
std::string archive_name; std::string archive_name;
std::vector<InputSection<E> *> sections; std::vector<std::unique_ptr<InputSection<E>>> sections;
std::span<ElfSym<E>> elf_syms; std::span<ElfSym<E>> elf_syms;
i64 first_global = 0; i64 first_global = 0;
const bool is_in_lib = false; const bool is_in_lib = false;
@ -1830,7 +1830,7 @@ inline i64 ObjectFile<E>::get_shndx(const ElfSym<E> &esym) {
template <typename E> template <typename E>
inline InputSection<E> *ObjectFile<E>::get_section(const ElfSym<E> &esym) { inline InputSection<E> *ObjectFile<E>::get_section(const ElfSym<E> &esym) {
return sections[get_shndx(esym)]; return sections[get_shndx(esym)].get();
} }
template <typename E> template <typename E>

View File

@ -175,7 +175,8 @@ void ObjectFile<E>::initialize_sections(Context<E> &ctx) {
is_debug_section(shdr, name)) is_debug_section(shdr, name))
continue; continue;
this->sections[i] = new InputSection(ctx, *this, shdr, name, i); this->sections[i] =
std::make_unique<InputSection<E>>(ctx, *this, shdr, name, i);
static Counter counter("regular_sections"); static Counter counter("regular_sections");
counter++; counter++;
@ -194,7 +195,7 @@ void ObjectFile<E>::initialize_sections(Context<E> &ctx) {
Fatal(ctx) << *this << ": invalid relocated section index: " Fatal(ctx) << *this << ": invalid relocated section index: "
<< (u32)shdr.sh_info; << (u32)shdr.sh_info;
if (InputSection<E> *target = sections[shdr.sh_info]) { if (std::unique_ptr<InputSection<E>> &target = sections[shdr.sh_info]) {
assert(target->relsec_idx == -1); assert(target->relsec_idx == -1);
target->relsec_idx = i; target->relsec_idx = i;
@ -209,11 +210,11 @@ void ObjectFile<E>::initialize_sections(Context<E> &ctx) {
template <typename E> template <typename E>
void ObjectFile<E>::initialize_ehframe_sections(Context<E> &ctx) { void ObjectFile<E>::initialize_ehframe_sections(Context<E> &ctx) {
for (i64 i = 0; i < sections.size(); i++) { for (i64 i = 0; i < sections.size(); i++) {
InputSection<E> *isec = sections[i]; std::unique_ptr<InputSection<E>> &isec = sections[i];
if (isec && isec->name == ".eh_frame") { if (isec && isec->is_alive && isec->name == ".eh_frame") {
read_ehframe(ctx, *isec); read_ehframe(ctx, *isec);
isec->is_ehframe = true; isec->is_ehframe = true;
sections[i] = nullptr; isec->is_alive = false;
} }
} }
} }
@ -535,17 +536,16 @@ void ObjectFile<E>::initialize_mergeable_sections(Context<E> &ctx) {
std::vector<MergeableSection<E>> mergeable_sections(sections.size()); std::vector<MergeableSection<E>> mergeable_sections(sections.size());
for (i64 i = 0; i < sections.size(); i++) { for (i64 i = 0; i < sections.size(); i++) {
if (InputSection<E> *isec = sections[i]) { std::unique_ptr<InputSection<E>> &isec = sections[i];
if (isec->shdr.sh_flags & SHF_MERGE) { if (isec && isec->is_alive && (isec->shdr.sh_flags & SHF_MERGE)) {
mergeable_sections[i] = split_section(ctx, *isec); mergeable_sections[i] = split_section(ctx, *isec);
sections[i] = nullptr; isec->is_alive = false;
}
} }
} }
// Initialize rel_fragments // Initialize rel_fragments
for (InputSection<E> *isec : sections) { for (std::unique_ptr<InputSection<E>> &isec : sections) {
if (!isec) if (!isec || !isec->is_alive)
continue; continue;
std::span<ElfRel<E>> rels = isec->get_rels(ctx); std::span<ElfRel<E>> rels = isec->get_rels(ctx);
@ -872,8 +872,8 @@ void ObjectFile<E>::claim_unresolved_symbols() {
template <typename E> template <typename E>
void ObjectFile<E>::scan_relocations(Context<E> &ctx) { void ObjectFile<E>::scan_relocations(Context<E> &ctx) {
// Scan relocations against seciton contents // Scan relocations against seciton contents
for (InputSection<E> *isec : sections) for (std::unique_ptr<InputSection<E>> &isec : sections)
if (isec && (isec->shdr.sh_flags & SHF_ALLOC)) if (isec && isec->is_alive && (isec->shdr.sh_flags & SHF_ALLOC))
isec->scan_relocations(ctx); isec->scan_relocations(ctx);
// Scan relocations against exception frames // Scan relocations against exception frames
@ -918,13 +918,13 @@ void ObjectFile<E>::convert_common_symbols(Context<E> &ctx) {
shdr->sh_size = elf_syms[i].st_size; shdr->sh_size = elf_syms[i].st_size;
shdr->sh_addralign = sym->esym().st_value; shdr->sh_addralign = sym->esym().st_value;
InputSection<E> *isec = std::unique_ptr<InputSection<E>> isec =
new InputSection(ctx, *this, *shdr, ".common", sections.size()); std::make_unique<InputSection<E>>(ctx, *this, *shdr, ".common",
sections.size());
isec->output_section = osec; isec->output_section = osec;
sections.push_back(isec); sym->input_section = isec.get();
sym->input_section = isec;
sym->value = 0; sym->value = 0;
sections.push_back(std::move(isec));
} }
} }

View File

@ -271,9 +271,9 @@ void bin_sections(Context<E> &ctx) {
tbb::parallel_for((i64)0, (i64)slices.size(), [&](i64 i) { tbb::parallel_for((i64)0, (i64)slices.size(), [&](i64 i) {
for (ObjectFile<E> *file : slices[i]) for (ObjectFile<E> *file : slices[i])
for (InputSection<E> *isec : file->sections) for (std::unique_ptr<InputSection<E>> &isec : file->sections)
if (isec && isec->is_alive) if (isec && isec->is_alive)
groups[i][isec->output_section->idx].push_back(isec); groups[i][isec->output_section->idx].push_back(isec.get());
}); });
std::vector<i64> sizes(num_osec); std::vector<i64> sizes(num_osec);
@ -297,10 +297,15 @@ void check_duplicate_symbols(Context<E> &ctx) {
for (i64 i = file->first_global; i < file->elf_syms.size(); i++) { for (i64 i = file->first_global; i < file->elf_syms.size(); i++) {
const ElfSym<E> &esym = file->elf_syms[i]; const ElfSym<E> &esym = file->elf_syms[i];
Symbol<E> &sym = *file->symbols[i]; Symbol<E> &sym = *file->symbols[i];
bool is_common = esym.is_common(); bool is_common = esym.is_common();
bool is_weak = (esym.st_bind == STB_WEAK); bool is_weak = (esym.st_bind == STB_WEAK);
bool is_eliminated = bool is_eliminated = false;
!esym.is_abs() && !esym.is_common() && !file->get_section(esym);
if (!esym.is_abs() && !esym.is_common())
if (InputSection<E> *isec = file->get_section(esym))
if (!isec->is_alive)
is_eliminated = true;
if (sym.file != file && esym.is_defined() && !is_common && if (sym.file != file && esym.is_defined() && !is_common &&
!is_weak && !is_eliminated) !is_weak && !is_eliminated)