mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-01 13:20:25 +00:00
Refactor ELF type inference functions.
Previously, we initialized Config->EKind and Config->EMachine when we instantiate ELF objects. That was not an ideal location to do that because the logic was buried too deep inside a concrete logic. This patch moves the code to the driver so that the initialization becomes explicit. Differential Revision: http://reviews.llvm.org/D21784 llvm-svn: 274089
This commit is contained in:
parent
80a4702d02
commit
5e64d3fb94
@ -313,9 +313,6 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
|
||||
Config->Emulation = S;
|
||||
}
|
||||
|
||||
if (Config->EMachine == EM_MIPS && Config->EKind == ELF64LEKind)
|
||||
Config->Mips64EL = true;
|
||||
|
||||
Config->AllowMultipleDefinition = Args.hasArg(OPT_allow_multiple_definition);
|
||||
Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic);
|
||||
Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions);
|
||||
@ -470,6 +467,17 @@ void LinkerDriver::createFiles(opt::InputArgList &Args) {
|
||||
|
||||
if (Files.empty() && !HasError)
|
||||
error("no input files.");
|
||||
|
||||
// If -m <machine_type> was not given, infer it from object files.
|
||||
if (Config->EKind == ELFNoneKind) {
|
||||
for (std::unique_ptr<InputFile> &F : Files) {
|
||||
if (F->EKind == ELFNoneKind)
|
||||
continue;
|
||||
Config->EKind = F->EKind;
|
||||
Config->EMachine = F->EMachine;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do actual linking. Note that when this function is called,
|
||||
@ -484,6 +492,8 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
|
||||
Script<ELFT>::X = &LS;
|
||||
|
||||
Config->Rela = ELFT::Is64Bits;
|
||||
Config->Mips64EL =
|
||||
(Config->EMachine == EM_MIPS && Config->EKind == ELF64LEKind);
|
||||
|
||||
// Add entry symbol. Note that AMDGPU binaries have no entry points.
|
||||
if (Config->Entry.empty() && !Config->Shared && !Config->Relocatable &&
|
||||
|
@ -44,17 +44,19 @@ static ELFFile<ELFT> createELFObj(MemoryBufferRef MB) {
|
||||
return F;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef MB)
|
||||
: InputFile(K, MB), ELFObj(createELFObj<ELFT>(MB)) {}
|
||||
|
||||
template <class ELFT>
|
||||
ELFKind ELFFileBase<ELFT>::getELFKind() {
|
||||
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), ELFObj(createELFObj<ELFT>(MB)) {
|
||||
EKind = getELFKind<ELFT>();
|
||||
EMachine = ELFObj.getHeader()->e_machine;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
typename ELFT::SymRange ELFFileBase<ELFT>::getElfSymbols(bool OnlyGlobals) {
|
||||
if (!Symtab)
|
||||
@ -644,23 +646,6 @@ void BitcodeFile::parse(DenseSet<StringRef> &ComdatGroups) {
|
||||
Symbols.push_back(createSymbol<ELFT>(KeptComdats, *Obj, Sym));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static std::unique_ptr<InputFile> createELFFileAux(MemoryBufferRef MB) {
|
||||
std::unique_ptr<T> Ret = llvm::make_unique<T>(MB);
|
||||
|
||||
if (!Config->FirstElf)
|
||||
Config->FirstElf = Ret.get();
|
||||
|
||||
if (Config->EKind == ELFNoneKind) {
|
||||
Config->EKind = Ret->getELFKind();
|
||||
Config->EMachine = Ret->getEMachine();
|
||||
if (Config->EMachine == EM_MIPS && Config->EKind == ELF64LEKind)
|
||||
Config->Mips64EL = true;
|
||||
}
|
||||
|
||||
return std::move(Ret);
|
||||
}
|
||||
|
||||
template <template <class> class T>
|
||||
static std::unique_ptr<InputFile> createELFFile(MemoryBufferRef MB) {
|
||||
unsigned char Size;
|
||||
@ -669,17 +654,21 @@ static std::unique_ptr<InputFile> createELFFile(MemoryBufferRef MB) {
|
||||
if (Endian != ELFDATA2LSB && Endian != ELFDATA2MSB)
|
||||
fatal("invalid data encoding: " + MB.getBufferIdentifier());
|
||||
|
||||
if (Size == ELFCLASS32) {
|
||||
if (Endian == ELFDATA2LSB)
|
||||
return createELFFileAux<T<ELF32LE>>(MB);
|
||||
return createELFFileAux<T<ELF32BE>>(MB);
|
||||
}
|
||||
if (Size == ELFCLASS64) {
|
||||
if (Endian == ELFDATA2LSB)
|
||||
return createELFFileAux<T<ELF64LE>>(MB);
|
||||
return createELFFileAux<T<ELF64BE>>(MB);
|
||||
}
|
||||
fatal("invalid file class: " + MB.getBufferIdentifier());
|
||||
std::unique_ptr<InputFile> Obj;
|
||||
if (Size == ELFCLASS32 && Endian == ELFDATA2LSB)
|
||||
Obj.reset(new T<ELF32LE>(MB));
|
||||
else if (Size == ELFCLASS32 && Endian == ELFDATA2MSB)
|
||||
Obj.reset(new T<ELF32BE>(MB));
|
||||
else if (Size == ELFCLASS64 && Endian == ELFDATA2LSB)
|
||||
Obj.reset(new T<ELF64LE>(MB));
|
||||
else if (Size == ELFCLASS64 && Endian == ELFDATA2MSB)
|
||||
Obj.reset(new T<ELF64BE>(MB));
|
||||
else
|
||||
fatal("invalid file class: " + MB.getBufferIdentifier());
|
||||
|
||||
if (!Config->FirstElf)
|
||||
Config->FirstElf = Obj.get();
|
||||
return Obj;
|
||||
}
|
||||
|
||||
static bool isBitcode(MemoryBufferRef MB) {
|
||||
|
@ -56,6 +56,11 @@ public:
|
||||
// string for creating error messages.
|
||||
StringRef ArchiveName;
|
||||
|
||||
// If this is an architecture-specific file, the following members
|
||||
// have ELF type (i.e. ELF{32,64}{LE,BE}) and target machine type.
|
||||
ELFKind EKind = ELFNoneKind;
|
||||
uint16_t EMachine = llvm::ELF::EM_NONE;
|
||||
|
||||
protected:
|
||||
InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {}
|
||||
|
||||
@ -79,11 +84,9 @@ public:
|
||||
return K == ObjectKind || K == SharedKind;
|
||||
}
|
||||
|
||||
static ELFKind getELFKind();
|
||||
const llvm::object::ELFFile<ELFT> &getObj() const { return ELFObj; }
|
||||
llvm::object::ELFFile<ELFT> &getObj() { return ELFObj; }
|
||||
|
||||
uint16_t getEMachine() const { return getObj().getHeader()->e_machine; }
|
||||
uint8_t getOSABI() const {
|
||||
return getObj().getHeader()->e_ident[llvm::ELF::EI_OSABI];
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ template <class ELFT> static bool isCompatible(InputFile *FileP) {
|
||||
auto *F = dyn_cast<ELFFileBase<ELFT>>(FileP);
|
||||
if (!F)
|
||||
return true;
|
||||
if (F->getELFKind() == Config->EKind && F->getEMachine() == Config->EMachine)
|
||||
if (F->EKind == Config->EKind && F->EMachine == Config->EMachine)
|
||||
return true;
|
||||
StringRef A = F->getName();
|
||||
StringRef B = Config->Emulation;
|
||||
|
@ -1304,7 +1304,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
|
||||
EHdr->e_ident[EI_VERSION] = EV_CURRENT;
|
||||
EHdr->e_ident[EI_OSABI] = FirstObj.getOSABI();
|
||||
EHdr->e_type = getELFType();
|
||||
EHdr->e_machine = FirstObj.getEMachine();
|
||||
EHdr->e_machine = FirstObj.EMachine;
|
||||
EHdr->e_version = EV_CURRENT;
|
||||
EHdr->e_entry = getEntryAddr<ELFT>();
|
||||
EHdr->e_shoff = SectionHeaderOff;
|
||||
|
Loading…
Reference in New Issue
Block a user