diff --git a/main.cc b/main.cc index 17142d82..774ee0bb 100644 --- a/main.cc +++ b/main.cc @@ -309,7 +309,7 @@ static void check_duplicate_symbols() { MyTimer t("check_undef_syms", before_copy_timer); auto is_error = [](ObjectFile *file, int i) { - const ELF64LE::Sym &esym = file->elf_syms[i]; + const ElfSym &esym = file->elf_syms[i]; Symbol &sym = *file->symbols[i]; bool is_weak = (esym.getBinding() == STB_WEAK); bool is_eliminated = diff --git a/mold.h b/mold.h index 992e2556..9c08bafa 100644 --- a/mold.h +++ b/mold.h @@ -157,6 +157,30 @@ private: MapT map; }; +// +// ELF +// + +struct ElfSym { + bool is_common() const { return sh_shndx == SHN_COMMON; } + bool is_abs() const { return sh_shndx == SHN_ABS; } + + u32 st_name; + + union { + u8 st_info; + struct { + u8 st_type : 4; + u8 st_bind : 4; + }; + }; + + u8 st_other; + u32 st_shndx; + u64 st_value; + u64 st_size; +}; + // // Symbol // @@ -204,7 +228,7 @@ public: std::string_view name; InputFile *file = nullptr; - const ELF64LE::Sym *esym = nullptr; + const ElfSym *esym = nullptr; InputSection *input_section = nullptr; StringPieceRef piece_ref; @@ -528,9 +552,9 @@ public: SymtabSection() : OutputChunk(SYNTHETIC) { name = ".symtab"; shdr.sh_type = llvm::ELF::SHT_SYMTAB; - shdr.sh_entsize = sizeof(ELF64LE::Sym); + shdr.sh_entsize = sizeof(ElfSym); shdr.sh_addralign = 8; - shdr.sh_size = sizeof(ELF64LE::Sym); + shdr.sh_size = sizeof(ElfSym); } void update_shdr() override; @@ -543,9 +567,9 @@ public: name = ".dynsym"; shdr.sh_type = llvm::ELF::SHT_DYNSYM; shdr.sh_flags = llvm::ELF::SHF_ALLOC; - shdr.sh_entsize = sizeof(ELF64LE::Sym); + shdr.sh_entsize = sizeof(ElfSym); shdr.sh_addralign = 8; - shdr.sh_size = sizeof(ELF64LE::Sym); + shdr.sh_size = sizeof(ElfSym); shdr.sh_info = 1; } @@ -698,7 +722,7 @@ public: std::string_view archive_name; std::vector sections; - ArrayRef elf_syms; + ArrayRef elf_syms; int first_global = 0; const bool is_in_archive; std::atomic_bool has_error = ATOMIC_VAR_INIT(false); @@ -744,10 +768,10 @@ public: private: std::string_view get_soname(ArrayRef elf_sections); - void maybe_override_symbol(Symbol &sym, const ELF64LE::Sym &esym); + void maybe_override_symbol(Symbol &sym, const ElfSym &esym); std::vector read_verdef(); - std::vector elf_syms; + std::vector elf_syms; std::vector versyms; std::string_view symbol_strtab; diff --git a/object_file.cc b/object_file.cc index b0412858..86788806 100644 --- a/object_file.cc +++ b/object_file.cc @@ -37,7 +37,7 @@ void ObjectFile::initialize_sections() { // Get the signature of this section group. if (shdr.sh_info >= elf_syms.size()) error(toString(this) + ": invalid symbol index"); - const ELF64LE::Sym &sym = elf_syms[shdr.sh_info]; + const ElfSym &sym = elf_syms[shdr.sh_info]; std::string_view signature = CHECK(sym.getName(symbol_strtab), this); // Get comdat group members. @@ -126,7 +126,7 @@ void ObjectFile::initialize_symbols() { // Initialize local symbols for (int i = 1; i < first_global; i++) { - const ELF64LE::Sym &esym = elf_syms[i]; + const ElfSym &esym = elf_syms[i]; std::string_view name = CHECK(esym.getName(symbol_strtab), this); local_symbols.emplace_back(name); @@ -147,13 +147,13 @@ void ObjectFile::initialize_symbols() { if (esym.getType() != STT_SECTION) { strtab_size += name.size() + 1; - local_symtab_size += sizeof(ELF64LE::Sym); + local_symtab_size += sizeof(ElfSym); } } // Initialize global symbols for (int i = first_global; i < elf_syms.size(); i++) { - const ELF64LE::Sym &esym = elf_syms[i]; + const ElfSym &esym = elf_syms[i]; std::string_view name = CHECK(esym.getName(symbol_strtab), this); int pos = name.find('@'); if (pos != std::string_view::npos) @@ -252,7 +252,7 @@ void ObjectFile::initialize_mergeable_sections() { // Initialize sym_pieces for (int i = 0; i < elf_syms.size(); i++) { - const ELF64LE::Sym &esym = elf_syms[i]; + const ElfSym &esym = elf_syms[i]; if (esym.isAbsolute() || esym.isCommon()) continue; @@ -296,7 +296,7 @@ void ObjectFile::parse() { static Counter defined("defined_syms"); static Counter undefined("undefined_syms"); - for (const ELF64LE::Sym &esym : elf_syms) { + for (const ElfSym &esym : elf_syms) { if (esym.isDefined()) defined.inc(); else @@ -314,7 +314,7 @@ void ObjectFile::parse() { // 4. Unclaimed (nonexistent) symbol // // Ties are broken by file priority. -static u64 get_rank(InputFile *file, const ELF64LE::Sym &esym, InputSection *isec) { +static u64 get_rank(InputFile *file, const ElfSym &esym, InputSection *isec) { if (isec && isec->is_comdat_member) return file->priority; if (esym.isUndefined()) { @@ -336,7 +336,7 @@ static u64 get_rank(const Symbol &sym) { void ObjectFile::maybe_override_symbol(Symbol &sym, int symidx) { InputSection *isec = nullptr; - const ELF64LE::Sym &esym = elf_syms[symidx]; + const ElfSym &esym = elf_syms[symidx]; if (!esym.isAbsolute() && !esym.isCommon()) isec = sections[esym.st_shndx]; @@ -366,7 +366,7 @@ void ObjectFile::maybe_override_symbol(Symbol &sym, int symidx) { void ObjectFile::resolve_symbols() { for (int i = first_global; i < symbols.size(); i++) { - const ELF64LE::Sym &esym = elf_syms[i]; + const ElfSym &esym = elf_syms[i]; if (!esym.isDefined()) continue; @@ -397,7 +397,7 @@ ObjectFile::mark_live_objects(tbb::parallel_do_feeder &feeder) { assert(is_alive); for (int i = first_global; i < symbols.size(); i++) { - const ELF64LE::Sym &esym = elf_syms[i]; + const ElfSym &esym = elf_syms[i]; Symbol &sym = *symbols[i]; if (esym.isDefined()) { @@ -426,7 +426,7 @@ void ObjectFile::handle_undefined_weak_symbols() { return; for (int i = first_global; i < symbols.size(); i++) { - const ELF64LE::Sym &esym = elf_syms[i]; + const ElfSym &esym = elf_syms[i]; Symbol &sym = *symbols[i]; if (esym.isUndefined() && esym.getBinding() == STB_WEAK) { @@ -520,11 +520,11 @@ void ObjectFile::convert_common_symbols() { void ObjectFile::compute_symtab() { for (int i = first_global; i < elf_syms.size(); i++) { - const ELF64LE::Sym &esym = elf_syms[i]; + const ElfSym &esym = elf_syms[i]; Symbol &sym = *symbols[i]; if (esym.getType() != STT_SECTION && sym.file == this) { - global_symtab_size += sizeof(ELF64LE::Sym); + global_symtab_size += sizeof(ElfSym); strtab_size += sym.name.size() + 1; } } @@ -541,8 +541,8 @@ void ObjectFile::write_symtab() { if (sym.type == STT_SECTION || sym.file != this) return; - ELF64LE::Sym &esym = *(ELF64LE::Sym *)(symtab_base + symtab_off); - symtab_off += sizeof(ELF64LE::Sym); + ElfSym &esym = *(ElfSym *)(symtab_base + symtab_off); + symtab_off += sizeof(ElfSym); esym = elf_syms[i]; esym.st_name = strtab_off; @@ -582,13 +582,13 @@ ObjectFile *ObjectFile::create_internal_file() { auto *obj = new ObjectFile(*mb, ""); // Create linker-synthesized symbols. - auto *elf_syms = new std::vector(1); + auto *elf_syms = new std::vector(1); obj->symbols.push_back(new Symbol("")); obj->first_global = 1; obj->is_alive = true; auto add = [&](std::string_view name, u8 visibility = STV_DEFAULT) { - ELF64LE::Sym esym = {}; + ElfSym esym = {}; esym.setType(STT_NOTYPE); esym.st_shndx = SHN_ABS; esym.setBinding(STB_GLOBAL); @@ -668,12 +668,12 @@ void SharedFile::parse() { // Read a symbol table. int first_global = symtab_sec->sh_info; - ArrayRef esyms = CHECK(obj.symbols(symtab_sec), this); + ArrayRef esyms = CHECK(obj.symbols(symtab_sec), this); ArrayRef vers; if (const ELF64LE::Shdr *sec = find_section(elf_sections, SHT_GNU_versym)) vers = CHECK(obj.template getSectionContentsAsArray(*sec), this); - std::vector> pairs; + std::vector> pairs; for (int i = first_global; i < esyms.size(); i++) { if (!esyms[i].isDefined()) @@ -690,8 +690,8 @@ void SharedFile::parse() { // Sort symbols by value for find_aliases(), as find_aliases() does // binary search on symbols. std::stable_sort(pairs.begin(), pairs.end(), - [](const std::pair &a, - const std::pair &b) { + [](const std::pair &a, + const std::pair &b) { return a.first->st_value < b.first->st_value; }); @@ -699,7 +699,7 @@ void SharedFile::parse() { versyms.reserve(pairs.size()); symbols.reserve(pairs.size()); - for (std::pair &x : pairs) { + for (std::pair &x : pairs) { elf_syms.push_back(x.first); versyms.push_back(x.second); @@ -742,7 +742,7 @@ std::vector SharedFile::read_verdef() { void SharedFile::resolve_symbols() { for (int i = 0; i < symbols.size(); i++) { Symbol &sym = *symbols[i]; - const ELF64LE::Sym &esym = *elf_syms[i]; + const ElfSym &esym = *elf_syms[i]; std::lock_guard lock(sym.mu); diff --git a/output_chunks.cc b/output_chunks.cc index addcd15d..b75c8659 100644 --- a/output_chunks.cc +++ b/output_chunks.cc @@ -245,7 +245,7 @@ void DynstrSection::copy_buf() { } void SymtabSection::update_shdr() { - shdr.sh_size = sizeof(ELF64LE::Sym); + shdr.sh_size = sizeof(ElfSym); for (ObjectFile *file : out::objs) { file->local_symtab_offset = shdr.sh_size; @@ -257,12 +257,12 @@ void SymtabSection::update_shdr() { shdr.sh_size += file->global_symtab_size; } - shdr.sh_info = out::objs[0]->global_symtab_offset / sizeof(ELF64LE::Sym); + shdr.sh_info = out::objs[0]->global_symtab_offset / sizeof(ElfSym); shdr.sh_link = out::strtab->shndx; } void SymtabSection::copy_buf() { - memset(out::buf + shdr.sh_offset, 0, sizeof(ELF64LE::Sym)); + memset(out::buf + shdr.sh_offset, 0, sizeof(ElfSym)); out::buf[out::strtab->shdr.sh_offset] = '\0'; tbb::parallel_for_each(out::objs, [](ObjectFile *file) { file->write_symtab(); }); @@ -290,7 +290,7 @@ static std::vector create_dynamic_section() { define(DT_PLTGOT, out::gotplt->shdr.sh_addr); define(DT_PLTREL, DT_RELA); define(DT_SYMTAB, out::dynsym->shdr.sh_addr); - define(DT_SYMENT, sizeof(ELF64LE::Sym)); + define(DT_SYMENT, sizeof(ElfSym)); define(DT_STRTAB, out::dynstr->shdr.sh_addr); define(DT_STRSZ, out::dynstr->shdr.sh_size); define(DT_HASH, out::hash->shdr.sh_addr); @@ -544,15 +544,15 @@ void DynsymSection::add_symbol(Symbol *sym) { void DynsymSection::update_shdr() { shdr.sh_link = out::dynstr->shndx; - shdr.sh_size = sizeof(ELF64LE::Sym) * (symbols.size() + 1); + shdr.sh_size = sizeof(ElfSym) * (symbols.size() + 1); } void DynsymSection::copy_buf() { u8 *base = out::buf + shdr.sh_offset; - memset(base, 0, sizeof(ELF64LE::Sym)); + memset(base, 0, sizeof(ElfSym)); tbb::parallel_for_each(symbols, [&](Symbol *sym) { - auto &esym = *(ELF64LE::Sym *)(base + sym->dynsym_idx * sizeof(ELF64LE::Sym)); + auto &esym = *(ElfSym *)(base + sym->dynsym_idx * sizeof(ElfSym)); memset(&esym, 0, sizeof(esym)); esym.st_name = sym->dynstr_offset; esym.setType(sym->type);