Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -11,17 +11,32 @@ #define LLD_ELF_CONFIG_H #include "llvm/ADT/StringRef.h" +#include "llvm/Object/ELF.h" +#include namespace lld { namespace elf2 { +enum ELFKind { ELF32LEKind, ELF32BEKind, ELF64LEKind, ELF64BEKind }; + struct Configuration { + bool Is64Bits() const { + return TargetELFKind == ELF64BEKind || TargetELFKind == ELF64LEKind; + } + bool IsBE() const { + return TargetELFKind == ELF64BEKind || TargetELFKind == ELF32BEKind; + } + llvm::StringRef OutputFile; llvm::StringRef DynamicLinker; std::string RPath; bool Shared = false; bool DiscardAll = false; bool DiscardLocals = false; + + // FIXME: Conditionally depends on host machine. + ELFKind TargetELFKind = ELF64LEKind; + uint16_t TargetEMachine = llvm::ELF::EM_X86_64; }; extern Configuration *Config; Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -15,6 +15,7 @@ #include "Writer.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/Object/ELF.h" #include "llvm/Support/FileSystem.h" using namespace llvm; @@ -35,6 +36,23 @@ } } +namespace { +using namespace ELF; + +struct Emulation { + const char *Name; + ELFKind TargetELFKind; + uint16_t TargetEMachine; +}; + +static const Emulation Emulations[] = { + {"elf_x86_64", ELF64LEKind, EM_X86_64}, + {"elf_i386", ELF32LEKind, EM_386}, + {"elf64ppc", ELF64BEKind, EM_PPC64}, + {"elf32ppc", ELF32BEKind, EM_PPC}, +}; +} + // Opens a file. Path has to be resolved already. // Newly created memory buffers are owned by this driver. MemoryBufferRef LinkerDriver::openFile(StringRef Path) { @@ -46,6 +64,30 @@ return MBRef; } +static uint16_t getElfMachineType(StringRef Object, bool IsBE) { + using namespace object; + + // First three fields of 32-bit and 64-bit ELF headers are of equal + // size, so no matter which one to use, but care about endianness. + if (Object.size() < (ELF::EI_NIDENT + 2 * sizeof(ELF::Elf32_Half))) + return ELF::EM_NONE; + if (IsBE) + return ((const Elf_Ehdr_Impl *)Object.data())->e_machine; + else + return ((const Elf_Ehdr_Impl *)Object.data())->e_machine; +} + +template