summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Driver.cpp16
-rw-r--r--lld/ELF/InputFiles.cpp57
-rw-r--r--lld/ELF/InputFiles.h7
-rw-r--r--lld/ELF/SymbolTable.cpp2
-rw-r--r--lld/ELF/Writer.cpp2
5 files changed, 43 insertions, 41 deletions
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 72e119ab7aa..68f89b65dfe 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -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 &&
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index feae964d60c..786604c8d6b 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -44,18 +44,20 @@ 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)
return Elf_Sym_Range(nullptr, nullptr);
@@ -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) {
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index d009d94f3a2..6ba2767ff96 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -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];
}
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index 557b1128e60..787976f83d0 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -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;
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 4cafa8abb46..849a67f03ae 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -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;
OpenPOWER on IntegriCloud