diff options
Diffstat (limited to 'ELF/InputFiles.cpp')
-rw-r--r-- | ELF/InputFiles.cpp | 112 |
1 files changed, 46 insertions, 66 deletions
diff --git a/ELF/InputFiles.cpp b/ELF/InputFiles.cpp index e0827a3ee43d..d9df6abbf233 100644 --- a/ELF/InputFiles.cpp +++ b/ELF/InputFiles.cpp @@ -37,10 +37,9 @@ ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef M) template <class ELFT> ELFKind ELFFileBase<ELFT>::getELFKind() { - using llvm::support::little; - if (ELFT::Is64Bits) - return ELFT::TargetEndianness == little ? ELF64LEKind : ELF64BEKind; - return ELFT::TargetEndianness == little ? ELF32LEKind : ELF32BEKind; + if (ELFT::TargetEndianness == support::little) + return ELFT::Is64Bits ? ELF64LEKind : ELF32LEKind; + return ELFT::Is64Bits ? ELF64BEKind : ELF32BEKind; } template <class ELFT> @@ -63,8 +62,7 @@ template <class ELFT> uint32_t ELFFileBase<ELFT>::getSectionIndex(const Elf_Sym &Sym) const { uint32_t I = Sym.st_shndx; if (I == ELF::SHN_XINDEX) - return this->ELFObj.getExtendedSymbolTableIndex(&Sym, this->Symtab, - SymtabSHNDX); + return ELFObj.getExtendedSymbolTableIndex(&Sym, Symtab, SymtabSHNDX); if (I >= ELF::SHN_LORESERVE || I == ELF::SHN_ABS) return 0; return I; @@ -74,7 +72,7 @@ template <class ELFT> void ELFFileBase<ELFT>::initStringTable() { if (!Symtab) return; ErrorOr<StringRef> StringTableOrErr = ELFObj.getStringTableForSymtab(*Symtab); - error(StringTableOrErr.getError()); + error(StringTableOrErr); StringTable = *StringTableOrErr; } @@ -108,9 +106,9 @@ ObjectFile<ELFT>::getLocalSymbol(uintX_t SymIndex) { } template <class ELFT> -void elf2::ObjectFile<ELFT>::parse(DenseSet<StringRef> &Comdats) { +void ObjectFile<ELFT>::parse(DenseSet<StringRef> &ComdatGroups) { // Read section and symbol tables. - initializeSections(Comdats); + initializeSections(ComdatGroups); initializeSymbols(); } @@ -139,7 +137,7 @@ ObjectFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) { const ELFFile<ELFT> &Obj = this->ELFObj; ErrorOr<ArrayRef<GroupEntryType>> EntriesOrErr = Obj.template getSectionContentsAsArray<GroupEntryType>(&Sec); - error(EntriesOrErr.getError()); + error(EntriesOrErr); ArrayRef<GroupEntryType> Entries = *EntriesOrErr; if (Entries.empty() || Entries[0] != GRP_COMDAT) error("Unsupported SHT_GROUP format"); @@ -174,7 +172,7 @@ static bool shouldMerge(const typename ELFFile<ELFT>::Elf_Shdr &Sec) { } template <class ELFT> -void elf2::ObjectFile<ELFT>::initializeSections(DenseSet<StringRef> &Comdats) { +void ObjectFile<ELFT>::initializeSections(DenseSet<StringRef> &ComdatGroups) { uint64_t Size = this->ELFObj.getNumSections(); Sections.resize(Size); unsigned I = -1; @@ -187,7 +185,7 @@ void elf2::ObjectFile<ELFT>::initializeSections(DenseSet<StringRef> &Comdats) { switch (Sec.sh_type) { case SHT_GROUP: Sections[I] = &InputSection<ELFT>::Discarded; - if (Comdats.insert(getShtGroupSignature(Sec)).second) + if (ComdatGroups.insert(getShtGroupSignature(Sec)).second) continue; for (GroupEntryType E : getShtGroupEntries(Sec)) { uint32_t SecIndex = E; @@ -235,7 +233,7 @@ void elf2::ObjectFile<ELFT>::initializeSections(DenseSet<StringRef> &Comdats) { } template <class ELFT> InputSectionBase<ELFT> * -elf2::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { +ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { ErrorOr<StringRef> NameOrErr = this->ELFObj.getSectionName(&Sec); error(NameOrErr); StringRef Name = *NameOrErr; @@ -250,29 +248,29 @@ elf2::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) { // A MIPS object file has a special section that contains register // usage info, which needs to be handled by the linker specially. if (Config->EMachine == EM_MIPS && Name == ".reginfo") { - MipsReginfo = new (this->Alloc) MipsReginfoInputSection<ELFT>(this, &Sec); + MipsReginfo = new (Alloc) MipsReginfoInputSection<ELFT>(this, &Sec); return MipsReginfo; } if (Name == ".eh_frame") - return new (this->EHAlloc.Allocate()) EHInputSection<ELFT>(this, &Sec); + return new (EHAlloc.Allocate()) EHInputSection<ELFT>(this, &Sec); if (shouldMerge<ELFT>(Sec)) - return new (this->MAlloc.Allocate()) MergeInputSection<ELFT>(this, &Sec); - return new (this->Alloc) InputSection<ELFT>(this, &Sec); + return new (MAlloc.Allocate()) MergeInputSection<ELFT>(this, &Sec); + return new (Alloc) InputSection<ELFT>(this, &Sec); } -template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() { +template <class ELFT> void ObjectFile<ELFT>::initializeSymbols() { this->initStringTable(); Elf_Sym_Range Syms = this->getNonLocalSymbols(); uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); - this->SymbolBodies.reserve(NumSymbols); + SymbolBodies.reserve(NumSymbols); for (const Elf_Sym &Sym : Syms) - this->SymbolBodies.push_back(createSymbolBody(this->StringTable, &Sym)); + SymbolBodies.push_back(createSymbolBody(this->StringTable, &Sym)); } template <class ELFT> InputSectionBase<ELFT> * -elf2::ObjectFile<ELFT>::getSection(const Elf_Sym &Sym) const { +ObjectFile<ELFT>::getSection(const Elf_Sym &Sym) const { uint32_t Index = this->getSectionIndex(Sym); if (Index == 0) return nullptr; @@ -282,19 +280,19 @@ elf2::ObjectFile<ELFT>::getSection(const Elf_Sym &Sym) const { } template <class ELFT> -SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable, +SymbolBody *ObjectFile<ELFT>::createSymbolBody(StringRef StringTable, const Elf_Sym *Sym) { ErrorOr<StringRef> NameOrErr = Sym->getName(StringTable); - error(NameOrErr.getError()); + error(NameOrErr); StringRef Name = *NameOrErr; switch (Sym->st_shndx) { case SHN_UNDEF: - return new (this->Alloc) UndefinedElf<ELFT>(Name, *Sym); + return new (Alloc) UndefinedElf<ELFT>(Name, *Sym); case SHN_COMMON: - return new (this->Alloc) DefinedCommon( - Name, Sym->st_size, Sym->st_value, - Sym->getBinding() == llvm::ELF::STB_WEAK, Sym->getVisibility()); + return new (Alloc) DefinedCommon(Name, Sym->st_size, Sym->st_value, + Sym->getBinding() == llvm::ELF::STB_WEAK, + Sym->getVisibility()); } switch (Sym->getBinding()) { @@ -305,20 +303,16 @@ SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable, case STB_GNU_UNIQUE: { InputSectionBase<ELFT> *Sec = getSection(*Sym); if (Sec == &InputSection<ELFT>::Discarded) - return new (this->Alloc) UndefinedElf<ELFT>(Name, *Sym); - return new (this->Alloc) DefinedRegular<ELFT>(Name, *Sym, Sec); + return new (Alloc) UndefinedElf<ELFT>(Name, *Sym); + return new (Alloc) DefinedRegular<ELFT>(Name, *Sym, Sec); } } } -static std::unique_ptr<Archive> openArchive(MemoryBufferRef MB) { - ErrorOr<std::unique_ptr<Archive>> ArchiveOrErr = Archive::create(MB); - error(ArchiveOrErr, "Failed to parse archive"); - return std::move(*ArchiveOrErr); -} - void ArchiveFile::parse() { - File = openArchive(MB); + ErrorOr<std::unique_ptr<Archive>> FileOrErr = Archive::create(MB); + error(FileOrErr, "Failed to parse archive"); + File = std::move(*FileOrErr); // Allocate a buffer for Lazy objects. size_t NumSyms = File->getNumberOfSymbols(); @@ -345,28 +339,9 @@ MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) { return *RefOrErr; } -std::vector<MemoryBufferRef> ArchiveFile::getMembers() { - File = openArchive(MB); - - std::vector<MemoryBufferRef> Result; - for (auto &ChildOrErr : File->children()) { - error(ChildOrErr, - "Could not get the child of the archive " + File->getFileName()); - const Archive::Child Child(*ChildOrErr); - ErrorOr<MemoryBufferRef> MbOrErr = Child.getMemoryBufferRef(); - if (!MbOrErr) - error(MbOrErr, "Could not get the buffer for a child of the archive " + - File->getFileName()); - Result.push_back(MbOrErr.get()); - } - return Result; -} - template <class ELFT> SharedFile<ELFT>::SharedFile(MemoryBufferRef M) - : ELFFileBase<ELFT>(Base::SharedKind, M) { - AsNeeded = Config->AsNeeded; -} + : ELFFileBase<ELFT>(Base::SharedKind, M), AsNeeded(Config->AsNeeded) {} template <class ELFT> const typename ELFFile<ELFT>::Elf_Shdr * @@ -379,6 +354,8 @@ SharedFile<ELFT>::getSection(const Elf_Sym &Sym) const { return *Ret; } +// Partially parse the shared object file so that we can call +// getSoName on this object. template <class ELFT> void SharedFile<ELFT>::parseSoName() { typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn; typedef typename ELFFile<ELFT>::uintX_t uintX_t; @@ -405,7 +382,7 @@ template <class ELFT> void SharedFile<ELFT>::parseSoName() { } this->initStringTable(); - this->SoName = this->getName(); + SoName = this->getName(); if (!DynamicSec) return; @@ -418,13 +395,14 @@ template <class ELFT> void SharedFile<ELFT>::parseSoName() { uintX_t Val = Dyn.getVal(); if (Val >= this->StringTable.size()) error("Invalid DT_SONAME entry"); - this->SoName = StringRef(this->StringTable.data() + Val); + SoName = StringRef(this->StringTable.data() + Val); return; } } } -template <class ELFT> void SharedFile<ELFT>::parse() { +// Fully parse the shared object file. This must be called after parseSoName(). +template <class ELFT> void SharedFile<ELFT>::parseRest() { Elf_Sym_Range Syms = this->getNonLocalSymbols(); uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); SymbolBodies.reserve(NumSymbols); @@ -456,7 +434,7 @@ static std::unique_ptr<InputFile> createELFFileAux(MemoryBufferRef MB) { } template <template <class> class T> -std::unique_ptr<InputFile> lld::elf2::createELFFile(MemoryBufferRef MB) { +static std::unique_ptr<InputFile> createELFFile(MemoryBufferRef MB) { std::pair<unsigned char, unsigned char> Type = getElfArchType(MB.getBuffer()); if (Type.second != ELF::ELFDATA2LSB && Type.second != ELF::ELFDATA2MSB) error("Invalid data encoding: " + MB.getBufferIdentifier()); @@ -474,6 +452,14 @@ std::unique_ptr<InputFile> lld::elf2::createELFFile(MemoryBufferRef MB) { error("Invalid file class: " + MB.getBufferIdentifier()); } +std::unique_ptr<InputFile> elf2::createObjectFile(MemoryBufferRef MB) { + return createELFFile<ObjectFile>(MB); +} + +std::unique_ptr<InputFile> elf2::createSharedFile(MemoryBufferRef MB) { + return createELFFile<SharedFile>(MB); +} + template class elf2::ELFFileBase<ELF32LE>; template class elf2::ELFFileBase<ELF32BE>; template class elf2::ELFFileBase<ELF64LE>; @@ -488,9 +474,3 @@ template class elf2::SharedFile<ELF32LE>; template class elf2::SharedFile<ELF32BE>; template class elf2::SharedFile<ELF64LE>; template class elf2::SharedFile<ELF64BE>; - -template std::unique_ptr<InputFile> -elf2::createELFFile<ObjectFile>(MemoryBufferRef); - -template std::unique_ptr<InputFile> -elf2::createELFFile<SharedFile>(MemoryBufferRef); |