diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index cc5ea7aee034..ba2c2377d438 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -46,19 +46,26 @@ bool ELFFileBase::isCompatibleWith(const ELFFileBase &Other) const { getEMachine() == Other.getEMachine(); } -template void ELFData::openELF(MemoryBufferRef MB) { - // Parse a memory buffer as a ELF file. +namespace { +class ECRAII { std::error_code EC; - ELFObj = llvm::make_unique>(MB.getBuffer(), EC); - error(EC); + +public: + std::error_code &getEC() { return EC; } + ~ECRAII() { error(EC); } +}; } +template +ELFData::ELFData(MemoryBufferRef MB) + : ELFObj(MB.getBuffer(), ECRAII().getEC()) {} + template typename ELFData::Elf_Sym_Range ELFData::getSymbolsHelper(bool Local) { if (!Symtab) return Elf_Sym_Range(nullptr, nullptr); - Elf_Sym_Range Syms = ELFObj->symbols(Symtab); + Elf_Sym_Range Syms = ELFObj.symbols(Symtab); uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); uint32_t FirstNonLocal = Symtab->sh_info; if (FirstNonLocal > NumSymbols) @@ -74,38 +81,39 @@ template typename ELFData::Elf_Sym_Range ELFData::getNonLocalSymbols() { if (!Symtab) return Elf_Sym_Range(nullptr, nullptr); - ErrorOr StringTableOrErr = - ELFObj->getStringTableForSymtab(*Symtab); + ErrorOr StringTableOrErr = ELFObj.getStringTableForSymtab(*Symtab); error(StringTableOrErr.getError()); StringTable = *StringTableOrErr; return getSymbolsHelper(false); } +template +ObjectFile::ObjectFile(MemoryBufferRef M) + : ObjectFileBase(getStaticELFKind(), M), ELFData(M) {} + template typename ObjectFile::Elf_Sym_Range ObjectFile::getLocalSymbols() { return this->getSymbolsHelper(true); } template void elf2::ObjectFile::parse() { - this->openELF(MB); - // Read section and symbol tables. initializeSections(); initializeSymbols(); } template void elf2::ObjectFile::initializeSections() { - uint64_t Size = this->ELFObj->getNumSections(); + uint64_t Size = this->ELFObj.getNumSections(); Sections.resize(Size); unsigned I = 0; - for (const Elf_Shdr &Sec : this->ELFObj->sections()) { + for (const Elf_Shdr &Sec : this->ELFObj.sections()) { switch (Sec.sh_type) { case SHT_SYMTAB: this->Symtab = &Sec; break; case SHT_SYMTAB_SHNDX: { ErrorOr> ErrorOrTable = - this->ELFObj->getSHNDXTable(Sec); + this->ELFObj.getSHNDXTable(Sec); error(ErrorOrTable); SymtabSHNDX = *ErrorOrTable; break; @@ -156,8 +164,8 @@ SymbolBody *elf2::ObjectFile::createSymbolBody(StringRef StringTable, case SHN_COMMON: return new (Alloc) DefinedCommon(Name, *Sym); case SHN_XINDEX: - SecIndex = this->ELFObj->getExtendedSymbolTableIndex(Sym, this->Symtab, - SymtabSHNDX); + SecIndex = this->ELFObj.getExtendedSymbolTableIndex(Sym, this->Symtab, + SymtabSHNDX); break; } @@ -203,10 +211,12 @@ MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) { return *Ret; } -template void SharedFile::parse() { - this->openELF(MB); +template +SharedFile::SharedFile(MemoryBufferRef M) + : SharedFileBase(getStaticELFKind(), M), ELFData(M) {} - for (const Elf_Shdr &Sec : this->ELFObj->sections()) { +template void SharedFile::parse() { + for (const Elf_Shdr &Sec : this->ELFObj.sections()) { if (Sec.sh_type == SHT_DYNSYM) { this->Symtab = &Sec; break; diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 52f4d1751d2b..b11db5029237 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -97,23 +97,23 @@ template static ELFKind getStaticELFKind() { template class ELFData { public: + ELFData(MemoryBufferRef MB); typedef typename llvm::object::ELFFile::Elf_Shdr Elf_Shdr; typedef typename llvm::object::ELFFile::Elf_Sym_Range Elf_Sym_Range; - llvm::object::ELFFile *getObj() const { return ELFObj.get(); } + const llvm::object::ELFFile &getObj() const { return ELFObj; } + llvm::object::ELFFile &getObj() { return ELFObj; } - uint16_t getEMachine() const { return getObj()->getHeader()->e_machine; } + uint16_t getEMachine() const { return getObj().getHeader()->e_machine; } StringRef getStringTable() const { return StringTable; } protected: - std::unique_ptr> ELFObj; + llvm::object::ELFFile ELFObj; const Elf_Shdr *Symtab = nullptr; StringRef StringTable; Elf_Sym_Range getNonLocalSymbols(); Elf_Sym_Range getSymbolsHelper(bool); - - void openELF(MemoryBufferRef MB); }; template @@ -131,8 +131,7 @@ public: cast(F)->getELFKind() == getStaticELFKind(); } - explicit ObjectFile(MemoryBufferRef M) - : ObjectFileBase(getStaticELFKind(), M) {} + explicit ObjectFile(MemoryBufferRef M); void parse() override; ArrayRef *> getSections() const { return Sections; } @@ -207,8 +206,7 @@ public: cast(F)->getELFKind() == getStaticELFKind(); } - explicit SharedFile(MemoryBufferRef M) - : SharedFileBase(getStaticELFKind(), M) {} + explicit SharedFile(MemoryBufferRef M); void parse() override; }; diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 2b57e5f13fda..70d2550d528d 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -32,7 +32,7 @@ void InputSection::relocate( const OutputSection &BssSec, const PltSection &PltSec, const GotSection &GotSec) { typedef Elf_Rel_Impl RelType; - bool IsMips64EL = File.getObj()->isMips64EL(); + bool IsMips64EL = File.getObj().isMips64EL(); for (const RelType &RI : Rels) { uint32_t SymIndex = RI.getSymbol(IsMips64EL); uint32_t Type = RI.getType(IsMips64EL); @@ -42,7 +42,7 @@ void InputSection::relocate( // resolved so we don't allocate a SymbolBody. const Elf_Shdr *SymTab = File.getSymbolTable(); if (SymIndex < SymTab->sh_info) { - const Elf_Sym *Sym = File.getObj()->getRelocationSymbol(&RI, SymTab); + const Elf_Sym *Sym = File.getObj().getRelocationSymbol(&RI, SymTab); if (!Sym) continue; SymVA = getLocalSymVA(Sym, File); @@ -98,26 +98,26 @@ void InputSection::writeTo(uint8_t *Buf, if (Header->sh_type == SHT_NOBITS) return; // Copy section contents from source object file to output file. - ArrayRef Data = *File->getObj()->getSectionContents(Header); + ArrayRef Data = *File->getObj().getSectionContents(Header); memcpy(Buf + OutputSectionOff, Data.data(), Data.size()); - const ObjectFile *File = getFile(); - ELFFile *EObj = File->getObj(); + ObjectFile *File = getFile(); + ELFFile &EObj = File->getObj(); uint8_t *Base = Buf + getOutputSectionOff(); uintX_t BaseAddr = Out->getVA() + getOutputSectionOff(); // Iterate over all relocation sections that apply to this section. for (const Elf_Shdr *RelSec : RelocSections) { if (RelSec->sh_type == SHT_RELA) - relocate(Base, EObj->relas(RelSec), *File, BaseAddr, BssSec, PltSec, + relocate(Base, EObj.relas(RelSec), *File, BaseAddr, BssSec, PltSec, GotSec); else - relocate(Base, EObj->rels(RelSec), *File, BaseAddr, BssSec, PltSec, + relocate(Base, EObj.rels(RelSec), *File, BaseAddr, BssSec, PltSec, GotSec); } } template StringRef InputSection::getSectionName() const { - ErrorOr Name = File->getObj()->getSectionName(Header); + ErrorOr Name = File->getObj().getSectionName(Header); error(Name); return *Name; } diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h index f0de99ec0848..cba8ee26767e 100644 --- a/lld/ELF/InputSection.h +++ b/lld/ELF/InputSection.h @@ -42,7 +42,7 @@ public: StringRef getSectionName() const; const Elf_Shdr *getSectionHdr() const { return Header; } - const ObjectFile *getFile() const { return File; } + ObjectFile *getFile() const { return File; } // The writer sets and uses the addresses. uintX_t getOutputSectionOff() const { return OutputSectionOff; } diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 113f25b8690a..04036d005222 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -64,7 +64,7 @@ PltSection::getEntryAddr(const SymbolBody &B) const { template void RelocationSection::writeTo(uint8_t *Buf) { const unsigned EntrySize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); - bool IsMips64EL = Relocs[0].C.getFile()->getObj()->isMips64EL(); + bool IsMips64EL = Relocs[0].C.getFile()->getObj().isMips64EL(); for (const DynamicReloc &Rel : Relocs) { auto *P = reinterpret_cast(Buf); Buf += EntrySize; @@ -242,7 +242,7 @@ lld::elf2::getLocalSymVA(const typename ELFFile::Elf_Sym *Sym, uint32_t SecIndex = Sym->st_shndx; if (SecIndex == SHN_XINDEX) - SecIndex = File.getObj()->getExtendedSymbolTableIndex( + SecIndex = File.getObj().getExtendedSymbolTableIndex( Sym, File.getSymbolTable(), File.getSymbolTableShndx()); ArrayRef *> Sections = File.getSections(); InputSection *Section = Sections[SecIndex]; @@ -309,7 +309,7 @@ template void SymbolTableSection::writeTo(uint8_t *Buf) { ESym->st_size = Sym.st_size; ESym->setBindingAndType(Sym.getBinding(), Sym.getType()); if (SecIndex == SHN_XINDEX) - SecIndex = File.getObj()->getExtendedSymbolTableIndex( + SecIndex = File.getObj().getExtendedSymbolTableIndex( &Sym, File.getSymbolTable(), File.getSymbolTableShndx()); ArrayRef *> Sections = File.getSections(); Section = Sections[SecIndex]; diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 19fb5de906af..80b2eaac6264 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -130,7 +130,7 @@ void SymbolTable::dupError(const SymbolBody &Old, const SymbolBody &New) { for (const std::unique_ptr &F : ObjectFiles) { const auto &File = cast>(*F); - Elf_Sym_Range Syms = File.getObj()->symbols(File.getSymbolTable()); + Elf_Sym_Range Syms = File.getObj().symbols(File.getSymbolTable()); if (&OldE > Syms.begin() && &OldE < Syms.end()) OldFile = F.get(); if (&NewE > Syms.begin() && &NewE < Syms.end()) diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index c9bf60e17312..78797dcd6340 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -249,7 +249,7 @@ void Writer::scanRelocs( iterator_range *> Rels) { typedef Elf_Rel_Impl RelType; const ObjectFile &File = *C.getFile(); - bool IsMips64EL = File.getObj()->isMips64EL(); + bool IsMips64EL = File.getObj().isMips64EL(); for (const RelType &RI : Rels) { uint32_t SymIndex = RI.getSymbol(IsMips64EL); SymbolBody *Body = File.getSymbolBody(SymIndex); @@ -275,17 +275,17 @@ void Writer::scanRelocs( template void Writer::scanRelocs(const InputSection &C) { - const ObjectFile *File = C.getFile(); - ELFFile *EObj = File->getObj(); + ObjectFile *File = C.getFile(); + ELFFile &EObj = File->getObj(); if (!(C.getSectionHdr()->sh_flags & SHF_ALLOC)) return; for (const Elf_Shdr *RelSec : C.RelocSections) { if (RelSec->sh_type == SHT_RELA) - scanRelocs(C, EObj->relas(RelSec)); + scanRelocs(C, EObj.relas(RelSec)); else - scanRelocs(C, EObj->rels(RelSec)); + scanRelocs(C, EObj.rels(RelSec)); } } @@ -299,7 +299,7 @@ static void undefError(const SymbolTable &S, const SymbolBody &Sym) { for (const std::unique_ptr &F : S.getObjectFiles()) { const auto &File = cast>(*F); - Elf_Sym_Range Syms = File.getObj()->symbols(File.getSymbolTable()); + Elf_Sym_Range Syms = File.getObj().symbols(File.getSymbolTable()); if (&SymE > Syms.begin() && &SymE < Syms.end()) SymFile = F.get(); }