diff options
-rw-r--r-- | lld/ELF/Driver.cpp | 16 | ||||
-rw-r--r-- | lld/ELF/InputFiles.cpp | 57 | ||||
-rw-r--r-- | lld/ELF/InputFiles.h | 7 | ||||
-rw-r--r-- | lld/ELF/SymbolTable.cpp | 2 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 2 |
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; |