summaryrefslogtreecommitdiff
path: root/lib/ReaderWriter/ELF/Hexagon
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ReaderWriter/ELF/Hexagon')
-rw-r--r--lib/ReaderWriter/ELF/Hexagon/CMakeLists.txt11
-rw-r--r--lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h79
-rw-r--r--lib/ReaderWriter/ELF/Hexagon/HexagonELFFile.h170
-rw-r--r--lib/ReaderWriter/ELF/Hexagon/HexagonELFReader.h62
-rw-r--r--lib/ReaderWriter/ELF/Hexagon/HexagonELFWriters.h61
-rw-r--r--lib/ReaderWriter/ELF/Hexagon/HexagonEncodings.h601
-rw-r--r--lib/ReaderWriter/ELF/Hexagon/HexagonExecutableAtoms.h29
-rw-r--r--lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h86
-rw-r--r--lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp25
-rw-r--r--lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h69
-rw-r--r--lib/ReaderWriter/ELF/Hexagon/HexagonRelocationFunctions.h49
-rw-r--r--lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp350
-rw-r--r--lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h35
-rw-r--r--lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h86
-rw-r--r--lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp334
-rw-r--r--lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h143
-rw-r--r--lib/ReaderWriter/ELF/Hexagon/Makefile16
17 files changed, 2206 insertions, 0 deletions
diff --git a/lib/ReaderWriter/ELF/Hexagon/CMakeLists.txt b/lib/ReaderWriter/ELF/Hexagon/CMakeLists.txt
new file mode 100644
index 0000000000000..6928f43c54592
--- /dev/null
+++ b/lib/ReaderWriter/ELF/Hexagon/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_llvm_library(lldHexagonELFTarget
+ HexagonLinkingContext.cpp
+ HexagonRelocationHandler.cpp
+ HexagonTargetHandler.cpp
+ LINK_LIBS
+ lldELF
+ lldReaderWriter
+ lldCore
+ LLVMObject
+ LLVMSupport
+ )
diff --git a/lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h b/lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h
new file mode 100644
index 0000000000000..e2d3193045b75
--- /dev/null
+++ b/lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h
@@ -0,0 +1,79 @@
+//===- lib/ReaderWriter/ELF/Hexagon/HexagonDynamicLibraryWriter.h ---------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef HEXAGON_DYNAMIC_LIBRARY_WRITER_H
+#define HEXAGON_DYNAMIC_LIBRARY_WRITER_H
+
+#include "DynamicLibraryWriter.h"
+#include "HexagonExecutableAtoms.h"
+#include "HexagonLinkingContext.h"
+
+namespace lld {
+namespace elf {
+
+template <typename ELFT> class HexagonTargetLayout;
+
+template <class ELFT>
+class HexagonDynamicLibraryWriter : public DynamicLibraryWriter<ELFT>,
+ public HexagonELFWriter<ELFT> {
+public:
+ HexagonDynamicLibraryWriter(HexagonLinkingContext &context,
+ HexagonTargetLayout<ELFT> &layout);
+
+protected:
+ // Add any runtime files and their atoms to the output
+ virtual bool createImplicitFiles(std::vector<std::unique_ptr<File>> &);
+
+ virtual void finalizeDefaultAtomValues();
+
+ virtual std::error_code setELFHeader() {
+ DynamicLibraryWriter<ELFT>::setELFHeader();
+ HexagonELFWriter<ELFT>::setELFHeader(*this->_elfHeader);
+ return std::error_code();
+ }
+
+private:
+ void addDefaultAtoms() {
+ _hexagonRuntimeFile->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
+ _hexagonRuntimeFile->addAbsoluteAtom("_DYNAMIC");
+ }
+
+ HexagonLinkingContext &_hexagonLinkingContext;
+ HexagonTargetLayout<ELFT> &_hexagonTargetLayout;
+ std::unique_ptr<HexagonRuntimeFile<ELFT>> _hexagonRuntimeFile;
+};
+
+template <class ELFT>
+HexagonDynamicLibraryWriter<ELFT>::HexagonDynamicLibraryWriter(
+ HexagonLinkingContext &context, HexagonTargetLayout<ELFT> &layout)
+ : DynamicLibraryWriter<ELFT>(context, layout),
+ HexagonELFWriter<ELFT>(context, layout), _hexagonLinkingContext(context),
+ _hexagonTargetLayout(layout),
+ _hexagonRuntimeFile(new HexagonRuntimeFile<ELFT>(context)) {}
+
+template <class ELFT>
+bool HexagonDynamicLibraryWriter<ELFT>::createImplicitFiles(
+ std::vector<std::unique_ptr<File>> &result) {
+ DynamicLibraryWriter<ELFT>::createImplicitFiles(result);
+ // Add the default atoms as defined for hexagon
+ addDefaultAtoms();
+ result.push_back(std::move(_hexagonRuntimeFile));
+ return true;
+}
+
+template <class ELFT>
+void HexagonDynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues() {
+ // Finalize the atom values that are part of the parent.
+ DynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues();
+ HexagonELFWriter<ELFT>::finalizeHexagonRuntimeAtomValues();
+}
+
+} // namespace elf
+} // namespace lld
+
+#endif // HEXAGON_DYNAMIC_LIBRARY_WRITER_H
diff --git a/lib/ReaderWriter/ELF/Hexagon/HexagonELFFile.h b/lib/ReaderWriter/ELF/Hexagon/HexagonELFFile.h
new file mode 100644
index 0000000000000..ab0b9b432b430
--- /dev/null
+++ b/lib/ReaderWriter/ELF/Hexagon/HexagonELFFile.h
@@ -0,0 +1,170 @@
+//===- lib/ReaderWriter/ELF/HexagonELFFile.h ------------------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_READER_WRITER_ELF_HEXAGON_ELF_FILE_H
+#define LLD_READER_WRITER_ELF_HEXAGON_ELF_FILE_H
+
+#include "ELFReader.h"
+#include "HexagonLinkingContext.h"
+
+namespace lld {
+namespace elf {
+
+template <class ELFT> class HexagonELFFile;
+
+template <class ELFT>
+class HexagonELFDefinedAtom : public ELFDefinedAtom<ELFT> {
+ typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
+ typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
+
+public:
+ HexagonELFDefinedAtom(const HexagonELFFile<ELFT> &file, StringRef symbolName,
+ StringRef sectionName, const Elf_Sym *symbol,
+ const Elf_Shdr *section, ArrayRef<uint8_t> contentData,
+ unsigned int referenceStart, unsigned int referenceEnd,
+ std::vector<ELFReference<ELFT> *> &referenceList)
+ : ELFDefinedAtom<ELFT>(file, symbolName, sectionName, symbol, section,
+ contentData, referenceStart, referenceEnd,
+ referenceList) {}
+
+ virtual DefinedAtom::ContentType contentType() const {
+ if (this->_contentType != DefinedAtom::typeUnknown)
+ return this->_contentType;
+ else if (this->_section->sh_flags & llvm::ELF::SHF_HEX_GPREL) {
+ if (this->_section->sh_type == llvm::ELF::SHT_NOBITS)
+ return (this->_contentType = DefinedAtom::typeZeroFillFast);
+ else
+ return (this->_contentType = DefinedAtom::typeDataFast);
+ }
+ return ELFDefinedAtom<ELFT>::contentType();
+ }
+
+ virtual DefinedAtom::ContentPermissions permissions() const {
+ if (this->_section->sh_flags & llvm::ELF::SHF_HEX_GPREL)
+ return DefinedAtom::permRW_;
+ return ELFDefinedAtom<ELFT>::permissions();
+ }
+};
+
+template <class ELFT> class HexagonELFCommonAtom : public ELFCommonAtom<ELFT> {
+ typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
+ typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
+
+public:
+ HexagonELFCommonAtom(const HexagonELFFile<ELFT> &file, StringRef symbolName,
+ const Elf_Sym *symbol)
+ : ELFCommonAtom<ELFT>(file, symbolName, symbol) {}
+
+ virtual bool isSmallCommonSymbol() const {
+ switch (this->_symbol->st_shndx) {
+ // Common symbols
+ case llvm::ELF::SHN_HEXAGON_SCOMMON:
+ case llvm::ELF::SHN_HEXAGON_SCOMMON_1:
+ case llvm::ELF::SHN_HEXAGON_SCOMMON_2:
+ case llvm::ELF::SHN_HEXAGON_SCOMMON_4:
+ case llvm::ELF::SHN_HEXAGON_SCOMMON_8:
+ return true;
+ default:
+ break;
+ }
+ return false;
+ }
+
+ virtual uint64_t size() const {
+ if (isSmallCommonSymbol())
+ return this->_symbol->st_size;
+ return ELFCommonAtom<ELFT>::size();
+ }
+
+ virtual DefinedAtom::Merge merge() const {
+ if (this->_symbol->getBinding() == llvm::ELF::STB_WEAK)
+ return DefinedAtom::mergeAsWeak;
+ if (isSmallCommonSymbol())
+ return DefinedAtom::mergeAsTentative;
+ return ELFCommonAtom<ELFT>::merge();
+ }
+
+ virtual DefinedAtom::ContentType contentType() const {
+ if (isSmallCommonSymbol())
+ return DefinedAtom::typeZeroFillFast;
+ return ELFCommonAtom<ELFT>::contentType();
+ }
+
+ virtual DefinedAtom::Alignment alignment() const {
+ if (isSmallCommonSymbol())
+ return DefinedAtom::Alignment(llvm::Log2_64(this->_symbol->st_value));
+ return ELFCommonAtom<ELFT>::alignment();
+ }
+
+ virtual DefinedAtom::ContentPermissions permissions() const {
+ if (isSmallCommonSymbol())
+ return DefinedAtom::permRW_;
+ return ELFCommonAtom<ELFT>::permissions();
+ }
+};
+
+template <class ELFT> class HexagonELFFile : public ELFFile<ELFT> {
+ typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
+ typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
+
+public:
+ HexagonELFFile(std::unique_ptr<MemoryBuffer> mb, HexagonLinkingContext &ctx)
+ : ELFFile<ELFT>(std::move(mb), ctx) {}
+
+ static ErrorOr<std::unique_ptr<HexagonELFFile>>
+ create(std::unique_ptr<MemoryBuffer> mb, HexagonLinkingContext &ctx) {
+ return std::unique_ptr<HexagonELFFile<ELFT>>(
+ new HexagonELFFile<ELFT>(std::move(mb), ctx));
+ }
+
+ bool isCommonSymbol(const Elf_Sym *symbol) const override {
+ switch (symbol->st_shndx) {
+ // Common symbols
+ case llvm::ELF::SHN_HEXAGON_SCOMMON:
+ case llvm::ELF::SHN_HEXAGON_SCOMMON_1:
+ case llvm::ELF::SHN_HEXAGON_SCOMMON_2:
+ case llvm::ELF::SHN_HEXAGON_SCOMMON_4:
+ case llvm::ELF::SHN_HEXAGON_SCOMMON_8:
+ return true;
+ default:
+ break;
+ }
+ return ELFFile<ELFT>::isCommonSymbol(symbol);
+ }
+
+ /// Process the Defined symbol and create an atom for it.
+ ErrorOr<ELFDefinedAtom<ELFT> *>
+ handleDefinedSymbol(StringRef symName, StringRef sectionName,
+ const Elf_Sym *sym, const Elf_Shdr *sectionHdr,
+ ArrayRef<uint8_t> contentData,
+ unsigned int referenceStart, unsigned int referenceEnd,
+ std::vector<ELFReference<ELFT> *> &referenceList) override {
+ return new (this->_readerStorage) HexagonELFDefinedAtom<ELFT>(
+ *this, symName, sectionName, sym, sectionHdr, contentData,
+ referenceStart, referenceEnd, referenceList);
+ }
+
+ /// Process the Common symbol and create an atom for it.
+ ErrorOr<ELFCommonAtom<ELFT> *>
+ handleCommonSymbol(StringRef symName, const Elf_Sym *sym) override {
+ return new (this->_readerStorage)
+ HexagonELFCommonAtom<ELFT>(*this, symName, sym);
+ }
+};
+
+template <class ELFT> class HexagonDynamicFile : public DynamicFile<ELFT> {
+public:
+ HexagonDynamicFile(const HexagonLinkingContext &context, StringRef name)
+ : DynamicFile<ELFT>(context, name) {}
+};
+
+} // elf
+} // lld
+
+#endif // LLD_READER_WRITER_ELF_HEXAGON_ELF_FILE_H
diff --git a/lib/ReaderWriter/ELF/Hexagon/HexagonELFReader.h b/lib/ReaderWriter/ELF/Hexagon/HexagonELFReader.h
new file mode 100644
index 0000000000000..1a4f891df7997
--- /dev/null
+++ b/lib/ReaderWriter/ELF/Hexagon/HexagonELFReader.h
@@ -0,0 +1,62 @@
+//===- lib/ReaderWriter/ELF/HexagonELFReader.h ----------------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_READER_WRITER_HEXAGON_ELF_READER_H
+#define LLD_READER_WRITER_HEXAGON_ELF_READER_H
+
+#include "ELFReader.h"
+#include "HexagonELFFile.h"
+
+namespace lld {
+namespace elf {
+
+typedef llvm::object::ELFType<llvm::support::little, 2, false> HexagonELFType;
+
+struct HexagonDynamicFileCreateELFTraits {
+ typedef llvm::ErrorOr<std::unique_ptr<lld::SharedLibraryFile>> result_type;
+
+ template <class ELFT>
+ static result_type create(std::unique_ptr<llvm::MemoryBuffer> mb,
+ HexagonLinkingContext &ctx) {
+ return lld::elf::HexagonDynamicFile<ELFT>::create(std::move(mb), ctx);
+ }
+};
+
+struct HexagonELFFileCreateELFTraits {
+ typedef llvm::ErrorOr<std::unique_ptr<lld::File>> result_type;
+
+ template <class ELFT>
+ static result_type create(std::unique_ptr<llvm::MemoryBuffer> mb,
+ HexagonLinkingContext &ctx) {
+ return lld::elf::HexagonELFFile<ELFT>::create(std::move(mb), ctx);
+ }
+};
+
+class HexagonELFObjectReader
+ : public ELFObjectReader<HexagonELFType, HexagonELFFileCreateELFTraits,
+ HexagonLinkingContext> {
+public:
+ HexagonELFObjectReader(HexagonLinkingContext &ctx)
+ : ELFObjectReader<HexagonELFType, HexagonELFFileCreateELFTraits,
+ HexagonLinkingContext>(ctx, llvm::ELF::EM_HEXAGON) {}
+};
+
+class HexagonELFDSOReader
+ : public ELFDSOReader<HexagonELFType, HexagonDynamicFileCreateELFTraits,
+ HexagonLinkingContext> {
+public:
+ HexagonELFDSOReader(HexagonLinkingContext &ctx)
+ : ELFDSOReader<HexagonELFType, HexagonDynamicFileCreateELFTraits,
+ HexagonLinkingContext>(ctx, llvm::ELF::EM_HEXAGON) {}
+};
+
+} // namespace elf
+} // namespace lld
+
+#endif // LLD_READER_WRITER_ELF_READER_H
diff --git a/lib/ReaderWriter/ELF/Hexagon/HexagonELFWriters.h b/lib/ReaderWriter/ELF/Hexagon/HexagonELFWriters.h
new file mode 100644
index 0000000000000..96c74f72222dc
--- /dev/null
+++ b/lib/ReaderWriter/ELF/Hexagon/HexagonELFWriters.h
@@ -0,0 +1,61 @@
+//===- lib/ReaderWriter/ELF/Hexagon/HexagonELFWriters.h -------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef HEXAGON_ELF_WRITERS_H
+#define HEXAGON_ELF_WRITERS_H
+
+#include "HexagonLinkingContext.h"
+#include "OutputELFWriter.h"
+
+namespace lld {
+namespace elf {
+
+template <class ELFT> class HexagonTargetLayout;
+
+template <typename ELFT> class HexagonELFWriter {
+public:
+ HexagonELFWriter(HexagonLinkingContext &context,
+ HexagonTargetLayout<ELFT> &targetLayout)
+ : _hexagonLinkingContext(context), _hexagonTargetLayout(targetLayout) {}
+
+protected:
+ bool setELFHeader(ELFHeader<ELFT> &elfHeader) {
+ elfHeader.e_ident(llvm::ELF::EI_VERSION, 1);
+ elfHeader.e_ident(llvm::ELF::EI_OSABI, 0);
+ elfHeader.e_version(1);
+ elfHeader.e_flags(0x3);
+ return true;
+ }
+
+ void finalizeHexagonRuntimeAtomValues() {
+ if (_hexagonLinkingContext.isDynamic()) {
+ auto gotAtomIter =
+ _hexagonTargetLayout.findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
+ auto gotpltSection = _hexagonTargetLayout.findOutputSection(".got.plt");
+ if (gotpltSection)
+ (*gotAtomIter)->_virtualAddr = gotpltSection->virtualAddr();
+ else
+ (*gotAtomIter)->_virtualAddr = 0;
+ auto dynamicAtomIter = _hexagonTargetLayout.findAbsoluteAtom("_DYNAMIC");
+ auto dynamicSection = _hexagonTargetLayout.findOutputSection(".dynamic");
+ if (dynamicSection)
+ (*dynamicAtomIter)->_virtualAddr = dynamicSection->virtualAddr();
+ else
+ (*dynamicAtomIter)->_virtualAddr = 0;
+ }
+ }
+
+private:
+ HexagonLinkingContext &_hexagonLinkingContext;
+ HexagonTargetLayout<ELFT> &_hexagonTargetLayout;
+};
+
+} // elf
+} // lld
+#endif // HEXAGON_ELF_WRITERS_H
diff --git a/lib/ReaderWriter/ELF/Hexagon/HexagonEncodings.h b/lib/ReaderWriter/ELF/Hexagon/HexagonEncodings.h
new file mode 100644
index 0000000000000..3e12786704a25
--- /dev/null
+++ b/lib/ReaderWriter/ELF/Hexagon/HexagonEncodings.h
@@ -0,0 +1,601 @@
+//===- lib/ReaderWriter/ELF/Hexagon/HexagonEncodings.h -------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+Instruction insn_encodings[] = {
+ { 0xffe00004, 0x40000000, 0x20f8, 0x0 },
+ { 0xffe03080, 0x9ca03080, 0xf60, 0x0 },
+ { 0xf9e00000, 0x48c00000, 0x61f20ff, 0x0 },
+ { 0xf7c02300, 0x13802100, 0x3000fe, 0x0 },
+ { 0xffe00000, 0x60c00000, 0x1f18, 0x0 },
+ { 0xffe00000, 0x69c00000, 0x1f18, 0x0 },
+ { 0xffe02000, 0x43000000, 0x7e0, 0x0 },
+ { 0xff602060, 0x3e000060, 0x1f80, 0x0 },
+ { 0xffe03000, 0x9ae01000, 0xf60, 0x0 },
+ { 0xf9e00000, 0x91600000, 0x6003fe0, 0x0 },
+ { 0xffe02084, 0xaf000084, 0x30078, 0x0 },
+ { 0xff602060, 0x3e000020, 0x1f80, 0x0 },
+ { 0xff602060, 0x3e200040, 0x1f80, 0x0 },
+ { 0xf7c02000, 0x10c02000, 0x3000fe, 0x0 },
+ { 0xffe00000, 0x60200000, 0x1f18, 0x0 },
+ { 0xffe00000, 0x69200000, 0x1f18, 0x0 },
+ { 0xffe038c0, 0xada00880, 0x3f, 0x0 },
+ { 0xff602000, 0x73002000, 0x1fe0, 0x0 },
+ { 0xf7c02000, 0x26c02000, 0x3000fe, 0x0 },
+ { 0xffe03880, 0x9f403880, 0x1f0100, 0x0 },
+ { 0xf9e00000, 0x48400000, 0x61f20ff, 0x0 },
+ { 0xffe02000, 0x41600000, 0x7e0, 0x0 },
+ { 0xffe02084, 0xaf000080, 0x30078, 0x0 },
+ { 0xf7c02300, 0x13800100, 0x3000fe, 0x0 },
+ { 0xffe01804, 0x46a00000, 0x20f8, 0x0 },
+ { 0xffe00004, 0x42400000, 0x20f8, 0x0 },
+ { 0xf7c02000, 0x22400000, 0x3000fe, 0x0 },
+ { 0xf7c02000, 0x12402000, 0x3000fe, 0x0 },
+ { 0xfc003d18, 0x28003c18, 0x3f00000, 0x1 },
+ { 0xffe00000, 0x39000000, 0x201f, 0x0 },
+ { 0xff601018, 0xdd400008, 0xfe0, 0x0 },
+ { 0xffc0001c, 0x75400000, 0x203fe0, 0x0 },
+ { 0xfc003fc7, 0x48003f47, 0x3f00000, 0x1 },
+ { 0xffe03080, 0x9ca03000, 0xf60, 0x0 },
+ { 0xf9e00000, 0x90800000, 0x6003fe0, 0x0 },
+ { 0xf8003fc7, 0x40003fc4, 0x7f00000, 0x1 },
+ { 0xfc003e00, 0x68003c00, 0x3f00000, 0x1 },
+ { 0xf8003fc7, 0x40003fc5, 0x7f00000, 0x1 },
+ { 0xf9e00000, 0x91800000, 0x6003fe0, 0x0 },
+ { 0xff602060, 0x3e400060, 0x1f80, 0x0 },
+ { 0xff602060, 0x3e000000, 0x1f80, 0x0 },
+ { 0xf8003d18, 0x20003c18, 0x7f00000, 0x1 },
+ { 0xf8003f00, 0x20003800, 0x7f00000, 0x1 },
+ { 0xf8003d18, 0x20003c10, 0x7f00000, 0x1 },
+ { 0xff602000, 0x73602000, 0x1fe0, 0x0 },
+ { 0xffe03880, 0x9f002080, 0x1f0100, 0x0 },
+ { 0xffe02000, 0x47000000, 0x7e0, 0x0 },
+ { 0xf9e00000, 0x91400000, 0x6003fe0, 0x0 },
+ { 0xffe02080, 0xabc00080, 0x3f, 0x0 },
+ { 0xf7c02000, 0x20802000, 0x3000fe, 0x0 },
+ { 0xf8003fc7, 0x40003f44, 0x7f00000, 0x1 },
+ { 0xffe03884, 0xafa03084, 0x30078, 0x0 },
+ { 0xffe03000, 0x9b001000, 0xf60, 0x0 },
+ { 0xffe01804, 0x42a00800, 0x20f8, 0x0 },
+ { 0xfc003f00, 0x28003100, 0x3f00000, 0x1 },
+ { 0xffe02080, 0xab800080, 0x3f, 0x0 },
+ { 0xf7c02000, 0x24c00000, 0x3000fe, 0x0 },
+ { 0xffe00000, 0x39a00000, 0x201f, 0x0 },
+ { 0xf7c02300, 0x13802300, 0x3000fe, 0x0 },
+ { 0xffe01804, 0x46a00800, 0x20f8, 0x0 },
+ { 0xffe020c0, 0xad602080, 0x3f, 0x0 },
+ { 0xfc003f00, 0x28003500, 0x3f00000, 0x1 },
+ { 0xfc003f00, 0x28003400, 0x3f00000, 0x1 },
+ { 0xffe020c0, 0xad6000c0, 0x3f, 0x0 },
+ { 0xffe00000, 0x60000000, 0x1f18, 0x0 },
+ { 0xf8003000, 0x40000000, 0x7f00000, 0x1 },
+ { 0xffe00000, 0x69000000, 0x1f18, 0x0 },
+ { 0xffe03080, 0x9c601080, 0xf60, 0x0 },
+ { 0xffe03080, 0x9ce01000, 0xf60, 0x0 },
+ { 0xffe03080, 0x9c601000, 0xf60, 0x0 },
+ { 0xf7c02000, 0x13402000, 0x3000fe, 0x0 },
+ { 0xffe03080, 0x9c603000, 0xf60, 0x0 },
+ { 0xf7c02000, 0x21c00000, 0x3000fe, 0x0 },
+ { 0xfc003000, 0x68000000, 0x3f00000, 0x1 },
+ { 0xf8003800, 0x60002000, 0x7f00000, 0x1 },
+ { 0xffe02084, 0xaf802084, 0x30078, 0x0 },
+ { 0xfc003000, 0x48000000, 0x3f00000, 0x1 },
+ { 0xf7c02300, 0x11c02100, 0x3000fe, 0x0 },
+ { 0xf7c02000, 0x12800000, 0x3000fe, 0x0 },
+ { 0xfc003e70, 0x28003a40, 0x3f00000, 0x1 },
+ { 0xfc003f00, 0x28003300, 0x3f00000, 0x1 },
+ { 0xff800000, 0xe0000000, 0x1fe0, 0x0 },
+ { 0xff602060, 0x3f400000, 0x1f80, 0x0 },
+ { 0xffe00004, 0x42000000, 0x20f8, 0x0 },
+ { 0xf8003f00, 0x60003300, 0x7f00000, 0x1 },
+ { 0xffe01804, 0x42a00000, 0x20f8, 0x0 },
+ { 0xf7c02000, 0x12c00000, 0x3000fe, 0x0 },
+ { 0xf0000000, 0x0, 0xfff3fff, 0x0 },
+ { 0xff000016, 0xde000016, 0xe020e8, 0x0 },
+ { 0xffe03000, 0x9b201000, 0xf60, 0x0 },
+ { 0xffe03880, 0xaba00880, 0x3f, 0x0 },
+ { 0xf8003e00, 0x40003c00, 0x7f00000, 0x1 },
+ { 0xff602060, 0x3f200040, 0x1f80, 0x0 },
+ { 0xffe03880, 0x9f203880, 0x1f0100, 0x0 },
+ { 0xf7c02000, 0x20c00000, 0x3000fe, 0x0 },
+ { 0xf9e01800, 0x48a00800, 0x61f20ff, 0x0 },
+ { 0xf9e00000, 0x90a00000, 0x6003fe0, 0x0 },
+ { 0xff802000, 0x74802000, 0x1fe0, 0x0 },
+ { 0xffe03000, 0x9a401000, 0xf60, 0x0 },
+ { 0xf7c02000, 0x10002000, 0x3000fe, 0x0 },
+ { 0xf7c03000, 0x14803000, 0x3000fe, 0x0 },
+ { 0xffe020c0, 0xad0020c0, 0x3f, 0x0 },
+ { 0xffe0001c, 0x75800000, 0x3fe0, 0x0 },
+ { 0xf9e01800, 0x48a01000, 0x61f20ff, 0x0 },
+ { 0xffe03080, 0x9dc03000, 0xf60, 0x0 },
+ { 0xffe03080, 0x9dc03080, 0xf60, 0x0 },
+ { 0xffe03080, 0x9dc01000, 0xf60, 0x0 },
+ { 0xffe03080, 0x9dc01080, 0xf60, 0x0 },
+ { 0xffe03080, 0x9d601000, 0xf60, 0x0 },
+ { 0xffe03080, 0x9d601080, 0xf60, 0x0 },
+ { 0xffe03080, 0x9d603000, 0xf60, 0x0 },
+ { 0xffe03080, 0x9d603080, 0xf60, 0x0 },
+ { 0xfc003e00, 0x48003c00, 0x3f00000, 0x1 },
+ { 0xffe02084, 0xaf402084, 0x30078, 0x0 },
+ { 0xffe00004, 0x46600000, 0x20f8, 0x0 },
+ { 0xffe03880, 0x9f203080, 0x1f0100, 0x0 },
+ { 0xf8003f00, 0x20003100, 0x7f00000, 0x1 },
+ { 0xf7c02000, 0x11402000, 0x3000fe, 0x0 },
+ { 0xf8003d08, 0x20003d00, 0x7f00000, 0x1 },
+ { 0xffe03080, 0x9ca01080, 0xf60, 0x0 },
+ { 0xffe03080, 0x9ca01000, 0xf60, 0x0 },
+ { 0xffe00000, 0x38a00000, 0x201f, 0x0 },
+ { 0xf7c02300, 0x11800000, 0x3000fe, 0x0 },
+ { 0xf7c02300, 0x13c02300, 0x3000fe, 0x0 },
+ { 0xffe03080, 0x9ce03000, 0xf60, 0x0 },
+ { 0xf9e00000, 0x90e00000, 0x6003fe0, 0x0 },
+ { 0xffe02084, 0xaf400080, 0x30078, 0x0 },
+ { 0xffe03080, 0x9ce03080, 0xf60, 0x0 },
+ { 0xff000000, 0x78000000, 0xdf3fe0, 0x0 },
+ { 0xffe03080, 0x9ce01080, 0xf60, 0x0 },
+ { 0xffe03880, 0xaba01080, 0x3f, 0x0 },
+ { 0xffe020c0, 0xad002080, 0x3f, 0x0 },
+ { 0xffe020c0, 0xad0000c0, 0x3f, 0x0 },
+ { 0xffe020c0, 0xad000080, 0x3f, 0x0 },
+ { 0xf7c02000, 0x25000000, 0x3000fe, 0x0 },
+ { 0xff602060, 0x3f200020, 0x1f80, 0x0 },
+ { 0xffe02084, 0xafc00084, 0x30078, 0x0 },
+ { 0xf7c02000, 0x24400000, 0x3000fe, 0x0 },
+ { 0xfc003000, 0x48001000, 0x3f00000, 0x1 },
+ { 0xf9e01800, 0xa1a01000, 0x60020ff, 0x0 },
+ { 0xff602060, 0x3f000040, 0x1f80, 0x0 },
+ { 0xffe02084, 0xaf602084, 0x30078, 0x0 },
+ { 0xf8003f00, 0x20003400, 0x7f00000, 0x1 },
+ { 0xffe02084, 0xaf400084, 0x30078, 0x0 },
+ { 0xffe01804, 0x44a01000, 0x20f8, 0x0 },
+ { 0xff602060, 0x3e200000, 0x1f80, 0x0 },
+ { 0xf8003e70, 0x20003a70, 0x7f00000, 0x1 },
+ { 0xf8003f00, 0x40003e00, 0x7f00000, 0x1 },
+ { 0xf8003f00, 0x20003300, 0x7f00000, 0x1 },
+ { 0xf7c02300, 0x13800300, 0x3000fe, 0x0 },
+ { 0xffe038c0, 0xada00080, 0x3f, 0x0 },
+ { 0xf9e00000, 0x49400000, 0x61f3fe0, 0x0 },
+ { 0xf8003800, 0x40002800, 0x7f00000, 0x1 },
+ { 0xffe038c0, 0xada020c0, 0x3f, 0x0 },
+ { 0xffe03884, 0xafa00880, 0x30078, 0x0 },
+ { 0xf9e00000, 0x49000000, 0x61f3fe0, 0x0 },
+ { 0xff800000, 0xd7000000, 0x6020e0, 0x0 },
+ { 0xffc00000, 0xda000000, 0x203fe0, 0x0 },
+ { 0xf7c02000, 0x12802000, 0x3000fe, 0x0 },
+ { 0xf9e00000, 0x49600000, 0x61f3fe0, 0x0 },
+ { 0xffe02000, 0x47400000, 0x7e0, 0x0 },
+ { 0xf9e00000, 0x49c00000, 0x61f3fe0, 0x0 },
+ { 0xffe03000, 0x9bc01000, 0xf60, 0x0 },
+ { 0xf7c02300, 0x13c00100, 0x3000fe, 0x0 },
+ { 0xffe03880, 0x9f002880, 0x1f0100, 0x0 },
+ { 0xffe03000, 0x9b601000, 0xf60, 0x0 },
+ { 0xffe01804, 0x40a00800, 0x20f8, 0x0 },
+ { 0xffe00004, 0x42800000, 0x20f8, 0x0 },
+ { 0xf7c03000, 0x14800000, 0x3000fe, 0x0 },
+ { 0xfc003000, 0x68001000, 0x3f00000, 0x1 },
+ { 0xfc003fc7, 0x48003f44, 0x3f00000, 0x1 },
+ { 0xfc003fc7, 0x48003f45, 0x3f00000, 0x1 },
+ { 0xf7c02000, 0x10800000, 0x3000fe, 0x0 },
+ { 0xf8003e70, 0x20003a50, 0x7f00000, 0x1 },
+ { 0xf7c02000, 0x21002000, 0x3000fe, 0x0 },
+ { 0xf8003fc4, 0x40003fc0, 0x7f00000, 0x1 },
+ { 0xf9e00000, 0x48000000, 0x61f20ff, 0x0 },
+ { 0xffc0001c, 0x75000010, 0x203fe0, 0x0 },
+ { 0xf8003f00, 0x20003800, 0x7f00000, 0x1 },
+ { 0xf9e00000, 0xa1800000, 0x60020ff, 0x0 },
+ { 0xffc01000, 0x61c00000, 0x202ffe, 0x0 },
+ { 0xffe02084, 0xaf402080, 0x30078, 0x0 },
+ { 0xffe03880, 0x9f602880, 0x1f0100, 0x0 },
+ { 0xfc003f00, 0x68003000, 0x3f00000, 0x1 },
+ { 0xfc003f00, 0x68003100, 0x3f00000, 0x1 },
+ { 0xff602060, 0x3f200000, 0x1f80, 0x0 },
+ { 0xffe03000, 0x9a801000, 0xf60, 0x0 },
+ { 0xf7c02000, 0x24802000, 0x3000fe, 0x0 },
+ { 0xffe00004, 0x42c00000, 0x20f8, 0x0 },
+ { 0xf7c02300, 0x11802000, 0x3000fe, 0x0 },
+ { 0xffc01000, 0x61401000, 0x202ffe, 0x0 },
+ { 0xffe02000, 0x43c00000, 0x7e0, 0x0 },
+ { 0xf7c02000, 0x11400000, 0x3000fe, 0x0 },
+ { 0xf7c02000, 0x21800000, 0x3000fe, 0x0 },
+ { 0xfc003c00, 0x28002c00, 0x3f00000, 0x1 },
+ { 0xfc003f00, 0x28003200, 0x3f00000, 0x1 },
+ { 0xffe03080, 0x9c803080, 0xf60, 0x0 },
+ { 0xf7c03000, 0x14c03000, 0x3000fe, 0x0 },
+ { 0xff800000, 0xdb800000, 0x6020e0, 0x0 },
+ { 0xf7c02000, 0x22402000, 0x3000fe, 0x0 },
+ { 0xffe00004, 0x46800000, 0x20f8, 0x0 },
+ { 0xffe00000, 0x69a00000, 0x1f18, 0x0 },
+ { 0xfc003e00, 0x68002a00, 0x3f00000, 0x1 },
+ { 0xffe00000, 0x60a00000, 0x1f18, 0x0 },
+ { 0xf7c02000, 0x25400000, 0x3000fe, 0x0 },
+ { 0xfc003e70, 0x28003a70, 0x3f00000, 0x1 },
+ { 0xffe03080, 0x9c803000, 0xf60, 0x0 },
+ { 0xffc01000, 0x61400000, 0x202ffe, 0x0 },
+ { 0xffe01804, 0x42a01000, 0x20f8, 0x0 },
+ { 0xffc0001c, 0x75000000, 0x203fe0, 0x0 },
+ { 0xffe02084, 0xafc02080, 0x30078, 0x0 },
+ { 0xffe03884, 0xafa00884, 0x30078, 0x0 },
+ { 0xffe03884, 0xafa02080, 0x30078, 0x0 },
+ { 0xffe00000, 0x38c00000, 0x201f, 0x0 },
+ { 0xffc01000, 0x61001000, 0x202ffe, 0x0 },
+ { 0xf9e00000, 0x48800000, 0x61f20ff, 0x0 },
+ { 0xf8003800, 0x40003000, 0x7f00000, 0x1 },
+ { 0xf7c03000, 0x15403000, 0x3000fe, 0x0 },
+ { 0xf7c03000, 0x15400000, 0x3000fe, 0x0 },
+ { 0xf7c02000, 0x21000000, 0x3000fe, 0x0 },
+ { 0xffe00004, 0x40c00000, 0x20f8, 0x0 },
+ { 0xffe01804, 0x46a01000, 0x20f8, 0x0 },
+ { 0xf8003d08, 0x20003d08, 0x7f00000, 0x1 },
+ { 0xffe038c0, 0xada02080, 0x3f, 0x0 },
+ { 0xffe03080, 0x9c203000, 0xf60, 0x0 },
+ { 0xfc003800, 0x68002000, 0x3f00000, 0x1 },
+ { 0xf9e00000, 0x90600000, 0x6003fe0, 0x0 },
+ { 0xf7c03000, 0x14000000, 0x3000fe, 0x0 },
+ { 0xf8003e70, 0x20003a40, 0x7f00000, 0x1 },
+ { 0xff201800, 0x5c000800, 0xdf20fe, 0x0 },
+ { 0xffe02000, 0x41800000, 0x7e0, 0x0 },
+ { 0xff800000, 0xdb000000, 0x6020e0, 0x0 },
+ { 0xfc003f00, 0x48003e00, 0x3f00000, 0x1 },
+ { 0xf7c03000, 0x14002000, 0x3000fe, 0x0 },
+ { 0xf7c02300, 0x11800100, 0x3000fe, 0x0 },
+ { 0xfc003e00, 0x68002800, 0x3f00000, 0x1 },
+ { 0xffe00004, 0x44c00000, 0x20f8, 0x0 },
+ { 0xffe03880, 0x9f003880, 0x1f0100, 0x0 },
+ { 0xff602000, 0x73402000, 0x1fe0, 0x0 },
+ { 0xffe00000, 0x38200000, 0x201f, 0x0 },
+ { 0xf7c02000, 0x24800000, 0x3000fe, 0x0 },
+ { 0xf7c03000, 0x15001000, 0x3000fe, 0x0 },
+ { 0xff800000, 0x7c800000, 0x1f2000, 0x0 },
+ { 0xf8003fc7, 0x40003fc6, 0x7f00000, 0x1 },
+ { 0xf7c02000, 0x12000000, 0x3000fe, 0x0 },
+ { 0xff602000, 0x73202000, 0x1fe0, 0x0 },
+ { 0xf7c02300, 0x13c00000, 0x3000fe, 0x0 },
+ { 0xff602060, 0x3f400040, 0x1f80, 0x0 },
+ { 0xf7c02000, 0x24002000, 0x3000fe, 0x0 },
+ { 0xffe02084, 0xaf800080, 0x30078, 0x0 },
+ { 0xffe00000, 0x38800000, 0x201f, 0x0 },
+ { 0xfc003f00, 0x28003800, 0x3f00000, 0x1 },
+ { 0xffe03080, 0x9c801080, 0xf60, 0x0 },
+ { 0xffe020c0, 0xad4000c0, 0x3f, 0x0 },
+ { 0xffe00000, 0x39400000, 0x201f, 0x0 },
+ { 0xf7c02300, 0x13c02100, 0x3000fe, 0x0 },
+ { 0xffe020c0, 0xad400080, 0x3f, 0x0 },
+ { 0xffe03880, 0x9f603880, 0x1f0100, 0x0 },
+ { 0xff000016, 0xde000002, 0xe020e8, 0x0 },
+ { 0xfc003d08, 0x28003d00, 0x3f00000, 0x1 },
+ { 0xfc003f00, 0x28003000, 0x3f00000, 0x1 },
+ { 0xffe03080, 0x9c401000, 0xf60, 0x0 },
+ { 0xf7c02000, 0x21402000, 0x3000fe, 0x0 },
+ { 0xff201800, 0x5c200800, 0xdf20fe, 0x0 },
+ { 0xffe01804, 0x40a01000, 0x20f8, 0x0 },
+ { 0xfc003f00, 0x68003300, 0x3f00000, 0x1 },
+ { 0xfc003f00, 0x68003200, 0x3f00000, 0x1 },
+ { 0xf7c03000, 0x15401000, 0x3000fe, 0x0 },
+ { 0xffe01804, 0x44a00800, 0x20f8, 0x0 },
+ { 0xf7c02000, 0x26000000, 0x3000fe, 0x0 },
+ { 0xffc00000, 0xda400000, 0x203fe0, 0x0 },
+ { 0xffe00004, 0x40600000, 0x20f8, 0x0 },
+ { 0xffe02080, 0xab600080, 0x3f, 0x0 },
+ { 0xf8003f00, 0x20003600, 0x7f00000, 0x1 },
+ { 0xf7c02300, 0x11c00300, 0x3000fe, 0x0 },
+ { 0xf8003f00, 0x20003700, 0x7f00000, 0x1 },
+ { 0xf7c02000, 0x25c00000, 0x3000fe, 0x0 },
+ { 0xf7c02300, 0x11800300, 0x3000fe, 0x0 },
+ { 0xffe03880, 0x9f802880, 0x1f0100, 0x0 },
+ { 0xfc003800, 0x48003000, 0x3f00000, 0x1 },
+ { 0xf8003c00, 0x20002c00, 0x7f00000, 0x1 },
+ { 0xf7c02000, 0x10400000, 0x3000fe, 0x0 },
+ { 0xff602060, 0x3f400060, 0x1f80, 0x0 },
+ { 0xffe03080, 0x9c801000, 0xf60, 0x0 },
+ { 0xff602060, 0x3e400040, 0x1f80, 0x0 },
+ { 0xf7c03000, 0x14402000, 0x3000fe, 0x0 },
+ { 0xffe0001c, 0x75800010, 0x3fe0, 0x0 },
+ { 0xff000016, 0xde000014, 0xe020e8, 0x0 },
+ { 0xf7c02300, 0x11c02000, 0x3000fe, 0x0 },
+ { 0xff600018, 0xdd200008, 0x1fe0, 0x0 },
+ { 0xff602060, 0x3e200060, 0x1f80, 0x0 },
+ { 0xff000016, 0xde000006, 0xe020e8, 0x0 },
+ { 0xffe00004, 0x44600000, 0x20f8, 0x0 },
+ { 0xf8003e00, 0x60002800, 0x7f00000, 0x1 },
+ { 0xfe600000, 0x3c000000, 0x207f, 0x0 },
+ { 0xffe03884, 0xafa02884, 0x30078, 0x0 },
+ { 0xf7c02300, 0x11802300, 0x3000fe, 0x0 },
+ { 0xffe00000, 0x38000000, 0x201f, 0x0 },
+ { 0xff200800, 0x5c000000, 0xdf20fe, 0x0 },
+ { 0xf7c02000, 0x13400000, 0x3000fe, 0x0 },
+ { 0xff200800, 0x5c200000, 0xdf20fe, 0x0 },
+ { 0xffe02000, 0x41000000, 0x7e0, 0x0 },
+ { 0xffe03880, 0x9fc02880, 0x1f0100, 0x0 },
+ { 0xffe00004, 0x46000000, 0x20f8, 0x0 },
+ { 0xff602060, 0x3f000020, 0x1f80, 0x0 },
+ { 0xfc003d08, 0x28003d08, 0x3f00000, 0x1 },
+ { 0xff602060, 0x3f200060, 0x1f80, 0x0 },
+ { 0xffe038c0, 0xada028c0, 0x3f, 0x0 },
+ { 0xffe038c0, 0xada008c0, 0x3f, 0x0 },
+ { 0xf8003f00, 0x20003500, 0x7f00000, 0x1 },
+ { 0xfc003fc4, 0x48003f40, 0x3f00000, 0x1 },
+ { 0xf9e01800, 0x48a00000, 0x61f20ff, 0x0 },
+ { 0xf7c03000, 0x14802000, 0x3000fe, 0x0 },
+ { 0xfc003f00, 0x28003900, 0x3f00000, 0x1 },
+ { 0xf8003fc7, 0x40003fc7, 0x7f00000, 0x1 },
+ { 0xffe02000, 0x45400000, 0x7e0, 0x0 },
+ { 0xffe038c0, 0xada02880, 0x3f, 0x0 },
+ { 0xffe02084, 0xaf002080, 0x30078, 0x0 },
+ { 0xffe03880, 0x9f803880, 0x1f0100, 0x0 },
+ { 0xf7c03000, 0x15000000, 0x3000fe, 0x0 },
+ { 0xfc003f00, 0x28003700, 0x3f00000, 0x1 },
+ { 0xfc003f00, 0x28003600, 0x3f00000, 0x1 },
+ { 0xffe02000, 0x47200000, 0x7e0, 0x0 },
+ { 0xffe03880, 0xaba00080, 0x3f, 0x0 },
+ { 0xffe02084, 0xafc00080, 0x30078, 0x0 },
+ { 0xff802000, 0x73800000, 0x1fe0, 0x0 },
+ { 0xffe03880, 0x9f202880, 0x1f0100, 0x0 },
+ { 0xf8003d18, 0x20003c00, 0x7f00000, 0x1 },
+ { 0xf9e00000, 0xa1600000, 0x60020ff, 0x0 },
+ { 0xffe00004, 0x44800000, 0x20f8, 0x0 },
+ { 0xf7c02000, 0x21802000, 0x3000fe, 0x0 },
+ { 0xff000000, 0xd8000000, 0x6020e0, 0x0 },
+ { 0xf9e00000, 0xa1000000, 0x60020ff, 0x0 },
+ { 0xffe03884, 0xafa00084, 0x30078, 0x0 },
+ { 0xff201800, 0x5c201800, 0xdf20fe, 0x0 },
+ { 0xff000016, 0xde000010, 0xe020e8, 0x0 },
+ { 0xffe03880, 0x9f603080, 0x1f0100, 0x0 },
+ { 0xffe02000, 0x41c00000, 0x7e0, 0x0 },
+ { 0xf7c02000, 0x20402000, 0x3000fe, 0x0 },
+ { 0xff800000, 0xe1000000, 0x1fe0, 0x0 },
+ { 0xf9e00000, 0xa1400000, 0x60020ff, 0x0 },
+ { 0xf7c03000, 0x14c00000, 0x3000fe, 0x0 },
+ { 0xf8003fc7, 0x40003f47, 0x7f00000, 0x1 },
+ { 0xffe00004, 0x40800000, 0x20f8, 0x0 },
+ { 0xff800000, 0xe1800000, 0x1fe0, 0x0 },
+ { 0xf7c02300, 0x11802100, 0x3000fe, 0x0 },
+ { 0xf9e00000, 0x49800000, 0x61f3fe0, 0x0 },
+ { 0xf7c02000, 0x26400000, 0x3000fe, 0x0 },
+ { 0xf8003c00, 0x20002800, 0x7f00000, 0x1 },
+ { 0xff902000, 0x7e002000, 0xf1fe0, 0x0 },
+ { 0xff902000, 0x7e802000, 0xf1fe0, 0x0 },
+ { 0xf9e00000, 0x91c00000, 0x6003fe0, 0x0 },
+ { 0xffe03884, 0xafa02880, 0x30078, 0x0 },
+ { 0xf7c02000, 0x22000000, 0x3000fe, 0x0 },
+ { 0xffe03080, 0x9d203000, 0xf60, 0x0 },
+ { 0xf7c02000, 0x26002000, 0x3000fe, 0x0 },
+ { 0xff800000, 0xe2000000, 0x1fe0, 0x0 },
+ { 0xf7c02000, 0x26c00000, 0x3000fe, 0x0 },
+ { 0xff602060, 0x3e400000, 0x1f80, 0x0 },
+ { 0xffe00000, 0x38400000, 0x201f, 0x0 },
+ { 0xfc003800, 0x48002000, 0x3f00000, 0x1 },
+ { 0xff000016, 0xde000000, 0xe020e8, 0x0 },
+ { 0xf8003f00, 0x20003000, 0x7f00000, 0x1 },
+ { 0xf8003e70, 0x20003a60, 0x7f00000, 0x1 },
+ { 0xff902000, 0x7e800000, 0xf1fe0, 0x0 },
+ { 0xffe020c0, 0xad6020c0, 0x3f, 0x0 },
+ { 0xf7c02300, 0x13802000, 0x3000fe, 0x0 },
+ { 0xffe020c0, 0xad600080, 0x3f, 0x0 },
+ { 0xff902000, 0x7e000000, 0xf1fe0, 0x0 },
+ { 0xf7000000, 0x17000000, 0x3000fe, 0x0 },
+ { 0xf7000000, 0x16000000, 0x3000fe, 0x0 },
+ { 0xf7c02000, 0x25002000, 0x3000fe, 0x0 },
+ { 0xfc003fc7, 0x48003fc7, 0x3f00000, 0x1 },
+ { 0xffc01000, 0x61801000, 0x202ffe, 0x0 },
+ { 0xffe03884, 0xafa03080, 0x30078, 0x0 },
+ { 0xf8003fc4, 0x40003f40, 0x7f00000, 0x1 },
+ { 0xfc003e70, 0x28003a60, 0x3f00000, 0x1 },
+ { 0xf7c02300, 0x13800000, 0x3000fe, 0x0 },
+ { 0xffe03880, 0x9f802080, 0x1f0100, 0x0 },
+ { 0xf0000000, 0xb0000000, 0xfe03fe0, 0x0 },
+ { 0xffe03880, 0x9f402080, 0x1f0100, 0x0 },
+ { 0xffe02000, 0x43200000, 0x7e0, 0x0 },
+ { 0xffe00000, 0x39800000, 0x201f, 0x0 },
+ { 0xffe03880, 0x9fc03880, 0x1f0100, 0x0 },
+ { 0xffe02000, 0x45600000, 0x7e0, 0x0 },
+ { 0xf9e00000, 0x91200000, 0x6003fe0, 0x0 },
+ { 0xffe02000, 0x43600000, 0x7e0, 0x0 },
+ { 0xfc003f00, 0x28003800, 0x3f00000, 0x1 },
+ { 0xff802000, 0x74000000, 0x1fe0, 0x0 },
+ { 0xffe02084, 0xaf002084, 0x30078, 0x0 },
+ { 0xff802000, 0x74800000, 0x1fe0, 0x0 },
+ { 0xf7c03000, 0x14c02000, 0x3000fe, 0x0 },
+ { 0xfe000001, 0x5a000000, 0x1ff3ffe, 0x0 },
+ { 0xff602060, 0x3f400020, 0x1f80, 0x0 },
+ { 0xf7c02000, 0x10802000, 0x3000fe, 0x0 },
+ { 0xffe02084, 0xaf802080, 0x30078, 0x0 },
+ { 0xffe00004, 0x46400000, 0x20f8, 0x0 },
+ { 0xffe020c0, 0xad800080, 0x3f, 0x0 },
+ { 0xffe020c0, 0xad8000c0, 0x3f, 0x0 },
+ { 0xf8003fc7, 0x40003f45, 0x7f00000, 0x1 },
+ { 0xf8003e00, 0x60002a00, 0x7f00000, 0x1 },
+ { 0xffe02084, 0xaf600084, 0x30078, 0x0 },
+ { 0xffe03080, 0x9c201000, 0xf60, 0x0 },
+ { 0xffe02000, 0x43400000, 0x7e0, 0x0 },
+ { 0xffe03080, 0x9c203080, 0xf60, 0x0 },
+ { 0xffe02000, 0x41200000, 0x7e0, 0x0 },
+ { 0xffe03080, 0x9c201080, 0xf60, 0x0 },
+ { 0xf7c02300, 0x11c02300, 0x3000fe, 0x0 },
+ { 0xffe03880, 0x9fc03080, 0x1f0100, 0x0 },
+ { 0xffe03880, 0x9f402880, 0x1f0100, 0x0 },
+ { 0xf8003800, 0x40002000, 0x7f00000, 0x1 },
+ { 0xf7c02000, 0x24402000, 0x3000fe, 0x0 },
+ { 0xf7c02000, 0x20c02000, 0x3000fe, 0x0 },
+ { 0xf7c02300, 0x11c00000, 0x3000fe, 0x0 },
+ { 0xffe02000, 0x45200000, 0x7e0, 0x0 },
+ { 0xf8003f00, 0x20003900, 0x7f00000, 0x1 },
+ { 0xf7c02300, 0x11c00100, 0x3000fe, 0x0 },
+ { 0xffe02084, 0xaf800084, 0x30078, 0x0 },
+ { 0xfe600000, 0x3c200000, 0x207f, 0x0 },
+ { 0xf7c02000, 0x26800000, 0x3000fe, 0x0 },
+ { 0xffe03880, 0x9f003080, 0x1f0100, 0x0 },
+ { 0xffe03884, 0xafa01084, 0x30078, 0x0 },
+ { 0xffc00000, 0x76000000, 0x203fe0, 0x0 },
+ { 0xff602060, 0x3e000040, 0x1f80, 0x0 },
+ { 0xffe020c0, 0xadc020c0, 0x3f, 0x0 },
+ { 0xffe00004, 0x44400000, 0x20f8, 0x0 },
+ { 0xffe020c0, 0xadc02080, 0x3f, 0x0 },
+ { 0xfe600000, 0x3c400000, 0x207f, 0x0 },
+ { 0xf7c02000, 0x20400000, 0x3000fe, 0x0 },
+ { 0xff800000, 0x7c000000, 0x1fe0, 0x0 },
+ { 0xffe03884, 0xafa00080, 0x30078, 0x0 },
+ { 0xff201800, 0x5c001800, 0xdf20fe, 0x0 },
+ { 0xffe02000, 0x47800000, 0x7e0, 0x0 },
+ { 0xff601018, 0xdd400000, 0xfe0, 0x0 },
+ { 0xffe020c0, 0xad4020c0, 0x3f, 0x0 },
+ { 0xffe020c0, 0xad402080, 0x3f, 0x0 },
+ { 0xf8003000, 0x40001000, 0x7f00000, 0x1 },
+ { 0xffe02084, 0xafc02084, 0x30078, 0x0 },
+ { 0xffe03080, 0x9c403080, 0xf60, 0x0 },
+ { 0xfc003e40, 0x28003a00, 0x3f00000, 0x1 },
+ { 0xffe038c0, 0xada010c0, 0x3f, 0x0 },
+ { 0xffe038c0, 0xada01080, 0x3f, 0x0 },
+ { 0xffe038c0, 0xada030c0, 0x3f, 0x0 },
+ { 0xffe038c0, 0xada03080, 0x3f, 0x0 },
+ { 0xf7c02000, 0x20800000, 0x3000fe, 0x0 },
+ { 0xfc003fc7, 0x48003f46, 0x3f00000, 0x1 },
+ { 0xffe01804, 0x44a00000, 0x20f8, 0x0 },
+ { 0xf7c02000, 0x20002000, 0x3000fe, 0x0 },
+ { 0xf7c02000, 0x12c02000, 0x3000fe, 0x0 },
+ { 0xffe03000, 0x9a601000, 0xf60, 0x0 },
+ { 0xffc00000, 0xda800000, 0x203fe0, 0x0 },
+ { 0xf9e00000, 0x90400000, 0x6003fe0, 0x0 },
+ { 0xffe02000, 0x47600000, 0x7e0, 0x0 },
+ { 0xffe03080, 0x9d403000, 0xf60, 0x0 },
+ { 0xffe03080, 0x9d403080, 0xf60, 0x0 },
+ { 0xffe03080, 0x9d401000, 0xf60, 0x0 },
+ { 0xffe03080, 0x9d401080, 0xf60, 0x0 },
+ { 0xffe02000, 0x41400000, 0x7e0, 0x0 },
+ { 0xff800000, 0xdf800000, 0x6020e0, 0x0 },
+ { 0xffc01000, 0x61000000, 0x202ffe, 0x0 },
+ { 0xffe03880, 0x9f202080, 0x1f0100, 0x0 },
+ { 0xfc003fc7, 0x48003fc6, 0x3f00000, 0x1 },
+ { 0xfe000000, 0x7a000000, 0x1fe0, 0x0 },
+ { 0xffff0000, 0x6a490000, 0x1f80, 0x0 },
+ { 0xff802000, 0x73000000, 0x1fe0, 0x0 },
+ { 0xff602060, 0x3e200020, 0x1f80, 0x0 },
+ { 0xf7c02000, 0x24000000, 0x3000fe, 0x0 },
+ { 0xf8003e40, 0x20003a00, 0x7f00000, 0x1 },
+ { 0xf7c03000, 0x14401000, 0x3000fe, 0x0 },
+ { 0xf8003f00, 0x20003200, 0x7f00000, 0x1 },
+ { 0xffc00000, 0x76400000, 0x203fe0, 0x0 },
+ { 0xf7c02000, 0x22002000, 0x3000fe, 0x0 },
+ { 0xffc01000, 0x61c01000, 0x202ffe, 0x0 },
+ { 0xf7c03000, 0x14801000, 0x3000fe, 0x0 },
+ { 0xf7c02000, 0x12002000, 0x3000fe, 0x0 },
+ { 0xf7c02000, 0x10402000, 0x3000fe, 0x0 },
+ { 0xff201800, 0x5d200000, 0xdf20fe, 0x0 },
+ { 0xf7c02000, 0x21400000, 0x3000fe, 0x0 },
+ { 0xff201800, 0x5d000000, 0xdf20fe, 0x0 },
+ { 0xffe02000, 0x45c00000, 0x7e0, 0x0 },
+ { 0xf7c02000, 0x25802000, 0x3000fe, 0x0 },
+ { 0xfc003e70, 0x28003a50, 0x3f00000, 0x1 },
+ { 0xf7c02300, 0x13c00300, 0x3000fe, 0x0 },
+ { 0xf9e01800, 0xa1a00800, 0x60020ff, 0x0 },
+ { 0xffe02000, 0x43800000, 0x7e0, 0x0 },
+ { 0xfc003fc4, 0x48003fc0, 0x3f00000, 0x1 },
+ { 0xff800000, 0xe2800000, 0x1fe0, 0x0 },
+ { 0xf7c02300, 0x13c02000, 0x3000fe, 0x0 },
+ { 0xffe03080, 0x9d803080, 0xf60, 0x0 },
+ { 0xffe03080, 0x9d803000, 0xf60, 0x0 },
+ { 0xffe03080, 0x9d801080, 0xf60, 0x0 },
+ { 0xf8003fc4, 0x40003f00, 0x7f00000, 0x1 },
+ { 0xffe00000, 0x39c00000, 0x201f, 0x0 },
+ { 0xffe03080, 0x9d203080, 0xf60, 0x0 },
+ { 0xffe02080, 0xab000080, 0x3f, 0x0 },
+ { 0xf8003e00, 0x60003c00, 0x7f00000, 0x1 },
+ { 0xffe03880, 0x9f602080, 0x1f0100, 0x0 },
+ { 0xffc00000, 0x76800000, 0x203fe0, 0x0 },
+ { 0xffe03884, 0xafa02084, 0x30078, 0x0 },
+ { 0xf7c02000, 0x13002000, 0x3000fe, 0x0 },
+ { 0xf9e00000, 0x91000000, 0x6003fe0, 0x0 },
+ { 0xffe03080, 0x9d201080, 0xf60, 0x0 },
+ { 0xf7c03000, 0x15002000, 0x3000fe, 0x0 },
+ { 0xf8003000, 0x60000000, 0x7f00000, 0x1 },
+ { 0xffc01000, 0x61800000, 0x202ffe, 0x0 },
+ { 0xf7c03000, 0x14400000, 0x3000fe, 0x0 },
+ { 0xffe03000, 0x9b401000, 0xf60, 0x0 },
+ { 0xf7c03000, 0x14003000, 0x3000fe, 0x0 },
+ { 0xffe03880, 0x9fc02080, 0x1f0100, 0x0 },
+ { 0xfc003fc4, 0x48003f00, 0x3f00000, 0x1 },
+ { 0xffe02000, 0x45000000, 0x7e0, 0x0 },
+ { 0xfc003800, 0x48002800, 0x3f00000, 0x1 },
+ { 0xfc003fc7, 0x48003fc5, 0x3f00000, 0x1 },
+ { 0xfc003d18, 0x28003c00, 0x3f00000, 0x1 },
+ { 0xfc003fc7, 0x48003fc4, 0x3f00000, 0x1 },
+ { 0xf8003f00, 0x60003200, 0x7f00000, 0x1 },
+ { 0xffe02084, 0xaf600080, 0x30078, 0x0 },
+ { 0xf9e01800, 0xa1a00000, 0x60020ff, 0x0 },
+ { 0xf7c03000, 0x14001000, 0x3000fe, 0x0 },
+ { 0xf7c03000, 0x14c01000, 0x3000fe, 0x0 },
+ { 0xffe00004, 0x46c00000, 0x20f8, 0x0 },
+ { 0xf7c03000, 0x15003000, 0x3000fe, 0x0 },
+ { 0xf7c02000, 0x10000000, 0x3000fe, 0x0 },
+ { 0xf8003d18, 0x20003c08, 0x7f00000, 0x1 },
+ { 0xffc0001c, 0x75400010, 0x203fe0, 0x0 },
+ { 0xf9e00000, 0x48600000, 0x61f20ff, 0x0 },
+ { 0xffe03080, 0x9c603080, 0xf60, 0x0 },
+ { 0xfe000000, 0x58000000, 0x1ff3ffe, 0x0 },
+ { 0xffe03000, 0x9a201000, 0xf60, 0x0 },
+ { 0xffe00000, 0x69e00000, 0x1f18, 0x0 },
+ { 0xffe020c0, 0xad802080, 0x3f, 0x0 },
+ { 0xffe02000, 0x47c00000, 0x7e0, 0x0 },
+ { 0xffe00000, 0x60e00000, 0x1f18, 0x0 },
+ { 0xf7c03000, 0x15402000, 0x3000fe, 0x0 },
+ { 0xffe020c0, 0xad8020c0, 0x3f, 0x0 },
+ { 0xff000016, 0xde000012, 0xe020e8, 0x0 },
+ { 0xf7c02000, 0x25c02000, 0x3000fe, 0x0 },
+ { 0xf8003f00, 0x60003100, 0x7f00000, 0x1 },
+ { 0xf8003f00, 0x60003000, 0x7f00000, 0x1 },
+ { 0xf7c02000, 0x25800000, 0x3000fe, 0x0 },
+ { 0xf7c03000, 0x14403000, 0x3000fe, 0x0 },
+ { 0xfc003d18, 0x28003c08, 0x3f00000, 0x1 },
+ { 0xffe03880, 0x9f403080, 0x1f0100, 0x0 },
+ { 0xf7c02000, 0x25402000, 0x3000fe, 0x0 },
+ { 0xf7c02000, 0x10c00000, 0x3000fe, 0x0 },
+ { 0xffe02000, 0x45800000, 0x7e0, 0x0 },
+ { 0xffe03880, 0x9f803080, 0x1f0100, 0x0 },
+ { 0xffe03080, 0x9d001000, 0xf60, 0x0 },
+ { 0xffe03080, 0x9d001080, 0xf60, 0x0 },
+ { 0xffe03080, 0x9d003000, 0xf60, 0x0 },
+ { 0xffe03080, 0x9d003080, 0xf60, 0x0 },
+ { 0xffe03080, 0x9d801000, 0xf60, 0x0 },
+ { 0xf9e00000, 0x49200000, 0x61f3fe0, 0x0 },
+ { 0xf9e00000, 0xa1c00000, 0x60020ff, 0x0 },
+ { 0xf9e00000, 0x90200000, 0x6003fe0, 0x0 },
+ { 0xffe03080, 0x9d201000, 0xf60, 0x0 },
+ { 0xffe03884, 0xafa01080, 0x30078, 0x0 },
+ { 0xffe02084, 0xaf602080, 0x30078, 0x0 },
+ { 0xffe038c0, 0xada000c0, 0x3f, 0x0 },
+ { 0xffe02080, 0xab400080, 0x3f, 0x0 },
+ { 0xff000016, 0xde000004, 0xe020e8, 0x0 },
+ { 0xffe00004, 0x44000000, 0x20f8, 0x0 },
+ { 0xf7c02000, 0x20000000, 0x3000fe, 0x0 },
+ { 0xfc003d18, 0x28003c10, 0x3f00000, 0x1 },
+ { 0xff600018, 0xdd000008, 0x1fe0, 0x0 },
+ { 0xffe020c0, 0xadc000c0, 0x3f, 0x0 },
+ { 0xffe020c0, 0xadc00080, 0x3f, 0x0 },
+ { 0xffe03000, 0x9b801000, 0xf60, 0x0 },
+ { 0xf8003fc7, 0x40003f46, 0x7f00000, 0x1 },
+ { 0xf7c02000, 0x21c02000, 0x3000fe, 0x0 },
+ { 0xffe01804, 0x40a00000, 0x20f8, 0x0 },
+ { 0xf7c02000, 0x26402000, 0x3000fe, 0x0 },
+ { 0xffe03080, 0x9c401080, 0xf60, 0x0 },
+ { 0xffe00000, 0x39200000, 0x201f, 0x0 },
+ { 0xffe03080, 0x9c403000, 0xf60, 0x0 },
+ { 0xf7c02000, 0x11002000, 0x3000fe, 0x0 },
+ { 0xfc003c00, 0x28002800, 0x3f00000, 0x1 },
+ { 0xffe00004, 0x40400000, 0x20f8, 0x0 },
+ { 0xf7c02000, 0x26802000, 0x3000fe, 0x0 },
+ { 0xf7c02000, 0x13000000, 0x3000fe, 0x0 },
+ { 0xffe00004, 0x42600000, 0x20f8, 0x0 },
+ { 0xf8003000, 0x60001000, 0x7f00000, 0x1 },
+ { 0xff602060, 0x3e400020, 0x1f80, 0x0 },
+ { 0xff602060, 0x3f000000, 0x1f80, 0x0 },
+ { 0xf7c02000, 0x24c02000, 0x3000fe, 0x0 },
+ { 0xff802000, 0x74002000, 0x1fe0, 0x0 },
+ { 0xf8003800, 0x20002000, 0x7f00000, 0x1 },
+ { 0xffe03000, 0x9aa01000, 0xf60, 0x0 },
+ { 0xf7c02000, 0x12400000, 0x3000fe, 0x0 },
+ { 0xff602060, 0x3f000060, 0x1f80, 0x0 },
+ { 0xf7c02000, 0x11000000, 0x3000fe, 0x0 },
+};
diff --git a/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableAtoms.h b/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableAtoms.h
new file mode 100644
index 0000000000000..a2505aa460c5b
--- /dev/null
+++ b/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableAtoms.h
@@ -0,0 +1,29 @@
+//===- lib/ReaderWriter/ELF/Hexagon/HexagonExecutableAtoms.h --------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_EXECUTABLE_ATOM_H
+#define LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_EXECUTABLE_ATOM_H
+
+#include "ELFFile.h"
+
+namespace lld {
+namespace elf {
+typedef llvm::object::ELFType<llvm::support::little, 2, false> HexagonELFType;
+class HexagonLinkingContext;
+
+template <class HexagonELFType> class HexagonRuntimeFile
+ : public RuntimeFile<HexagonELFType> {
+public:
+ HexagonRuntimeFile(HexagonLinkingContext &context)
+ : RuntimeFile<HexagonELFType>(context, "Hexagon runtime file") {}
+};
+} // elf
+} // lld
+
+#endif // LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_EXECUTABLE_ATOM_H
diff --git a/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h b/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h
new file mode 100644
index 0000000000000..0848e64166faa
--- /dev/null
+++ b/lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h
@@ -0,0 +1,86 @@
+//===- lib/ReaderWriter/ELF/Hexagon/HexagonExecutableWriter.h -------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef HEXAGON_EXECUTABLE_WRITER_H
+#define HEXAGON_EXECUTABLE_WRITER_H
+
+#include "ExecutableWriter.h"
+#include "HexagonELFWriters.h"
+#include "HexagonExecutableAtoms.h"
+#include "HexagonLinkingContext.h"
+
+namespace lld {
+namespace elf {
+
+template <typename ELFT> class HexagonTargetLayout;
+
+template <class ELFT>
+class HexagonExecutableWriter : public ExecutableWriter<ELFT>,
+ public HexagonELFWriter<ELFT> {
+public:
+ HexagonExecutableWriter(HexagonLinkingContext &context,
+ HexagonTargetLayout<ELFT> &layout);
+
+protected:
+ // Add any runtime files and their atoms to the output
+ virtual bool createImplicitFiles(std::vector<std::unique_ptr<File>> &);
+
+ virtual void finalizeDefaultAtomValues();
+
+ virtual std::error_code setELFHeader() {
+ ExecutableWriter<ELFT>::setELFHeader();
+ HexagonELFWriter<ELFT>::setELFHeader(*this->_elfHeader);
+ return std::error_code();
+ }
+
+private:
+ void addDefaultAtoms() {
+ _hexagonRuntimeFile->addAbsoluteAtom("_SDA_BASE_");
+ if (this->_context.isDynamic()) {
+ _hexagonRuntimeFile->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
+ _hexagonRuntimeFile->addAbsoluteAtom("_DYNAMIC");
+ }
+ }
+
+ HexagonLinkingContext &_hexagonLinkingContext;
+ HexagonTargetLayout<ELFT> &_hexagonTargetLayout;
+ std::unique_ptr<HexagonRuntimeFile<ELFT>> _hexagonRuntimeFile;
+};
+
+template <class ELFT>
+HexagonExecutableWriter<ELFT>::HexagonExecutableWriter(
+ HexagonLinkingContext &context, HexagonTargetLayout<ELFT> &layout)
+ : ExecutableWriter<ELFT>(context, layout),
+ HexagonELFWriter<ELFT>(context, layout), _hexagonLinkingContext(context),
+ _hexagonTargetLayout(layout),
+ _hexagonRuntimeFile(new HexagonRuntimeFile<ELFT>(context)) {}
+
+template <class ELFT>
+bool HexagonExecutableWriter<ELFT>::createImplicitFiles(
+ std::vector<std::unique_ptr<File>> &result) {
+ ExecutableWriter<ELFT>::createImplicitFiles(result);
+ // Add the default atoms as defined for hexagon
+ addDefaultAtoms();
+ result.push_back(std::move(_hexagonRuntimeFile));
+ return true;
+}
+
+template <class ELFT>
+void HexagonExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
+ // Finalize the atom values that are part of the parent.
+ ExecutableWriter<ELFT>::finalizeDefaultAtomValues();
+ auto sdabaseAtomIter = _hexagonTargetLayout.findAbsoluteAtom("_SDA_BASE_");
+ (*sdabaseAtomIter)->_virtualAddr =
+ _hexagonTargetLayout.getSDataSection()->virtualAddr();
+ HexagonELFWriter<ELFT>::finalizeHexagonRuntimeAtomValues();
+}
+
+} // namespace elf
+} // namespace lld
+
+#endif // HEXAGON_EXECUTABLE_WRITER_H
diff --git a/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp b/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp
new file mode 100644
index 0000000000000..7eacb2b44c3b2
--- /dev/null
+++ b/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp
@@ -0,0 +1,25 @@
+//===- lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp -------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "HexagonLinkingContext.h"
+#include "HexagonTargetHandler.h"
+
+using namespace lld::elf;
+
+std::unique_ptr<lld::ELFLinkingContext>
+HexagonLinkingContext::create(llvm::Triple triple) {
+ if (triple.getArch() == llvm::Triple::hexagon)
+ return std::unique_ptr<lld::ELFLinkingContext>(
+ new HexagonLinkingContext(triple));
+ return nullptr;
+}
+
+HexagonLinkingContext::HexagonLinkingContext(llvm::Triple triple)
+ : ELFLinkingContext(triple, std::unique_ptr<TargetHandlerBase>(
+ new HexagonTargetHandler(*this))) {}
diff --git a/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h b/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h
new file mode 100644
index 0000000000000..c920cdf153aaf
--- /dev/null
+++ b/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h
@@ -0,0 +1,69 @@
+//===- lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h ---------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_LINKING_CONTEXT_H
+#define LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_LINKING_CONTEXT_H
+
+#include "lld/ReaderWriter/ELFLinkingContext.h"
+#include "llvm/Object/ELF.h"
+#include "llvm/Support/ELF.h"
+
+namespace lld {
+namespace elf {
+
+typedef llvm::object::ELFType<llvm::support::little, 2, false> HexagonELFType;
+
+class HexagonLinkingContext final : public ELFLinkingContext {
+public:
+ static std::unique_ptr<ELFLinkingContext> create(llvm::Triple);
+ HexagonLinkingContext(llvm::Triple triple);
+
+ void addPasses(PassManager &) override;
+
+ bool isDynamicRelocation(const Reference &r) const override {
+ if (r.kindNamespace() != Reference::KindNamespace::ELF)
+ return false;
+ switch (r.kindValue()) {
+ case llvm::ELF::R_HEX_RELATIVE:
+ case llvm::ELF::R_HEX_GLOB_DAT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool isPLTRelocation(const Reference &r) const override {
+ if (r.kindNamespace() != Reference::KindNamespace::ELF)
+ return false;
+ switch (r.kindValue()) {
+ case llvm::ELF::R_HEX_JMP_SLOT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /// \brief Hexagon has only one relative relocation
+ /// a) for supporting relative relocs - R_HEX_RELATIVE
+ bool isRelativeReloc(const Reference &r) const override {
+ if (r.kindNamespace() != Reference::KindNamespace::ELF)
+ return false;
+ switch (r.kindValue()) {
+ case llvm::ELF::R_HEX_RELATIVE:
+ return true;
+ default:
+ return false;
+ }
+ }
+};
+
+} // elf
+} // lld
+
+#endif // LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_LINKING_CONTEXT_H
diff --git a/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationFunctions.h b/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationFunctions.h
new file mode 100644
index 0000000000000..2b9e25ce363b5
--- /dev/null
+++ b/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationFunctions.h
@@ -0,0 +1,49 @@
+//===- HexagonRelocationFunction.h ----------------------------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_RELOCATION_FUNCTIONS_H
+#define LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_RELOCATION_FUNCTIONS_H
+
+namespace lld {
+namespace elf {
+
+/// \brief HexagonInstruction which is used to store various values
+typedef struct {
+ uint32_t insnMask;
+ uint32_t insnCmpMask;
+ uint32_t insnBitMask;
+ bool isDuplex;
+} Instruction;
+
+#include "HexagonEncodings.h"
+
+#define FINDV4BITMASK(INSN) \
+ findBitMask((uint32_t) * ((llvm::support::ulittle32_t *) INSN), \
+ insn_encodings, \
+ sizeof(insn_encodings) / sizeof(Instruction))
+
+/// \brief finds the scatter Bits that need to be used to apply relocations
+inline uint32_t
+findBitMask(uint32_t insn, Instruction *encodings, int32_t numInsns) {
+ for (int32_t i = 0; i < numInsns; i++) {
+ if (((insn & 0xc000) == 0) && !(encodings[i].isDuplex))
+ continue;
+
+ if (((insn & 0xc000) != 0) && (encodings[i].isDuplex))
+ continue;
+
+ if (((encodings[i].insnMask) & insn) == encodings[i].insnCmpMask)
+ return encodings[i].insnBitMask;
+ }
+ llvm_unreachable("found unknown instruction");
+}
+
+} // elf
+} // lld
+
+#endif // LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_RELOCATION_FUNCTIONS_H
diff --git a/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp b/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp
new file mode 100644
index 0000000000000..21967d356a311
--- /dev/null
+++ b/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp
@@ -0,0 +1,350 @@
+//===- lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp ---------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "HexagonLinkingContext.h"
+#include "HexagonRelocationFunctions.h"
+#include "HexagonTargetHandler.h"
+#include "HexagonRelocationHandler.h"
+#include "llvm/Support/Endian.h"
+
+using namespace lld;
+using namespace lld::elf;
+using namespace llvm::ELF;
+using namespace llvm::support::endian;
+
+#define APPLY_RELOC(result) \
+ write32le(location, result | read32le(location));
+
+static int relocBNPCREL(uint8_t *location, uint64_t P, uint64_t S, uint64_t A,
+ int32_t nBits) {
+ int32_t result = (uint32_t)(((S + A) - P) >> 2);
+ int32_t range = 1 << nBits;
+ if (result < range && result > -range) {
+ result = lld::scatterBits<int32_t>(result, FINDV4BITMASK(location));
+ APPLY_RELOC(result);
+ return 0;
+ }
+ return 1;
+}
+
+/// \brief Word32_LO: 0x00c03fff : (S + A) : Truncate
+static int relocLO16(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
+ uint32_t result = (uint32_t)(S + A);
+ result = lld::scatterBits<int32_t>(result, 0x00c03fff);
+ APPLY_RELOC(result);
+ return 0;
+}
+
+/// \brief Word32_LO: 0x00c03fff : (S + A) >> 16 : Truncate
+static int relocHI16(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
+ uint32_t result = (uint32_t)((S + A) >> 16);
+ result = lld::scatterBits<int32_t>(result, 0x00c03fff);
+ APPLY_RELOC(result);
+ return 0;
+}
+
+/// \brief Word32: 0xffffffff : (S + A) : Truncate
+static int reloc32(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
+ uint32_t result = (uint32_t)(S + A);
+ APPLY_RELOC(result);
+ return 0;
+}
+
+static int reloc32_6_X(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
+ int64_t result = ((S + A) >> 6);
+ int64_t range = ((int64_t)1) << 32;
+ if (result > range)
+ return 1;
+ result = lld::scatterBits<int32_t>(result, 0xfff3fff);
+ APPLY_RELOC(result);
+ return 0;
+}
+
+// R_HEX_B32_PCREL_X
+static int relocHexB32PCRELX(uint8_t *location, uint64_t P, uint64_t S,
+ uint64_t A) {
+ int64_t result = ((S + A - P) >> 6);
+ result = lld::scatterBits<int32_t>(result, 0xfff3fff);
+ APPLY_RELOC(result);
+ return 0;
+}
+
+// R_HEX_BN_PCREL_X
+static int relocHexBNPCRELX(uint8_t *location, uint64_t P, uint64_t S,
+ uint64_t A, int nbits) {
+ int32_t result = ((S + A - P) & 0x3f);
+ int32_t range = 1 << nbits;
+ if (result < range && result > -range) {
+ result = lld::scatterBits<int32_t>(result, FINDV4BITMASK(location));
+ APPLY_RELOC(result);
+ return 0;
+ }
+ return 1;
+}
+
+// R_HEX_6_PCREL_X
+static int relocHex6PCRELX(uint8_t *location, uint64_t P, uint64_t S,
+ uint64_t A) {
+ int32_t result = (S + A - P);
+ result = lld::scatterBits<int32_t>(result, FINDV4BITMASK(location));
+ APPLY_RELOC(result);
+ return 0;
+}
+
+// R_HEX_N_X : Word32_U6 : (S + A) : Unsigned Truncate
+static int relocHex_N_X(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
+ uint32_t result = (S + A);
+ result = lld::scatterBits<uint32_t>(result, FINDV4BITMASK(location));
+ APPLY_RELOC(result);
+ return 0;
+}
+
+// GP REL relocations
+static int relocHexGPRELN(uint8_t *location, uint64_t P, uint64_t S, uint64_t A,
+ uint64_t GP, int nShiftBits) {
+ int32_t result = (int64_t)((S + A - GP) >> nShiftBits);
+ int32_t range = 1L << 16;
+ if (result <= range) {
+ result = lld::scatterBits<uint32_t>(result, FINDV4BITMASK(location));
+ APPLY_RELOC(result);
+ return 0;
+ }
+ return 1;
+}
+
+/// \brief Word32_LO: 0x00c03fff : (G) : Truncate
+static int relocHexGOTLO16(uint8_t *location, uint64_t A, uint64_t GOT) {
+ int32_t result = (int32_t)(A-GOT);
+ result = lld::scatterBits<int32_t>(result, 0x00c03fff);
+ APPLY_RELOC(result);
+ return 0;
+}
+
+/// \brief Word32_LO: 0x00c03fff : (G) >> 16 : Truncate
+static int relocHexGOTHI16(uint8_t *location, uint64_t A, uint64_t GOT) {
+ int32_t result = (int32_t)((A-GOT) >> 16);
+ result = lld::scatterBits<int32_t>(result, 0x00c03fff);
+ APPLY_RELOC(result);
+ return 0;
+}
+
+/// \brief Word32: 0xffffffff : (G) : Truncate
+static int relocHexGOT32(uint8_t *location, uint64_t A, uint64_t GOT) {
+ int32_t result = (int32_t)(GOT - A);
+ APPLY_RELOC(result);
+ return 0;
+}
+
+/// \brief Word32_U16 : (G) : Truncate
+static int relocHexGOT16(uint8_t *location, uint64_t A, uint64_t GOT) {
+ int32_t result = (int32_t)(GOT-A);
+ int32_t range = 1L << 16;
+ if (result <= range) {
+ result = lld::scatterBits<int32_t>(result, FINDV4BITMASK(location));
+ APPLY_RELOC(result);
+ return 0;
+ }
+ return 1;
+}
+
+static int relocHexGOT32_6_X(uint8_t *location, uint64_t A, uint64_t GOT) {
+ int32_t result = (int32_t)((A-GOT) >> 6);
+ result = lld::scatterBits<int32_t>(result, FINDV4BITMASK(location));
+ APPLY_RELOC(result);
+ return 0;
+}
+
+static int relocHexGOT16_X(uint8_t *location, uint64_t A, uint64_t GOT) {
+ int32_t result = (int32_t)(A-GOT);
+ int32_t range = 1L << 6;
+ if (result <= range) {
+ result = lld::scatterBits<int32_t>(result, FINDV4BITMASK(location));
+ APPLY_RELOC(result);
+ return 0;
+ }
+ return 1;
+}
+
+static int relocHexGOT11_X(uint8_t *location, uint64_t A, uint64_t GOT) {
+ uint32_t result = (uint32_t)(A-GOT);
+ result = lld::scatterBits<uint32_t>(result, FINDV4BITMASK(location));
+ APPLY_RELOC(result);
+ return 0;
+}
+
+static int relocHexGOTRELSigned(uint8_t *location, uint64_t P, uint64_t S,
+ uint64_t A, uint64_t GOT, int shiftBits = 0) {
+ int32_t result = (int32_t)((S + A - GOT) >> shiftBits);
+ result = lld::scatterBits<int32_t>(result, FINDV4BITMASK(location));
+ APPLY_RELOC(result);
+ return 0;
+}
+
+static int relocHexGOTRELUnsigned(uint8_t *location, uint64_t P, uint64_t S,
+ uint64_t A, uint64_t GOT, int shiftBits = 0) {
+ uint32_t result = (uint32_t)((S + A - GOT) >> shiftBits);
+ result = lld::scatterBits<uint32_t>(result, FINDV4BITMASK(location));
+ APPLY_RELOC(result);
+ return 0;
+}
+
+static int relocHexGOTREL_HILO16(uint8_t *location, uint64_t P, uint64_t S,
+ uint64_t A, uint64_t GOT, int shiftBits = 0) {
+ int32_t result = (int32_t)((S + A - GOT) >> shiftBits);
+ result = lld::scatterBits<int32_t>(result, 0x00c03fff);
+ APPLY_RELOC(result);
+ return 0;
+}
+
+static int relocHexGOTREL_32(uint8_t *location, uint64_t P, uint64_t S,
+ uint64_t A, uint64_t GOT) {
+ int32_t result = (int32_t)(S + A - GOT);
+ APPLY_RELOC(result);
+ return 0;
+}
+
+std::error_code HexagonTargetRelocationHandler::applyRelocation(
+ ELFWriter &writer, llvm::FileOutputBuffer &buf, const lld::AtomLayout &atom,
+ const Reference &ref) const {
+ uint8_t *atomContent = buf.getBufferStart() + atom._fileOffset;
+ uint8_t *location = atomContent + ref.offsetInAtom();
+ uint64_t targetVAddress = writer.addressOfAtom(ref.target());
+ uint64_t relocVAddress = atom._virtualAddr + ref.offsetInAtom();
+
+ if (ref.kindNamespace() != Reference::KindNamespace::ELF)
+ return std::error_code();
+ assert(ref.kindArch() == Reference::KindArch::Hexagon);
+ switch (ref.kindValue()) {
+ case R_HEX_B22_PCREL:
+ relocBNPCREL(location, relocVAddress, targetVAddress, ref.addend(), 21);
+ break;
+ case R_HEX_B15_PCREL:
+ relocBNPCREL(location, relocVAddress, targetVAddress, ref.addend(), 14);
+ break;
+ case R_HEX_B9_PCREL:
+ relocBNPCREL(location, relocVAddress, targetVAddress, ref.addend(), 8);
+ break;
+ case R_HEX_LO16:
+ relocLO16(location, relocVAddress, targetVAddress, ref.addend());
+ break;
+ case R_HEX_HI16:
+ relocHI16(location, relocVAddress, targetVAddress, ref.addend());
+ break;
+ case R_HEX_32:
+ reloc32(location, relocVAddress, targetVAddress, ref.addend());
+ break;
+ case R_HEX_32_6_X:
+ reloc32_6_X(location, relocVAddress, targetVAddress, ref.addend());
+ break;
+ case R_HEX_B32_PCREL_X:
+ relocHexB32PCRELX(location, relocVAddress, targetVAddress, ref.addend());
+ break;
+ case R_HEX_B22_PCREL_X:
+ relocHexBNPCRELX(location, relocVAddress, targetVAddress, ref.addend(), 21);
+ break;
+ case R_HEX_B15_PCREL_X:
+ relocHexBNPCRELX(location, relocVAddress, targetVAddress, ref.addend(), 14);
+ break;
+ case R_HEX_B13_PCREL_X:
+ relocHexBNPCRELX(location, relocVAddress, targetVAddress, ref.addend(), 12);
+ break;
+ case R_HEX_B9_PCREL_X:
+ relocHexBNPCRELX(location, relocVAddress, targetVAddress, ref.addend(), 8);
+ break;
+ case R_HEX_B7_PCREL_X:
+ relocHexBNPCRELX(location, relocVAddress, targetVAddress, ref.addend(), 6);
+ break;
+ case R_HEX_GPREL16_0:
+ relocHexGPRELN(location, relocVAddress, targetVAddress, ref.addend(),
+ _hexagonTargetLayout.getSDataSection()->virtualAddr(), 0);
+ break;
+ case R_HEX_GPREL16_1:
+ relocHexGPRELN(location, relocVAddress, targetVAddress, ref.addend(),
+ _hexagonTargetLayout.getSDataSection()->virtualAddr(), 1);
+ break;
+ case R_HEX_GPREL16_2:
+ relocHexGPRELN(location, relocVAddress, targetVAddress, ref.addend(),
+ _hexagonTargetLayout.getSDataSection()->virtualAddr(), 2);
+ break;
+ case R_HEX_GPREL16_3:
+ relocHexGPRELN(location, relocVAddress, targetVAddress, ref.addend(),
+ _hexagonTargetLayout.getSDataSection()->virtualAddr(), 3);
+ break;
+ case R_HEX_16_X:
+ case R_HEX_12_X:
+ case R_HEX_11_X:
+ case R_HEX_10_X:
+ case R_HEX_9_X:
+ case R_HEX_8_X:
+ case R_HEX_7_X:
+ case R_HEX_6_X:
+ relocHex_N_X(location, relocVAddress, targetVAddress, ref.addend());
+ break;
+ case R_HEX_6_PCREL_X:
+ relocHex6PCRELX(location, relocVAddress, targetVAddress, ref.addend());
+ break;
+ case R_HEX_JMP_SLOT:
+ case R_HEX_GLOB_DAT:
+ break;
+ case R_HEX_GOTREL_32:
+ relocHexGOTREL_32(location, relocVAddress, targetVAddress, ref.addend(),
+ _hexagonTargetLayout.getGOTSymAddr());
+ break;
+ case R_HEX_GOTREL_LO16:
+ relocHexGOTREL_HILO16(location, relocVAddress, targetVAddress, ref.addend(),
+ _hexagonTargetLayout.getGOTSymAddr());
+ break;
+ case R_HEX_GOTREL_HI16:
+ relocHexGOTREL_HILO16(location, relocVAddress, targetVAddress, ref.addend(),
+ _hexagonTargetLayout.getGOTSymAddr(), 16);
+ break;
+ case R_HEX_GOT_LO16:
+ relocHexGOTLO16(location, targetVAddress,
+ _hexagonTargetLayout.getGOTSymAddr());
+ break;
+ case R_HEX_GOT_HI16:
+ relocHexGOTHI16(location, targetVAddress,
+ _hexagonTargetLayout.getGOTSymAddr());
+ break;
+ case R_HEX_GOT_32:
+ relocHexGOT32(location, targetVAddress,
+ _hexagonTargetLayout.getGOTSymAddr());
+ break;
+ case R_HEX_GOT_16:
+ relocHexGOT16(location, targetVAddress,
+ _hexagonTargetLayout.getGOTSymAddr());
+ break;
+ case R_HEX_GOT_32_6_X:
+ relocHexGOT32_6_X(location, targetVAddress,
+ _hexagonTargetLayout.getGOTSymAddr());
+ break;
+ case R_HEX_GOT_16_X:
+ relocHexGOT16_X(location, targetVAddress,
+ _hexagonTargetLayout.getGOTSymAddr());
+ break;
+ case R_HEX_GOT_11_X:
+ relocHexGOT11_X(location, targetVAddress,
+ _hexagonTargetLayout.getGOTSymAddr());
+ break;
+ case R_HEX_GOTREL_32_6_X:
+ relocHexGOTRELSigned(location, relocVAddress, targetVAddress, ref.addend(),
+ _hexagonTargetLayout.getGOTSymAddr(), 6);
+ break;
+ case R_HEX_GOTREL_16_X:
+ case R_HEX_GOTREL_11_X:
+ relocHexGOTRELUnsigned(location, relocVAddress, targetVAddress,
+ ref.addend(), _hexagonTargetLayout.getGOTSymAddr());
+ break;
+
+ default:
+ return make_unhandled_reloc_error();
+ }
+
+ return std::error_code();
+}
diff --git a/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h b/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h
new file mode 100644
index 0000000000000..4795d0264b9cd
--- /dev/null
+++ b/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h
@@ -0,0 +1,35 @@
+//===- lld/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.h -----------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_RELOCATION_HANDLER_H
+#define LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_RELOCATION_HANDLER_H
+
+#include "HexagonSectionChunks.h"
+#include "HexagonTargetHandler.h"
+#include "lld/ReaderWriter/RelocationHelperFunctions.h"
+
+namespace lld {
+namespace elf {
+
+class HexagonTargetHandler;
+
+class HexagonTargetRelocationHandler final : public TargetRelocationHandler {
+public:
+ HexagonTargetRelocationHandler(HexagonTargetLayout<HexagonELFType> &layout)
+ : _hexagonTargetLayout(layout) {}
+
+ std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
+ const lld::AtomLayout &,
+ const Reference &) const override;
+
+private:
+ HexagonTargetLayout<HexagonELFType> &_hexagonTargetLayout;
+};
+} // elf
+} // lld
+#endif
diff --git a/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h b/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h
new file mode 100644
index 0000000000000..5b3fbbbd899be
--- /dev/null
+++ b/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h
@@ -0,0 +1,86 @@
+//===- lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h-----------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef HEXAGON_SECTION_CHUNKS_H
+#define HEXAGON_SECTION_CHUNKS_H
+
+#include "HexagonTargetHandler.h"
+
+namespace lld {
+namespace elf {
+template <typename ELFT> class HexagonTargetLayout;
+class HexagonLinkingContext;
+
+/// \brief Handle Hexagon SData section
+template <class HexagonELFType>
+class SDataSection : public AtomSection<HexagonELFType> {
+public:
+ SDataSection(const HexagonLinkingContext &context)
+ : AtomSection<HexagonELFType>(
+ context, ".sdata", DefinedAtom::typeDataFast, 0,
+ HexagonTargetLayout<HexagonELFType>::ORDER_SDATA) {
+ this->_type = SHT_PROGBITS;
+ this->_flags = SHF_ALLOC | SHF_WRITE;
+ this->_alignment = 4096;
+ }
+
+ /// \brief Finalize the section contents before writing
+ virtual void doPreFlight();
+
+ /// \brief Does this section have an output segment.
+ virtual bool hasOutputSegment() { return true; }
+
+ const lld::AtomLayout *appendAtom(const Atom *atom) {
+ const DefinedAtom *definedAtom = cast<DefinedAtom>(atom);
+ DefinedAtom::Alignment atomAlign = definedAtom->alignment();
+ uint64_t alignment = 1u << atomAlign.powerOf2;
+ this->_atoms.push_back(new (this->_alloc) lld::AtomLayout(atom, 0, 0));
+ // Set the section alignment to the largest alignment
+ // std::max doesn't support uint64_t
+ if (this->_alignment < alignment)
+ this->_alignment = alignment;
+ return (this->_atoms.back());
+ }
+
+}; // SDataSection
+
+template <class HexagonELFType>
+void SDataSection<HexagonELFType>::doPreFlight() {
+ // sort the atoms on the alignments they have been set
+ std::stable_sort(this->_atoms.begin(), this->_atoms.end(),
+ [](const lld::AtomLayout * A,
+ const lld::AtomLayout * B) {
+ const DefinedAtom *definedAtomA = cast<DefinedAtom>(A->_atom);
+ const DefinedAtom *definedAtomB = cast<DefinedAtom>(B->_atom);
+ int64_t alignmentA = 1 << definedAtomA->alignment().powerOf2;
+ int64_t alignmentB = 1 << definedAtomB->alignment().powerOf2;
+ if (alignmentA == alignmentB) {
+ if (definedAtomA->merge() == DefinedAtom::mergeAsTentative)
+ return false;
+ if (definedAtomB->merge() == DefinedAtom::mergeAsTentative)
+ return true;
+ }
+ return alignmentA < alignmentB;
+ });
+
+ // Set the fileOffset, and the appropriate size of the section
+ for (auto &ai : this->_atoms) {
+ const DefinedAtom *definedAtom = cast<DefinedAtom>(ai->_atom);
+ DefinedAtom::Alignment atomAlign = definedAtom->alignment();
+ uint64_t fOffset = this->alignOffset(this->fileSize(), atomAlign);
+ uint64_t mOffset = this->alignOffset(this->memSize(), atomAlign);
+ ai->_fileOffset = fOffset;
+ this->_fsize = fOffset + definedAtom->size();
+ this->_msize = mOffset + definedAtom->size();
+ }
+} // finalize
+
+} // elf
+} // lld
+
+#endif // LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_SECTION_CHUNKS_H
diff --git a/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp b/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
new file mode 100644
index 0000000000000..9b10c2f160f41
--- /dev/null
+++ b/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
@@ -0,0 +1,334 @@
+//===- lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp --------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "HexagonExecutableWriter.h"
+#include "HexagonDynamicLibraryWriter.h"
+#include "HexagonLinkingContext.h"
+#include "HexagonTargetHandler.h"
+
+using namespace lld;
+using namespace elf;
+using namespace llvm::ELF;
+
+using llvm::makeArrayRef;
+
+HexagonTargetHandler::HexagonTargetHandler(HexagonLinkingContext &context)
+ : _hexagonLinkingContext(context),
+ _hexagonRuntimeFile(new HexagonRuntimeFile<HexagonELFType>(context)),
+ _hexagonTargetLayout(new HexagonTargetLayout<HexagonELFType>(context)),
+ _hexagonRelocationHandler(new HexagonTargetRelocationHandler(
+ *_hexagonTargetLayout.get())) {}
+
+std::unique_ptr<Writer> HexagonTargetHandler::getWriter() {
+ switch (_hexagonLinkingContext.getOutputELFType()) {
+ case llvm::ELF::ET_EXEC:
+ return std::unique_ptr<Writer>(
+ new elf::HexagonExecutableWriter<HexagonELFType>(
+ _hexagonLinkingContext, *_hexagonTargetLayout.get()));
+ case llvm::ELF::ET_DYN:
+ return std::unique_ptr<Writer>(
+ new elf::HexagonDynamicLibraryWriter<HexagonELFType>(
+ _hexagonLinkingContext, *_hexagonTargetLayout.get()));
+ case llvm::ELF::ET_REL:
+ llvm_unreachable("TODO: support -r mode");
+ default:
+ llvm_unreachable("unsupported output type");
+ }
+}
+
+using namespace llvm::ELF;
+
+// .got atom
+const uint8_t hexagonGotAtomContent[4] = { 0 };
+// .got.plt atom (entry 0)
+const uint8_t hexagonGotPlt0AtomContent[16] = { 0 };
+// .got.plt atom (all other entries)
+const uint8_t hexagonGotPltAtomContent[4] = { 0 };
+// .plt (entry 0)
+const uint8_t hexagonPlt0AtomContent[28] = {
+ 0x00, 0x40, 0x00, 0x00, // { immext (#0)
+ 0x1c, 0xc0, 0x49, 0x6a, // r28 = add (pc, ##GOT0@PCREL) } # address of GOT0
+ 0x0e, 0x42, 0x9c, 0xe2, // { r14 -= add (r28, #16) # offset of GOTn from GOTa
+ 0x4f, 0x40, 0x9c, 0x91, // r15 = memw (r28 + #8) # object ID at GOT2
+ 0x3c, 0xc0, 0x9c, 0x91, // r28 = memw (r28 + #4) }# dynamic link at GOT1
+ 0x0e, 0x42, 0x0e, 0x8c, // { r14 = asr (r14, #2) # index of PLTn
+ 0x00, 0xc0, 0x9c, 0x52, // jumpr r28 } # call dynamic linker
+};
+
+// .plt (other entries)
+const uint8_t hexagonPltAtomContent[16] = {
+ 0x00, 0x40, 0x00, 0x00, // { immext (#0)
+ 0x0e, 0xc0, 0x49, 0x6a, // r14 = add (pc, ##GOTn@PCREL) } # address of GOTn
+ 0x1c, 0xc0, 0x8e, 0x91, // r28 = memw (r14) # contents of GOTn
+ 0x00, 0xc0, 0x9c, 0x52, // jumpr r28 # call it
+};
+
+class HexagonGOTAtom : public GOTAtom {
+public:
+ HexagonGOTAtom(const File &f) : GOTAtom(f, ".got") {}
+
+ ArrayRef<uint8_t> rawContent() const override {
+ return makeArrayRef(hexagonGotAtomContent);
+ }
+
+ Alignment alignment() const override { return Alignment(2); }
+};
+
+class HexagonGOTPLTAtom : public GOTAtom {
+public:
+ HexagonGOTPLTAtom(const File &f) : GOTAtom(f, ".got.plt") {}
+
+ ArrayRef<uint8_t> rawContent() const override {
+ return makeArrayRef(hexagonGotPltAtomContent);
+ }
+
+ Alignment alignment() const override { return Alignment(2); }
+};
+
+class HexagonGOTPLT0Atom : public GOTAtom {
+public:
+ HexagonGOTPLT0Atom(const File &f) : GOTAtom(f, ".got.plt") {}
+
+ ArrayRef<uint8_t> rawContent() const override {
+ return makeArrayRef(hexagonGotPlt0AtomContent);
+ }
+
+ Alignment alignment() const override { return Alignment(3); }
+};
+
+class HexagonPLT0Atom : public PLT0Atom {
+public:
+ HexagonPLT0Atom(const File &f) : PLT0Atom(f) {}
+
+ ArrayRef<uint8_t> rawContent() const override {
+ return makeArrayRef(hexagonPlt0AtomContent);
+ }
+};
+
+class HexagonPLTAtom : public PLTAtom {
+
+public:
+ HexagonPLTAtom(const File &f, StringRef secName) : PLTAtom(f, secName) {}
+
+ ArrayRef<uint8_t> rawContent() const override {
+ return makeArrayRef(hexagonPltAtomContent);
+ }
+};
+
+class ELFPassFile : public SimpleFile {
+public:
+ ELFPassFile(const ELFLinkingContext &eti) : SimpleFile("ELFPassFile") {
+ setOrdinal(eti.getNextOrdinalAndIncrement());
+ }
+
+ llvm::BumpPtrAllocator _alloc;
+};
+
+/// \brief Create GOT and PLT entries for relocations. Handles standard GOT/PLT
+template <class Derived> class GOTPLTPass : public Pass {
+ /// \brief Handle a specific reference.
+ void handleReference(const DefinedAtom &atom, const Reference &ref) {
+ if (ref.kindNamespace() != Reference::KindNamespace::ELF)
+ return;
+ assert(ref.kindArch() == Reference::KindArch::Hexagon);
+ switch (ref.kindValue()) {
+ case R_HEX_PLT_B22_PCREL:
+ case R_HEX_B22_PCREL:
+ static_cast<Derived *>(this)->handlePLT32(ref);
+ break;
+ case R_HEX_GOT_LO16:
+ case R_HEX_GOT_HI16:
+ case R_HEX_GOT_32_6_X:
+ case R_HEX_GOT_16_X:
+ case R_HEX_GOT_11_X:
+ static_cast<Derived *>(this)->handleGOTREL(ref);
+ break;
+ }
+ }
+
+protected:
+ /// \brief Create a GOT entry containing 0.
+ const GOTAtom *getNullGOT() {
+ if (!_null) {
+ _null = new (_file._alloc) HexagonGOTPLTAtom(_file);
+#ifndef NDEBUG
+ _null->_name = "__got_null";
+#endif
+ }
+ return _null;
+ }
+
+public:
+ GOTPLTPass(const ELFLinkingContext &ctx)
+ : _file(ctx), _null(nullptr), _PLT0(nullptr), _got0(nullptr) {}
+
+ /// \brief Do the pass.
+ ///
+ /// The goal here is to first process each reference individually. Each call
+ /// to handleReference may modify the reference itself and/or create new
+ /// atoms which must be stored in one of the maps below.
+ ///
+ /// After all references are handled, the atoms created during that are all
+ /// added to mf.
+ void perform(std::unique_ptr<MutableFile> &mf) override {
+ // Process all references.
+ for (const auto &atom : mf->defined())
+ for (const auto &ref : *atom)
+ handleReference(*atom, *ref);
+
+ // Add all created atoms to the link.
+ uint64_t ordinal = 0;
+ if (_PLT0) {
+ _PLT0->setOrdinal(ordinal++);
+ mf->addAtom(*_PLT0);
+ }
+ for (auto &plt : _pltVector) {
+ plt->setOrdinal(ordinal++);
+ mf->addAtom(*plt);
+ }
+ if (_null) {
+ _null->setOrdinal(ordinal++);
+ mf->addAtom(*_null);
+ }
+ if (_got0) {
+ _got0->setOrdinal(ordinal++);
+ mf->addAtom(*_got0);
+ }
+ for (auto &got : _gotVector) {
+ got->setOrdinal(ordinal++);
+ mf->addAtom(*got);
+ }
+ }
+
+protected:
+ /// \brief Owner of all the Atoms created by this pass.
+ ELFPassFile _file;
+
+ /// \brief Map Atoms to their GOT entries.
+ llvm::DenseMap<const Atom *, GOTAtom *> _gotMap;
+
+ /// \brief Map Atoms to their PLT entries.
+ llvm::DenseMap<const Atom *, PLTAtom *> _pltMap;
+
+ /// \brief the list of GOT/PLT atoms
+ std::vector<GOTAtom *> _gotVector;
+ std::vector<PLTAtom *> _pltVector;
+
+ /// \brief GOT entry that is always 0. Used for undefined weaks.
+ GOTAtom *_null;
+
+ /// \brief The got and plt entries for .PLT0. This is used to call into the
+ /// dynamic linker for symbol resolution.
+ /// @{
+ PLT0Atom *_PLT0;
+ GOTAtom *_got0;
+ /// @}
+};
+
+class DynamicGOTPLTPass final : public GOTPLTPass<DynamicGOTPLTPass> {
+public:
+ DynamicGOTPLTPass(const elf::HexagonLinkingContext &ctx) : GOTPLTPass(ctx) {
+ _got0 = new (_file._alloc) HexagonGOTPLT0Atom(_file);
+#ifndef NDEBUG
+ _got0->_name = "__got0";
+#endif
+ }
+
+ const PLT0Atom *getPLT0() {
+ if (_PLT0)
+ return _PLT0;
+ _PLT0 = new (_file._alloc) HexagonPLT0Atom(_file);
+ _PLT0->addReferenceELF_Hexagon(R_HEX_B32_PCREL_X, 0, _got0, 0);
+ _PLT0->addReferenceELF_Hexagon(R_HEX_6_PCREL_X, 4, _got0, 4);
+ DEBUG_WITH_TYPE("PLT", llvm::dbgs() << "[ PLT0/GOT0 ] "
+ << "Adding plt0/got0 \n");
+ return _PLT0;
+ }
+
+ const PLTAtom *getPLTEntry(const Atom *a) {
+ auto plt = _pltMap.find(a);
+ if (plt != _pltMap.end())
+ return plt->second;
+ auto ga = new (_file._alloc) HexagonGOTPLTAtom(_file);
+ ga->addReferenceELF_Hexagon(R_HEX_JMP_SLOT, 0, a, 0);
+ auto pa = new (_file._alloc) HexagonPLTAtom(_file, ".plt");
+ pa->addReferenceELF_Hexagon(R_HEX_B32_PCREL_X, 0, ga, 0);
+ pa->addReferenceELF_Hexagon(R_HEX_6_PCREL_X, 4, ga, 4);
+
+ // Point the got entry to the PLT0 atom initially
+ ga->addReferenceELF_Hexagon(R_HEX_32, 0, getPLT0(), 0);
+#ifndef NDEBUG
+ ga->_name = "__got_";
+ ga->_name += a->name();
+ pa->_name = "__plt_";
+ pa->_name += a->name();
+ DEBUG_WITH_TYPE("PLT", llvm::dbgs() << "[" << a->name() << "] "
+ << "Adding plt/got: " << pa->_name
+ << "/" << ga->_name << "\n");
+#endif
+ _gotMap[a] = ga;
+ _pltMap[a] = pa;
+ _gotVector.push_back(ga);
+ _pltVector.push_back(pa);
+ return pa;
+ }
+
+ const GOTAtom *getGOTEntry(const Atom *a) {
+ auto got = _gotMap.find(a);
+ if (got != _gotMap.end())
+ return got->second;
+ auto ga = new (_file._alloc) HexagonGOTAtom(_file);
+ ga->addReferenceELF_Hexagon(R_HEX_GLOB_DAT, 0, a, 0);
+
+#ifndef NDEBUG
+ ga->_name = "__got_";
+ ga->_name += a->name();
+ DEBUG_WITH_TYPE("GOT", llvm::dbgs() << "[" << a->name() << "] "
+ << "Adding got: " << ga->_name << "\n");
+#endif
+ _gotMap[a] = ga;
+ _gotVector.push_back(ga);
+ return ga;
+ }
+
+ std::error_code handleGOTREL(const Reference &ref) {
+ // Turn this so that the target is set to the GOT entry
+ const_cast<Reference &>(ref).setTarget(getGOTEntry(ref.target()));
+ return std::error_code();
+ }
+
+ std::error_code handlePLT32(const Reference &ref) {
+ // Turn this into a PC32 to the PLT entry.
+ assert(ref.kindNamespace() == Reference::KindNamespace::ELF);
+ assert(ref.kindArch() == Reference::KindArch::Hexagon);
+ const_cast<Reference &>(ref).setKindValue(R_HEX_B22_PCREL);
+ const_cast<Reference &>(ref).setTarget(getPLTEntry(ref.target()));
+ return std::error_code();
+ }
+};
+
+void elf::HexagonLinkingContext::addPasses(PassManager &pm) {
+ if (isDynamic())
+ pm.add(llvm::make_unique<DynamicGOTPLTPass>(*this));
+ ELFLinkingContext::addPasses(pm);
+}
+
+void HexagonTargetHandler::registerRelocationNames(Registry &registry) {
+ registry.addKindTable(Reference::KindNamespace::ELF,
+ Reference::KindArch::Hexagon, kindStrings);
+}
+
+#define ELF_RELOC(name, value) LLD_KIND_STRING_ENTRY(name),
+
+const Registry::KindStrings HexagonTargetHandler::kindStrings[] = {
+#include "llvm/Support/ELFRelocs/Hexagon.def"
+ LLD_KIND_STRING_END
+};
+
+#undef ELF_RELOC
diff --git a/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h b/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h
new file mode 100644
index 0000000000000..f4315f710ec7c
--- /dev/null
+++ b/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h
@@ -0,0 +1,143 @@
+//===- lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h ----------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef HEXAGON_TARGET_HANDLER_H
+#define HEXAGON_TARGET_HANDLER_H
+
+#include "DefaultTargetHandler.h"
+#include "HexagonELFReader.h"
+#include "HexagonExecutableAtoms.h"
+#include "HexagonRelocationHandler.h"
+#include "HexagonSectionChunks.h"
+#include "TargetLayout.h"
+
+namespace lld {
+namespace elf {
+class HexagonLinkingContext;
+
+/// \brief TargetLayout for Hexagon
+template <class HexagonELFType>
+class HexagonTargetLayout final : public TargetLayout<HexagonELFType> {
+public:
+ enum HexagonSectionOrder {
+ ORDER_SDATA = 205
+ };
+
+ HexagonTargetLayout(HexagonLinkingContext &hti)
+ : TargetLayout<HexagonELFType>(hti), _sdataSection(nullptr),
+ _gotSymAtom(nullptr), _cachedGotSymAtom(false) {
+ _sdataSection = new (_alloc) SDataSection<HexagonELFType>(hti);
+ }
+
+ /// \brief Return the section order for a input section
+ virtual Layout::SectionOrder getSectionOrder(
+ StringRef name, int32_t contentType, int32_t contentPermissions) {
+ if ((contentType == DefinedAtom::typeDataFast) ||
+ (contentType == DefinedAtom::typeZeroFillFast))
+ return ORDER_SDATA;
+
+ return DefaultLayout<HexagonELFType>::getSectionOrder(name, contentType,
+ contentPermissions);
+ }
+
+ /// \brief Return the appropriate input section name.
+ virtual StringRef getInputSectionName(const DefinedAtom *da) const {
+ switch (da->contentType()) {
+ case DefinedAtom::typeDataFast:
+ case DefinedAtom::typeZeroFillFast:
+ return ".sdata";
+ default:
+ break;
+ }
+ return DefaultLayout<HexagonELFType>::getInputSectionName(da);
+ }
+
+ /// \brief Gets or creates a section.
+ virtual AtomSection<HexagonELFType> *
+ createSection(StringRef name, int32_t contentType,
+ DefinedAtom::ContentPermissions contentPermissions,
+ Layout::SectionOrder sectionOrder) {
+ if ((contentType == DefinedAtom::typeDataFast) ||
+ (contentType == DefinedAtom::typeZeroFillFast))
+ return _sdataSection;
+ return DefaultLayout<HexagonELFType>::createSection(
+ name, contentType, contentPermissions, sectionOrder);
+ }
+
+ /// \brief get the segment type for the section thats defined by the target
+ virtual Layout::SegmentType
+ getSegmentType(Section<HexagonELFType> *section) const {
+ if (section->order() == ORDER_SDATA)
+ return PT_LOAD;
+
+ return DefaultLayout<HexagonELFType>::getSegmentType(section);
+ }
+
+ Section<HexagonELFType> *getSDataSection() const {
+ return _sdataSection;
+ }
+
+ uint64_t getGOTSymAddr() {
+ if (!_cachedGotSymAtom) {
+ auto gotAtomIter = this->findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
+ _gotSymAtom = (*gotAtomIter);
+ _cachedGotSymAtom = true;
+ }
+ if (_gotSymAtom)
+ return _gotSymAtom->_virtualAddr;
+ return 0;
+ }
+
+private:
+ llvm::BumpPtrAllocator _alloc;
+ SDataSection<HexagonELFType> *_sdataSection;
+ AtomLayout *_gotSymAtom;
+ bool _cachedGotSymAtom;
+};
+
+/// \brief TargetHandler for Hexagon
+class HexagonTargetHandler final :
+ public DefaultTargetHandler<HexagonELFType> {
+public:
+ HexagonTargetHandler(HexagonLinkingContext &targetInfo);
+
+ void registerRelocationNames(Registry &registry) override;
+
+ const HexagonTargetRelocationHandler &getRelocationHandler() const override {
+ return *(_hexagonRelocationHandler.get());
+ }
+
+ HexagonTargetLayout<HexagonELFType> &getTargetLayout() override {
+ return *(_hexagonTargetLayout.get());
+ }
+
+ std::unique_ptr<Reader> getObjReader() override {
+ return std::unique_ptr<Reader>(
+ new HexagonELFObjectReader(_hexagonLinkingContext));
+ }
+
+ std::unique_ptr<Reader> getDSOReader() override {
+ return std::unique_ptr<Reader>(
+ new HexagonELFDSOReader(_hexagonLinkingContext));
+ }
+
+ std::unique_ptr<Writer> getWriter() override;
+
+private:
+ llvm::BumpPtrAllocator _alloc;
+ static const Registry::KindStrings kindStrings[];
+ HexagonLinkingContext &_hexagonLinkingContext;
+ std::unique_ptr<HexagonRuntimeFile<HexagonELFType> > _hexagonRuntimeFile;
+ std::unique_ptr<HexagonTargetLayout<HexagonELFType>> _hexagonTargetLayout;
+ std::unique_ptr<HexagonTargetRelocationHandler> _hexagonRelocationHandler;
+};
+} // end namespace elf
+} // end namespace lld
+
+#endif
diff --git a/lib/ReaderWriter/ELF/Hexagon/Makefile b/lib/ReaderWriter/ELF/Hexagon/Makefile
new file mode 100644
index 0000000000000..8d6f1a0a3b1ed
--- /dev/null
+++ b/lib/ReaderWriter/ELF/Hexagon/Makefile
@@ -0,0 +1,16 @@
+##===- lld/lib/ReaderWriter/ELF/Hexagon/Makefile ----------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LLD_LEVEL := ../../../..
+LIBRARYNAME := lldHexagonELFTarget
+USEDLIBS = lldCore.a
+
+CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLD_LEVEL)/lib/ReaderWriter/ELF/Hexagon -I$(PROJ_SRC_DIR)/$(LLD_LEVEL)/lib/ReaderWriter/ELF
+
+include $(LLD_LEVEL)/Makefile