diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2016-10-27 14:00:51 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2016-10-27 14:00:51 +0000 |
commit | 7cc713adcb668c23cbac71cfd7f268dd5afb618d (patch) | |
tree | 344e03452b13a92021f49bbee335444c19ce5960 | |
parent | f21dd2648f9b0d05c9b19d767664825ca5411183 (diff) | |
download | bcm5719-llvm-7cc713adcb668c23cbac71cfd7f268dd5afb618d.tar.gz bcm5719-llvm-7cc713adcb668c23cbac71cfd7f268dd5afb618d.zip |
Store OSABI in Config.
This allows us to set a value for it based on -m.
llvm-svn: 285294
-rw-r--r-- | lld/ELF/Config.h | 1 | ||||
-rw-r--r-- | lld/ELF/Driver.cpp | 13 | ||||
-rw-r--r-- | lld/ELF/InputFiles.cpp | 1 | ||||
-rw-r--r-- | lld/ELF/InputFiles.h | 5 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 6 | ||||
-rw-r--r-- | lld/test/ELF/emulation.s | 3 |
6 files changed, 17 insertions, 12 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 96eebac97bd..3b9f716c7b0 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -70,6 +70,7 @@ struct VersionDefinition { // Most fields are initialized by the driver. struct Configuration { InputFile *FirstElf = nullptr; + uint8_t OSABI = 0; llvm::StringMap<uint64_t> SectionStartMap; llvm::StringRef DynamicLinker; llvm::StringRef Entry; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index d4915928040..ac31f12d804 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -58,10 +58,13 @@ bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly, } // Parses a linker -m option. -static std::pair<ELFKind, uint16_t> parseEmulation(StringRef Emul) { +static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef Emul) { + uint8_t OSABI = 0; StringRef S = Emul; - if (S.endswith("_fbsd")) + if (S.endswith("_fbsd")) { S = S.drop_back(5); + OSABI = ELFOSABI_FREEBSD; + } std::pair<ELFKind, uint16_t> Ret = StringSwitch<std::pair<ELFKind, uint16_t>>(S) @@ -85,7 +88,7 @@ static std::pair<ELFKind, uint16_t> parseEmulation(StringRef Emul) { else error("unknown emulation: " + Emul); } - return Ret; + return std::make_tuple(Ret.first, Ret.second, OSABI); } // Returns slices of MB by parsing MB as an archive file. @@ -455,7 +458,8 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { if (auto *Arg = Args.getLastArg(OPT_m)) { // Parse ELF{32,64}{LE,BE} and CPU type. StringRef S = Arg->getValue(); - std::tie(Config->EKind, Config->EMachine) = parseEmulation(S); + std::tie(Config->EKind, Config->EMachine, Config->OSABI) = + parseEmulation(S); Config->Emulation = S; } @@ -649,6 +653,7 @@ void LinkerDriver::inferMachineType() { continue; Config->EKind = F->EKind; Config->EMachine = F->EMachine; + Config->OSABI = F->OSABI; return; } error("target emulation unknown: -m or at least one .o file required"); diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index b0c177fc48c..34e55efd6fa 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -106,6 +106,7 @@ ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef MB) : InputFile(K, MB), ELFObj(createELFObj<ELFT>(MB)) { EKind = getELFKind<ELFT>(); EMachine = ELFObj.getHeader()->e_machine; + OSABI = ELFObj.getHeader()->e_ident[llvm::ELF::EI_OSABI]; } template <class ELFT> diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 083e86772b8..69fce665e62 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -108,6 +108,7 @@ public: // have ELF type (i.e. ELF{32,64}{LE,BE}) and target machine type. ELFKind EKind = ELFNoneKind; uint16_t EMachine = llvm::ELF::EM_NONE; + uint8_t OSABI = 0; static void freePool(); @@ -143,10 +144,6 @@ public: const llvm::object::ELFFile<ELFT> &getObj() const { return ELFObj; } llvm::object::ELFFile<ELFT> &getObj() { return ELFObj; } - uint8_t getOSABI() const { - return getObj().getHeader()->e_ident[llvm::ELF::EI_OSABI]; - } - StringRef getStringTable() const { return StringTable; } uint32_t getSectionIndex(const Elf_Sym &Sym) const; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 8a39398587b..67ca8cdc1d4 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -1339,16 +1339,14 @@ template <class ELFT> void Writer<ELFT>::writeHeader() { uint8_t *Buf = Buffer->getBufferStart(); memcpy(Buf, "\177ELF", 4); - auto &FirstObj = cast<ELFFileBase<ELFT>>(*Config->FirstElf); - // Write the ELF header. auto *EHdr = reinterpret_cast<Elf_Ehdr *>(Buf); EHdr->e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32; EHdr->e_ident[EI_DATA] = getELFEncoding<ELFT>(); EHdr->e_ident[EI_VERSION] = EV_CURRENT; - EHdr->e_ident[EI_OSABI] = FirstObj.getOSABI(); + EHdr->e_ident[EI_OSABI] = Config->OSABI; EHdr->e_type = getELFType(); - EHdr->e_machine = FirstObj.EMachine; + EHdr->e_machine = Config->EMachine; EHdr->e_version = EV_CURRENT; EHdr->e_entry = getEntryAddr<ELFT>(); EHdr->e_shoff = SectionHeaderOff; diff --git a/lld/test/ELF/emulation.s b/lld/test/ELF/emulation.s index de9605048bc..a54faeaa832 100644 --- a/lld/test/ELF/emulation.s +++ b/lld/test/ELF/emulation.s @@ -3,6 +3,9 @@ # RUN: llvm-readobj -file-headers %t2x64 | FileCheck --check-prefix=AMD64 %s # RUN: ld.lld %tx64 -o %t3x64 # RUN: llvm-readobj -file-headers %t3x64 | FileCheck --check-prefix=AMD64 %s +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.sysv +# RUN: ld.lld -m elf_amd64_fbsd %t.sysv -o %t.freebsd +# RUN: llvm-readobj -file-headers %t.freebsd | FileCheck --check-prefix=AMD64 %s # AMD64: ElfHeader { # AMD64-NEXT: Ident { # AMD64-NEXT: Magic: (7F 45 4C 46) |