summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2016-10-27 14:00:51 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2016-10-27 14:00:51 +0000
commit7cc713adcb668c23cbac71cfd7f268dd5afb618d (patch)
tree344e03452b13a92021f49bbee335444c19ce5960
parentf21dd2648f9b0d05c9b19d767664825ca5411183 (diff)
downloadbcm5719-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.h1
-rw-r--r--lld/ELF/Driver.cpp13
-rw-r--r--lld/ELF/InputFiles.cpp1
-rw-r--r--lld/ELF/InputFiles.h5
-rw-r--r--lld/ELF/Writer.cpp6
-rw-r--r--lld/test/ELF/emulation.s3
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)
OpenPOWER on IntegriCloud