diff options
Diffstat (limited to 'lib/ReaderWriter/ELF/Hexagon')
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 ®istry) { + 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 ®istry) 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 |