diff --git a/gc_sections.cc b/gc_sections.cc index af4bfb01..f5ccefef 100644 --- a/gc_sections.cc +++ b/gc_sections.cc @@ -90,8 +90,8 @@ collect_root_set(Context &ctx) { // Add sections that are not subject to garbage collection. tbb::parallel_for_each(ctx.objs, [&](ObjectFile *file) { - for (InputSection *isec : file->sections) { - if (!isec) + for (std::unique_ptr> &isec : file->sections) { + if (!isec || !isec->is_alive) continue; // -gc-sections discards only SHF_ALLOC sections. If you want to @@ -102,7 +102,7 @@ collect_root_set(Context &ctx) { isec->is_visited = true; 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 &ctx) { tbb::parallel_for_each(ctx.objs, [&](ObjectFile *file) { for (i64 i = 0; i < file->sections.size(); i++) { - InputSection *isec = file->sections[i]; + std::unique_ptr> &isec = file->sections[i]; if (isec && isec->is_alive && !isec->is_visited) { if (ctx.arg.print_gc_sections) diff --git a/icf.cc b/icf.cc index 19fd1700..527ca17f 100644 --- a/icf.cc +++ b/icf.cc @@ -184,8 +184,8 @@ static void merge_leaf_nodes(Context &ctx) { LeafHasher, LeafEq> map; tbb::parallel_for((i64)0, (i64)ctx.objs.size(), [&](i64 i) { - for (InputSection *isec : ctx.objs[i]->sections) { - if (!isec) + for (std::unique_ptr> &isec : ctx.objs[i]->sections) { + if (!isec || !isec->is_alive) continue; if (!is_eligible(*isec)) { @@ -196,9 +196,9 @@ static void merge_leaf_nodes(Context &ctx) { if (is_leaf(ctx, *isec)) { leaf++; 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()) - it->second = isec; + it->second = isec.get(); } else { eligible++; isec->icf_eligible = true; @@ -207,9 +207,9 @@ static void merge_leaf_nodes(Context &ctx) { }); tbb::parallel_for((i64)0, (i64)ctx.objs.size(), [&](i64 i) { - for (InputSection *isec : ctx.objs[i]->sections) { - if (isec && isec->icf_leaf) { - auto it = map.find(isec); + for (std::unique_ptr> &isec : ctx.objs[i]->sections) { + if (isec && isec->is_alive && isec->icf_leaf) { + auto it = map.find(isec.get()); assert(it != map.end()); isec->leader = it->second; } @@ -307,8 +307,8 @@ static std::vector *> gather_sections(Context &ctx) { std::vector num_sections(ctx.objs.size()); tbb::parallel_for((i64)0, (i64)ctx.objs.size(), [&](i64 i) { - for (InputSection *isec : ctx.objs[i]->sections) - if (isec && isec->icf_eligible) + for (std::unique_ptr> &isec : ctx.objs[i]->sections) + if (isec && isec->is_alive && isec->icf_eligible) num_sections[i]++; }); @@ -322,9 +322,9 @@ static std::vector *> gather_sections(Context &ctx) { // Fill `sections` contents. tbb::parallel_for((i64)0, (i64)ctx.objs.size(), [&](i64 i) { i64 idx = section_indices[i]; - for (InputSection *isec : ctx.objs[i]->sections) - if (isec && isec->icf_eligible) - sections[idx++] = isec; + for (std::unique_ptr> &isec : ctx.objs[i]->sections) + if (isec && isec->is_alive && isec->icf_eligible) + sections[idx++] = isec.get(); }); tbb::parallel_for((i64)0, (i64)sections.size(), [&](i64 i) { @@ -444,12 +444,12 @@ static void print_icf_sections(Context &ctx) { tbb::concurrent_unordered_multimap *, InputSection *> map; tbb::parallel_for_each(ctx.objs, [&](ObjectFile *file) { - for (InputSection *isec : file->sections) { - if (isec && isec->leader) { - if (isec == isec->leader) - leaders.push_back(isec); + for (std::unique_ptr> &isec : file->sections) { + if (isec && isec->is_alive && isec->leader) { + if (isec.get() == isec->leader) + leaders.push_back(isec.get()); else - map.insert({isec->leader, isec}); + map.insert({isec->leader, isec.get()}); } } }); diff --git a/input_sections.cc b/input_sections.cc index 8e1c3b04..f34f27ac 100644 --- a/input_sections.cc +++ b/input_sections.cc @@ -139,7 +139,6 @@ void InputSection::kill() { is_alive = false; for (FdeRecord &fde : fdes) fde.is_alive = false; - file.sections[section_idx] = nullptr; } } diff --git a/main.cc b/main.cc index 9f5fc477..e88ab35c 100644 --- a/main.cc +++ b/main.cc @@ -219,7 +219,7 @@ static void show_stats(Context &ctx) { static Counter undefined("undefined_syms"); undefined += obj->symbols.size() - obj->first_global; - for (InputSection *sec : obj->sections) { + for (std::unique_ptr> &sec : obj->sections) { if (!sec || !sec->is_alive) continue; diff --git a/mold.h b/mold.h index e84699ed..890948bc 100644 --- a/mold.h +++ b/mold.h @@ -862,7 +862,7 @@ public: inline std::span *> get_global_syms(); std::string archive_name; - std::vector *> sections; + std::vector>> sections; std::span> elf_syms; i64 first_global = 0; const bool is_in_lib = false; @@ -1830,7 +1830,7 @@ inline i64 ObjectFile::get_shndx(const ElfSym &esym) { template inline InputSection *ObjectFile::get_section(const ElfSym &esym) { - return sections[get_shndx(esym)]; + return sections[get_shndx(esym)].get(); } template diff --git a/object_file.cc b/object_file.cc index 79323779..cfd059c9 100644 --- a/object_file.cc +++ b/object_file.cc @@ -175,7 +175,8 @@ void ObjectFile::initialize_sections(Context &ctx) { is_debug_section(shdr, name)) continue; - this->sections[i] = new InputSection(ctx, *this, shdr, name, i); + this->sections[i] = + std::make_unique>(ctx, *this, shdr, name, i); static Counter counter("regular_sections"); counter++; @@ -194,7 +195,7 @@ void ObjectFile::initialize_sections(Context &ctx) { Fatal(ctx) << *this << ": invalid relocated section index: " << (u32)shdr.sh_info; - if (InputSection *target = sections[shdr.sh_info]) { + if (std::unique_ptr> &target = sections[shdr.sh_info]) { assert(target->relsec_idx == -1); target->relsec_idx = i; @@ -209,11 +210,11 @@ void ObjectFile::initialize_sections(Context &ctx) { template void ObjectFile::initialize_ehframe_sections(Context &ctx) { for (i64 i = 0; i < sections.size(); i++) { - InputSection *isec = sections[i]; - if (isec && isec->name == ".eh_frame") { + std::unique_ptr> &isec = sections[i]; + if (isec && isec->is_alive && isec->name == ".eh_frame") { read_ehframe(ctx, *isec); isec->is_ehframe = true; - sections[i] = nullptr; + isec->is_alive = false; } } } @@ -535,17 +536,16 @@ void ObjectFile::initialize_mergeable_sections(Context &ctx) { std::vector> mergeable_sections(sections.size()); for (i64 i = 0; i < sections.size(); i++) { - if (InputSection *isec = sections[i]) { - if (isec->shdr.sh_flags & SHF_MERGE) { - mergeable_sections[i] = split_section(ctx, *isec); - sections[i] = nullptr; - } + std::unique_ptr> &isec = sections[i]; + if (isec && isec->is_alive && (isec->shdr.sh_flags & SHF_MERGE)) { + mergeable_sections[i] = split_section(ctx, *isec); + isec->is_alive = false; } } // Initialize rel_fragments - for (InputSection *isec : sections) { - if (!isec) + for (std::unique_ptr> &isec : sections) { + if (!isec || !isec->is_alive) continue; std::span> rels = isec->get_rels(ctx); @@ -872,8 +872,8 @@ void ObjectFile::claim_unresolved_symbols() { template void ObjectFile::scan_relocations(Context &ctx) { // Scan relocations against seciton contents - for (InputSection *isec : sections) - if (isec && (isec->shdr.sh_flags & SHF_ALLOC)) + for (std::unique_ptr> &isec : sections) + if (isec && isec->is_alive && (isec->shdr.sh_flags & SHF_ALLOC)) isec->scan_relocations(ctx); // Scan relocations against exception frames @@ -918,13 +918,13 @@ void ObjectFile::convert_common_symbols(Context &ctx) { shdr->sh_size = elf_syms[i].st_size; shdr->sh_addralign = sym->esym().st_value; - InputSection *isec = - new InputSection(ctx, *this, *shdr, ".common", sections.size()); + std::unique_ptr> isec = + std::make_unique>(ctx, *this, *shdr, ".common", + sections.size()); isec->output_section = osec; - sections.push_back(isec); - - sym->input_section = isec; + sym->input_section = isec.get(); sym->value = 0; + sections.push_back(std::move(isec)); } } diff --git a/passes.cc b/passes.cc index f961cac4..e83ca8d4 100644 --- a/passes.cc +++ b/passes.cc @@ -271,9 +271,9 @@ void bin_sections(Context &ctx) { tbb::parallel_for((i64)0, (i64)slices.size(), [&](i64 i) { for (ObjectFile *file : slices[i]) - for (InputSection *isec : file->sections) + for (std::unique_ptr> &isec : file->sections) 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 sizes(num_osec); @@ -297,10 +297,15 @@ void check_duplicate_symbols(Context &ctx) { for (i64 i = file->first_global; i < file->elf_syms.size(); i++) { const ElfSym &esym = file->elf_syms[i]; Symbol &sym = *file->symbols[i]; + bool is_common = esym.is_common(); bool is_weak = (esym.st_bind == STB_WEAK); - bool is_eliminated = - !esym.is_abs() && !esym.is_common() && !file->get_section(esym); + bool is_eliminated = false; + + if (!esym.is_abs() && !esym.is_common()) + if (InputSection *isec = file->get_section(esym)) + if (!isec->is_alive) + is_eliminated = true; if (sym.file != file && esym.is_defined() && !is_common && !is_weak && !is_eliminated)