diff --git a/main.cc b/main.cc index b76cb4ed..f85779f3 100644 --- a/main.cc +++ b/main.cc @@ -691,42 +691,6 @@ static u8 *open_output_file(u64 filesize) { return (u8 *)buf; } -static void write_symtab() { - MyTimer t("write_symtab", copy_timer); - - std::vector local_symtab_off(out::files.size() + 1); - std::vector local_strtab_off(out::files.size() + 1); - local_symtab_off[0] = sizeof(ELF64LE::Sym); - local_strtab_off[0] = 1; - - for (int i = 1; i < out::files.size() + 1; i++) { - local_symtab_off[i] = local_symtab_off[i - 1] + out::files[i - 1]->local_symtab_size; - local_strtab_off[i] = local_strtab_off[i - 1] + out::files[i - 1]->local_strtab_size; - } - - out::symtab->shdr.sh_info = local_symtab_off.back() / sizeof(ELF64LE::Sym); - - std::vector global_symtab_off(out::files.size() + 1); - std::vector global_strtab_off(out::files.size() + 1); - global_symtab_off[0] = local_symtab_off.back(); - global_strtab_off[0] = local_strtab_off.back(); - - for (int i = 1; i < out::files.size() + 1; i++) { - global_symtab_off[i] = - global_symtab_off[i - 1] + out::files[i - 1]->global_symtab_size; - global_strtab_off[i] = - global_strtab_off[i - 1] + out::files[i - 1]->global_strtab_size; - } - - assert(global_symtab_off.back() == out::symtab->shdr.sh_size); - assert(global_strtab_off.back() == out::strtab->shdr.sh_size); - - tbb::parallel_for((size_t)0, out::files.size(), [&](size_t i) { - out::files[i]->write_local_symtab(local_symtab_off[i], local_strtab_off[i]); - out::files[i]->write_global_symtab(global_symtab_off[i], global_strtab_off[i]); - }); -} - static int get_thread_count(InputArgList &args) { if (auto *arg = args.getLastArg(OPT_thread_count)) { int n; @@ -981,9 +945,6 @@ int main(int argc, char **argv) { }); } - // Fill .symtab and .strtab - write_symtab(); - // Fill .plt, .got, got.plt, .rela.plt sections write_got_plt(); diff --git a/mold.h b/mold.h index 6bb3376c..c75668d4 100644 --- a/mold.h +++ b/mold.h @@ -518,14 +518,16 @@ public: shdr.sh_entsize = sizeof(ELF64LE::Sym); shdr.sh_addralign = 8; shdr.sh_size = sizeof(ELF64LE::Sym); - contents.push_back({}); } void update_shdr() override; - void initialize_buf() override; + void copy_buf() override; private: - std::vector contents; + std::vector local_symtab_off; + std::vector local_strtab_off; + std::vector global_symtab_off; + std::vector global_strtab_off; }; class DynsymSection : public OutputChunk { diff --git a/output_chunks.cc b/output_chunks.cc index a68a731c..9a6a147e 100644 --- a/output_chunks.cc +++ b/output_chunks.cc @@ -234,10 +234,43 @@ void DynstrSection::copy_buf() { void SymtabSection::update_shdr() { shdr.sh_link = out::strtab->shndx; + + local_symtab_off.resize(out::files.size() + 1); + local_strtab_off.resize(out::files.size() + 1); + global_symtab_off.resize(out::files.size() + 1); + global_strtab_off.resize(out::files.size() + 1); + + local_symtab_off[0] = sizeof(ELF64LE::Sym); + local_strtab_off[0] = 1; + + for (int i = 1; i < out::files.size() + 1; i++) { + local_symtab_off[i] = local_symtab_off[i - 1] + out::files[i - 1]->local_symtab_size; + local_strtab_off[i] = local_strtab_off[i - 1] + out::files[i - 1]->local_strtab_size; + } + + shdr.sh_info = local_symtab_off.back() / sizeof(ELF64LE::Sym); + + global_symtab_off[0] = local_symtab_off.back(); + global_strtab_off[0] = local_strtab_off.back(); + + for (int i = 1; i < out::files.size() + 1; i++) { + global_symtab_off[i] = + global_symtab_off[i - 1] + out::files[i - 1]->global_symtab_size; + global_strtab_off[i] = + global_strtab_off[i - 1] + out::files[i - 1]->global_strtab_size; + } + + assert(global_symtab_off.back() == out::symtab->shdr.sh_size); + assert(global_strtab_off.back() == out::strtab->shdr.sh_size); } -void SymtabSection::initialize_buf() { +void SymtabSection::copy_buf() { memset(out::buf + shdr.sh_offset, 0, sizeof(ELF64LE::Sym)); + + tbb::parallel_for((size_t)0, out::files.size(), [&](size_t i) { + out::files[i]->write_local_symtab(local_symtab_off[i], local_strtab_off[i]); + out::files[i]->write_global_symtab(global_symtab_off[i], global_strtab_off[i]); + }); } void DynamicSection::update_shdr() {