forked from OSchip/llvm-project
Removes createELFFile which takes a template class as a template parameter.
This patch is to reduce amount of template uses. The new code is less exciting and boring than before, but I think it is easier to read. Differential Revision: https://reviews.llvm.org/D32467 llvm-svn: 301488
This commit is contained in:
parent
87b30ac9d3
commit
330e52b018
|
@ -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)
|
||||
switch (getELFKind(this->MB)) {
|
||||
case ELF32LEKind:
|
||||
return getElfSymbols<ELF32LE>();
|
||||
case ELF32BEKind:
|
||||
return getElfSymbols<ELF32BE>();
|
||||
}
|
||||
if (Endian == ELFDATA2LSB)
|
||||
case ELF64LEKind:
|
||||
return getElfSymbols<ELF64LE>();
|
||||
case ELF64BEKind:
|
||||
return getElfSymbols<ELF64BE>();
|
||||
default:
|
||||
llvm_unreachable("getELFKind");
|
||||
}
|
||||
}
|
||||
|
||||
template void ArchiveFile::parse<ELF32LE>();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue