mirror of
https://github.com/rui314/mold.git
synced 2024-11-14 07:18:42 +03:00
wip
This commit is contained in:
parent
32ca7046cf
commit
d03e4c9a17
@ -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
34
icf.cc
@ -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()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
main.cc
2
main.cc
@ -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
4
mold.h
@ -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>
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
passes.cc
13
passes.cc
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user