aboutsummaryrefslogtreecommitdiff
path: root/ELF/InputFiles.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ELF/InputFiles.cpp')
-rw-r--r--ELF/InputFiles.cpp112
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);