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;
|
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>
|
template <class ELFT>
|
||||||
ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef MB) : InputFile(K, MB) {
|
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;
|
EMachine = getObj().getHeader()->e_machine;
|
||||||
OSABI = getObj().getHeader()->e_ident[llvm::ELF::EI_OSABI];
|
OSABI = getObj().getHeader()->e_ident[llvm::ELF::EI_OSABI];
|
||||||
}
|
}
|
||||||
|
@ -174,8 +172,10 @@ void ELFFileBase<ELFT>::initSymtab(ArrayRef<Elf_Shdr> Sections,
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
elf::ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M)
|
elf::ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M, StringRef ArchiveName)
|
||||||
: ELFFileBase<ELFT>(Base::ObjectKind, M) {}
|
: ELFFileBase<ELFT>(Base::ObjectKind, M) {
|
||||||
|
this->ArchiveName = ArchiveName;
|
||||||
|
}
|
||||||
|
|
||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getLocalSymbols() {
|
ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getLocalSymbols() {
|
||||||
|
@ -862,49 +862,24 @@ void BitcodeFile::parse(DenseSet<CachedHashStringRef> &ComdatGroups) {
|
||||||
Symbols.push_back(createBitcodeSymbol<ELFT>(KeptComdats, ObjSym, this));
|
Symbols.push_back(createBitcodeSymbol<ELFT>(KeptComdats, ObjSym, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Small bit of template meta programming to handle the SharedFile constructor
|
static ELFKind getELFKind(MemoryBufferRef MB) {
|
||||||
// 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) {
|
|
||||||
unsigned char Size;
|
unsigned char Size;
|
||||||
unsigned char Endian;
|
unsigned char Endian;
|
||||||
std::tie(Size, Endian) = getElfArchType(MB.getBuffer());
|
std::tie(Size, Endian) = getElfArchType(MB.getBuffer());
|
||||||
|
|
||||||
if (Endian != ELFDATA2LSB && Endian != ELFDATA2MSB)
|
if (Endian != ELFDATA2LSB && Endian != ELFDATA2MSB)
|
||||||
fatal(MB.getBufferIdentifier() + ": invalid data encoding");
|
fatal(MB.getBufferIdentifier() + ": invalid data encoding");
|
||||||
|
if (Size != ELFCLASS32 && Size != ELFCLASS64)
|
||||||
|
fatal(MB.getBufferIdentifier() + ": invalid file class");
|
||||||
|
|
||||||
size_t BufSize = MB.getBuffer().size();
|
size_t BufSize = MB.getBuffer().size();
|
||||||
if ((Size == ELFCLASS32 && BufSize < sizeof(Elf32_Ehdr)) ||
|
if ((Size == ELFCLASS32 && BufSize < sizeof(Elf32_Ehdr)) ||
|
||||||
(Size == ELFCLASS64 && BufSize < sizeof(Elf64_Ehdr)))
|
(Size == ELFCLASS64 && BufSize < sizeof(Elf64_Ehdr)))
|
||||||
fatal(MB.getBufferIdentifier() + ": file is too short");
|
fatal(MB.getBufferIdentifier() + ": file is too short");
|
||||||
|
|
||||||
InputFile *Obj;
|
if (Size == ELFCLASS32)
|
||||||
if (Size == ELFCLASS32 && Endian == ELFDATA2LSB)
|
return (Endian == ELFDATA2LSB) ? ELF32LEKind : ELF32BEKind;
|
||||||
Obj = createELFAux<T, ELF32LE>(MB, DefaultSoName);
|
return (Endian == ELFDATA2LSB) ? ELF64LEKind : ELF64BEKind;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void BinaryFile::parse() {
|
template <class ELFT> void BinaryFile::parse() {
|
||||||
|
@ -941,15 +916,36 @@ static bool isBitcode(MemoryBufferRef MB) {
|
||||||
|
|
||||||
InputFile *elf::createObjectFile(MemoryBufferRef MB, StringRef ArchiveName,
|
InputFile *elf::createObjectFile(MemoryBufferRef MB, StringRef ArchiveName,
|
||||||
uint64_t OffsetInArchive) {
|
uint64_t OffsetInArchive) {
|
||||||
InputFile *F = isBitcode(MB)
|
if (isBitcode(MB))
|
||||||
? make<BitcodeFile>(MB, ArchiveName, OffsetInArchive)
|
return make<BitcodeFile>(MB, ArchiveName, OffsetInArchive);
|
||||||
: createELFFile<ObjectFile>(MB, "");
|
|
||||||
F->ArchiveName = ArchiveName;
|
switch (getELFKind(MB)) {
|
||||||
return F;
|
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) {
|
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() {
|
MemoryBufferRef LazyObjectFile::getBuffer() {
|
||||||
|
@ -1004,17 +1000,18 @@ std::vector<StringRef> LazyObjectFile::getSymbols() {
|
||||||
if (isBitcode(this->MB))
|
if (isBitcode(this->MB))
|
||||||
return getBitcodeSymbols();
|
return getBitcodeSymbols();
|
||||||
|
|
||||||
unsigned char Size;
|
switch (getELFKind(this->MB)) {
|
||||||
unsigned char Endian;
|
case ELF32LEKind:
|
||||||
std::tie(Size, Endian) = getElfArchType(this->MB.getBuffer());
|
return getElfSymbols<ELF32LE>();
|
||||||
if (Size == ELFCLASS32) {
|
case ELF32BEKind:
|
||||||
if (Endian == ELFDATA2LSB)
|
|
||||||
return getElfSymbols<ELF32LE>();
|
|
||||||
return getElfSymbols<ELF32BE>();
|
return getElfSymbols<ELF32BE>();
|
||||||
}
|
case ELF64LEKind:
|
||||||
if (Endian == ELFDATA2LSB)
|
|
||||||
return getElfSymbols<ELF64LE>();
|
return getElfSymbols<ELF64LE>();
|
||||||
return getElfSymbols<ELF64BE>();
|
case ELF64BEKind:
|
||||||
|
return getElfSymbols<ELF64BE>();
|
||||||
|
default:
|
||||||
|
llvm_unreachable("getELFKind");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template void ArchiveFile::parse<ELF32LE>();
|
template void ArchiveFile::parse<ELF32LE>();
|
||||||
|
|
|
@ -156,7 +156,7 @@ public:
|
||||||
ArrayRef<SymbolBody *> getSymbols();
|
ArrayRef<SymbolBody *> getSymbols();
|
||||||
ArrayRef<SymbolBody *> getLocalSymbols();
|
ArrayRef<SymbolBody *> getLocalSymbols();
|
||||||
|
|
||||||
explicit ObjectFile(MemoryBufferRef M);
|
ObjectFile(MemoryBufferRef M, StringRef ArchiveName);
|
||||||
void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
|
void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
|
||||||
|
|
||||||
InputSectionBase *getSection(const Elf_Sym &Sym) const;
|
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.
|
// Add symbols in File to the symbol table.
|
||||||
template <class ELFT> void SymbolTable<ELFT>::addFile(InputFile *File) {
|
template <class ELFT> void SymbolTable<ELFT>::addFile(InputFile *File) {
|
||||||
|
if (!Config->FirstElf && isa<ELFFileBase<ELFT>>(File))
|
||||||
|
Config->FirstElf = File;
|
||||||
|
|
||||||
if (!isCompatible<ELFT>(File))
|
if (!isCompatible<ELFT>(File))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue