summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/InputFiles.cpp109
-rw-r--r--lld/ELF/InputFiles.h2
-rw-r--r--lld/ELF/SymbolTable.cpp3
3 files changed, 57 insertions, 57 deletions
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index d99f71eb4aa..973a2660c43 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -137,15 +137,13 @@ std::string lld::toString(const InputFile *F) {
return F->ToStringCache;
}
-template <class ELFT> static ELFKind getELFKind() {
- if (ELFT::TargetEndianness == support::little)
- return ELFT::Is64Bits ? ELF64LEKind : ELF32LEKind;
- return ELFT::Is64Bits ? ELF64BEKind : ELF32BEKind;
-}
-
template <class ELFT>
ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef MB) : InputFile(K, MB) {
- EKind = getELFKind<ELFT>();
+ if (ELFT::TargetEndianness == support::little)
+ EKind = ELFT::Is64Bits ? ELF64LEKind : ELF32LEKind;
+ else
+ EKind = ELFT::Is64Bits ? ELF64BEKind : ELF32BEKind;
+
EMachine = getObj().getHeader()->e_machine;
OSABI = getObj().getHeader()->e_ident[llvm::ELF::EI_OSABI];
}
@@ -174,8 +172,10 @@ void ELFFileBase<ELFT>::initSymtab(ArrayRef<Elf_Shdr> Sections,
}
template <class ELFT>
-elf::ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M)
- : ELFFileBase<ELFT>(Base::ObjectKind, M) {}
+elf::ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M, StringRef ArchiveName)
+ : ELFFileBase<ELFT>(Base::ObjectKind, M) {
+ this->ArchiveName = ArchiveName;
+}
template <class ELFT>
ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getLocalSymbols() {
@@ -862,49 +862,24 @@ void BitcodeFile::parse(DenseSet<CachedHashStringRef> &ComdatGroups) {
Symbols.push_back(createBitcodeSymbol<ELFT>(KeptComdats, ObjSym, this));
}
-// Small bit of template meta programming to handle the SharedFile constructor
-// being the only one with a DefaultSoName parameter.
-template <template <class> class T, class E>
-typename std::enable_if<std::is_same<T<E>, SharedFile<E>>::value,
- InputFile *>::type
-createELFAux(MemoryBufferRef MB, StringRef DefaultSoName) {
- return make<T<E>>(MB, DefaultSoName);
-}
-template <template <class> class T, class E>
-typename std::enable_if<!std::is_same<T<E>, SharedFile<E>>::value,
- InputFile *>::type
-createELFAux(MemoryBufferRef MB, StringRef DefaultSoName) {
- return make<T<E>>(MB);
-}
-
-template <template <class> class T>
-static InputFile *createELFFile(MemoryBufferRef MB, StringRef DefaultSoName) {
+static ELFKind getELFKind(MemoryBufferRef MB) {
unsigned char Size;
unsigned char Endian;
std::tie(Size, Endian) = getElfArchType(MB.getBuffer());
+
if (Endian != ELFDATA2LSB && Endian != ELFDATA2MSB)
fatal(MB.getBufferIdentifier() + ": invalid data encoding");
+ if (Size != ELFCLASS32 && Size != ELFCLASS64)
+ fatal(MB.getBufferIdentifier() + ": invalid file class");
size_t BufSize = MB.getBuffer().size();
if ((Size == ELFCLASS32 && BufSize < sizeof(Elf32_Ehdr)) ||
(Size == ELFCLASS64 && BufSize < sizeof(Elf64_Ehdr)))
fatal(MB.getBufferIdentifier() + ": file is too short");
- InputFile *Obj;
- if (Size == ELFCLASS32 && Endian == ELFDATA2LSB)
- Obj = createELFAux<T, ELF32LE>(MB, DefaultSoName);
- else if (Size == ELFCLASS32 && Endian == ELFDATA2MSB)
- Obj = createELFAux<T, ELF32BE>(MB, DefaultSoName);
- else if (Size == ELFCLASS64 && Endian == ELFDATA2LSB)
- Obj = createELFAux<T, ELF64LE>(MB, DefaultSoName);
- else if (Size == ELFCLASS64 && Endian == ELFDATA2MSB)
- Obj = createELFAux<T, ELF64BE>(MB, DefaultSoName);
- else
- fatal(MB.getBufferIdentifier() + ": invalid file class");
-
- if (!Config->FirstElf)
- Config->FirstElf = Obj;
- return Obj;
+ if (Size == ELFCLASS32)
+ return (Endian == ELFDATA2LSB) ? ELF32LEKind : ELF32BEKind;
+ return (Endian == ELFDATA2LSB) ? ELF64LEKind : ELF64BEKind;
}
template <class ELFT> void BinaryFile::parse() {
@@ -941,15 +916,36 @@ static bool isBitcode(MemoryBufferRef MB) {
InputFile *elf::createObjectFile(MemoryBufferRef MB, StringRef ArchiveName,
uint64_t OffsetInArchive) {
- InputFile *F = isBitcode(MB)
- ? make<BitcodeFile>(MB, ArchiveName, OffsetInArchive)
- : createELFFile<ObjectFile>(MB, "");
- F->ArchiveName = ArchiveName;
- return F;
+ if (isBitcode(MB))
+ return make<BitcodeFile>(MB, ArchiveName, OffsetInArchive);
+
+ switch (getELFKind(MB)) {
+ case ELF32LEKind:
+ return make<ObjectFile<ELF32LE>>(MB, ArchiveName);
+ case ELF32BEKind:
+ return make<ObjectFile<ELF32BE>>(MB, ArchiveName);
+ case ELF64LEKind:
+ return make<ObjectFile<ELF64LE>>(MB, ArchiveName);
+ case ELF64BEKind:
+ return make<ObjectFile<ELF64BE>>(MB, ArchiveName);
+ default:
+ llvm_unreachable("getELFKind");
+ }
}
InputFile *elf::createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName) {
- return createELFFile<SharedFile>(MB, DefaultSoName);
+ switch (getELFKind(MB)) {
+ case ELF32LEKind:
+ return make<SharedFile<ELF32LE>>(MB, DefaultSoName);
+ case ELF32BEKind:
+ return make<SharedFile<ELF32BE>>(MB, DefaultSoName);
+ case ELF64LEKind:
+ return make<SharedFile<ELF64LE>>(MB, DefaultSoName);
+ case ELF64BEKind:
+ return make<SharedFile<ELF64BE>>(MB, DefaultSoName);
+ default:
+ llvm_unreachable("getELFKind");
+ }
}
MemoryBufferRef LazyObjectFile::getBuffer() {
@@ -1004,17 +1000,18 @@ std::vector<StringRef> LazyObjectFile::getSymbols() {
if (isBitcode(this->MB))
return getBitcodeSymbols();
- unsigned char Size;
- unsigned char Endian;
- std::tie(Size, Endian) = getElfArchType(this->MB.getBuffer());
- if (Size == ELFCLASS32) {
- if (Endian == ELFDATA2LSB)
- return getElfSymbols<ELF32LE>();
+ switch (getELFKind(this->MB)) {
+ case ELF32LEKind:
+ return getElfSymbols<ELF32LE>();
+ case ELF32BEKind:
return getElfSymbols<ELF32BE>();
- }
- if (Endian == ELFDATA2LSB)
+ case ELF64LEKind:
return getElfSymbols<ELF64LE>();
- return getElfSymbols<ELF64BE>();
+ case ELF64BEKind:
+ return getElfSymbols<ELF64BE>();
+ default:
+ llvm_unreachable("getELFKind");
+ }
}
template void ArchiveFile::parse<ELF32LE>();
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index 4552270316d..d0a45a4a98c 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -156,7 +156,7 @@ public:
ArrayRef<SymbolBody *> getSymbols();
ArrayRef<SymbolBody *> getLocalSymbols();
- explicit ObjectFile(MemoryBufferRef M);
+ ObjectFile(MemoryBufferRef M, StringRef ArchiveName);
void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
InputSectionBase *getSection(const Elf_Sym &Sym) const;
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index e55b8bf52c1..541fc1bf647 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -52,6 +52,9 @@ template <class ELFT> static bool isCompatible(InputFile *F) {
// Add symbols in File to the symbol table.
template <class ELFT> void SymbolTable<ELFT>::addFile(InputFile *File) {
+ if (!Config->FirstElf && isa<ELFFileBase<ELFT>>(File))
+ Config->FirstElf = File;
+
if (!isCompatible<ELFT>(File))
return;
OpenPOWER on IntegriCloud