diff options
author | Tom Stellard <thomas.stellard@amd.com> | 2015-08-27 15:55:44 +0000 |
---|---|---|
committer | Tom Stellard <thomas.stellard@amd.com> | 2015-08-27 15:55:44 +0000 |
commit | 15d1fa1bccc0a7d90cdacc5844858d0899767597 (patch) | |
tree | 6d04f6e7fd9d2105a71f04fea470b90511e0fad1 | |
parent | dc8c48924a4f823aff8c07a3366e3d267d29186d (diff) | |
download | llvm-15d1fa1bccc0a7d90cdacc5844858d0899767597.zip llvm-15d1fa1bccc0a7d90cdacc5844858d0899767597.tar.gz llvm-15d1fa1bccc0a7d90cdacc5844858d0899767597.tar.bz2 |
ELF: Add AMDGPU ReaderWriter
This is a basic implementation that allows lld to emit binaries
consumable by the HSA runtime.
Differential Revision: http://reviews.llvm.org/D11267
llvm-svn: 246155
19 files changed, 489 insertions, 4 deletions
diff --git a/lld/include/lld/Core/Reference.h b/lld/include/lld/Core/Reference.h index 7a804c3..971721e 100644 --- a/lld/include/lld/Core/Reference.h +++ b/lld/include/lld/Core/Reference.h @@ -56,7 +56,7 @@ public: void setKindNamespace(KindNamespace ns) { _kindNamespace = (uint8_t)ns; } // Which architecture the kind value is for. - enum class KindArch { all, AArch64, ARM, Hexagon, Mips, x86, x86_64 }; + enum class KindArch { all, AArch64, AMDGPU, ARM, Hexagon, Mips, x86, x86_64 }; KindArch kindArch() const { return (KindArch)_kindArch; } void setKindArch(KindArch a) { _kindArch = (uint8_t)a; } diff --git a/lld/include/lld/ReaderWriter/ELFLinkingContext.h b/lld/include/lld/ReaderWriter/ELFLinkingContext.h index acf6c3c..d1a5b28 100644 --- a/lld/include/lld/ReaderWriter/ELFLinkingContext.h +++ b/lld/include/lld/ReaderWriter/ELFLinkingContext.h @@ -44,6 +44,7 @@ using llvm::object::ELF64BE; class ELFWriter; std::unique_ptr<ELFLinkingContext> createAArch64LinkingContext(llvm::Triple); +std::unique_ptr<ELFLinkingContext> createAMDGPULinkingContext(llvm::Triple); std::unique_ptr<ELFLinkingContext> createARMLinkingContext(llvm::Triple); std::unique_ptr<ELFLinkingContext> createExampleLinkingContext(llvm::Triple); std::unique_ptr<ELFLinkingContext> createHexagonLinkingContext(llvm::Triple); diff --git a/lld/lib/Driver/CMakeLists.txt b/lld/lib/Driver/CMakeLists.txt index 382e36b..64498cc 100644 --- a/lld/lib/Driver/CMakeLists.txt +++ b/lld/lib/Driver/CMakeLists.txt @@ -21,6 +21,7 @@ add_llvm_library(lldDriver lldELF lldELF2 lldAArch64ELFTarget + lldAMDGPUELFTarget lldARMELFTarget lldHexagonELFTarget lldMipsELFTarget diff --git a/lld/lib/Driver/GnuLdDriver.cpp b/lld/lib/Driver/GnuLdDriver.cpp index c78759e..67fbf3c 100644 --- a/lld/lib/Driver/GnuLdDriver.cpp +++ b/lld/lib/Driver/GnuLdDriver.cpp @@ -329,6 +329,7 @@ std::unique_ptr<ELFLinkingContext> GnuLdDriver::createELFLinkingContext(llvm::Triple triple) { std::unique_ptr<ELFLinkingContext> p; if ((p = elf::createAArch64LinkingContext(triple))) return p; + if ((p = elf::createAMDGPULinkingContext(triple))) return p; if ((p = elf::createARMLinkingContext(triple))) return p; if ((p = elf::createExampleLinkingContext(triple))) return p; if ((p = elf::createHexagonLinkingContext(triple))) return p; diff --git a/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPUExecutableWriter.cpp b/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPUExecutableWriter.cpp new file mode 100644 index 0000000..4ef97ff --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPUExecutableWriter.cpp @@ -0,0 +1,33 @@ +//===- lib/ReaderWriter/ELF/AMDGPU/AMDGPUExecutableWriter.cpp -------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "AMDGPUExecutableWriter.h" + +using namespace lld::elf; + +AMDGPUExecutableWriter::AMDGPUExecutableWriter(AMDGPULinkingContext &ctx, + AMDGPUTargetLayout &layout) + : ExecutableWriter(ctx, layout), _ctx(ctx), _targetLayout(layout) {} + +void AMDGPUExecutableWriter::createImplicitFiles( + std::vector<std::unique_ptr<File>> &Result) { + // ExecutableWriter::createImplicitFiles() adds C runtime symbols that we + // don't need, so we use the OutputELFWriter implementation instead. + OutputELFWriter<ELF64LE>::createImplicitFiles(Result); +} + +void AMDGPUExecutableWriter::finalizeDefaultAtomValues() { + + // ExecutableWriter::finalizeDefaultAtomValues() assumes the presence of + // C runtime symbols. However, since we skip the call to + // ExecutableWriter::createImplicitFiles(), these symbols are never added + // and ExectuableWriter::finalizeDefaultAtomValues() will crash if we call + // it. + OutputELFWriter<ELF64LE>::finalizeDefaultAtomValues(); +} diff --git a/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPUExecutableWriter.h b/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPUExecutableWriter.h new file mode 100644 index 0000000..99f41c2 --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPUExecutableWriter.h @@ -0,0 +1,42 @@ +//===- lib/ReaderWriter/ELF/AMDGPU/AMDGPUExecutableWriter.h ---------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef AMDGPU_EXECUTABLE_WRITER_H +#define AMDGPU_EXECUTABLE_WRITER_H + +#include "ExecutableWriter.h" +#include "AMDGPULinkingContext.h" +#include "AMDGPUSymbolTable.h" +#include "AMDGPUTargetHandler.h" + +namespace lld { +namespace elf { + +class AMDGPUTargetLayout; + +class AMDGPUExecutableWriter : public ExecutableWriter<ELF64LE> { +public: + AMDGPUExecutableWriter(AMDGPULinkingContext &ctx, AMDGPUTargetLayout &layout); + + unique_bump_ptr<SymbolTable<ELF64LE>> createSymbolTable() override { + return unique_bump_ptr<SymbolTable<ELF64LE>>(new (this->_alloc) + AMDGPUSymbolTable(_ctx)); + } + + void createImplicitFiles(std::vector<std::unique_ptr<File>> &Result) override; + void finalizeDefaultAtomValues() override; + +private: + AMDGPULinkingContext &_ctx; + AMDGPUTargetLayout &_targetLayout; +}; + +} // namespace elf +} // namespace lld + +#endif // AMDGPU_EXECUTABLE_WRITER_H diff --git a/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPULinkingContext.cpp b/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPULinkingContext.cpp new file mode 100644 index 0000000..b1e8364 --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPULinkingContext.cpp @@ -0,0 +1,41 @@ +//===- lib/ReaderWriter/ELF/AMDGPU/AMDGPULinkingContext.cpp ---------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===------------------------------------------------------------------------===// + +#include "AMDGPULinkingContext.h" +#include "AMDGPUTargetHandler.h" + +namespace lld { +namespace elf { + +std::unique_ptr<ELFLinkingContext> +createAMDGPULinkingContext(llvm::Triple triple) { + if (triple.getArch() == llvm::Triple::amdgcn) + return llvm::make_unique<AMDGPULinkingContext>(triple); + return nullptr; +} + +AMDGPULinkingContext::AMDGPULinkingContext(llvm::Triple triple) + : ELFLinkingContext(triple, llvm::make_unique<AMDGPUTargetHandler>(*this)) { +} + +static const Registry::KindStrings kindStrings[] = {LLD_KIND_STRING_END}; + +void AMDGPULinkingContext::registerRelocationNames(Registry ®istry) { + registry.addKindTable(Reference::KindNamespace::ELF, + Reference::KindArch::AMDGPU, kindStrings); +} + +void setAMDGPUELFHeader(ELFHeader<ELF64LE> &elfHeader) { + elfHeader.e_ident(llvm::ELF::EI_OSABI, ELFOSABI_AMDGPU_HSA); +} + +StringRef AMDGPULinkingContext::entrySymbolName() const { return ""; } + +} // namespace elf +} // namespace lld diff --git a/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPULinkingContext.h b/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPULinkingContext.h new file mode 100644 index 0000000..1cc7a3c --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPULinkingContext.h @@ -0,0 +1,36 @@ +//===- lib/ReaderWriter/ELF/AMDGPU/AMDGPULinkingContext.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_AMDGPU_AMDGPU_LINKING_CONTEXT_H +#define LLD_READER_WRITER_ELF_AMDGPU_AMDGPU_LINKING_CONTEXT_H + +#include "OutputELFWriter.h" +#include "lld/ReaderWriter/ELFLinkingContext.h" +#include "llvm/Object/ELF.h" +#include "llvm/Support/ELF.h" + +namespace lld { +namespace elf { + +class AMDGPULinkingContext final : public ELFLinkingContext { +public: + AMDGPULinkingContext(llvm::Triple triple); + int getMachineType() const override { return llvm::ELF::EM_AMDGPU; } + + void registerRelocationNames(Registry &r) override; + + StringRef entrySymbolName() const override; +}; + +void setAMDGPUELFHeader(ELFHeader<ELF64LE> &elfHeader); + +} // elf +} // lld + +#endif // LLD_READER_WRITER_ELF_AMDGPU_AMDGPU_LINKING_CONTEXT_H diff --git a/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPURelocationHandler.cpp b/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPURelocationHandler.cpp new file mode 100644 index 0000000..fdbc0b2 --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPURelocationHandler.cpp @@ -0,0 +1,18 @@ +//===- lib/ReaderWriter/ELF/AMDGPU/AMDGPURelocationHandler.cpp -----------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "AMDGPURelocationHandler.h" + +using namespace lld::elf; + +std::error_code AMDGPUTargetRelocationHandler::applyRelocation( + ELFWriter &writer, llvm::FileOutputBuffer &buf, const AtomLayout &atom, + const Reference &ref) const { + return std::error_code(); +} diff --git a/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPURelocationHandler.h b/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPURelocationHandler.h new file mode 100644 index 0000000..82c7c11 --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPURelocationHandler.h @@ -0,0 +1,33 @@ +//===- lld/ReaderWriter/ELF/AMDGPU/AMDGPURelocationHandler.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_AMDGPU_AMDGPU_RELOCATION_HANDLER_H +#define LLD_READER_WRITER_ELF_AMDGPU_AMDGPU_RELOCATION_HANDLER_H + +#include "lld/ReaderWriter/ELFLinkingContext.h" + +namespace lld { +namespace elf { +class AMDGPUTargetHandler; +class AMDGPUTargetLayout; + +class AMDGPUTargetRelocationHandler final : public TargetRelocationHandler { +public: + AMDGPUTargetRelocationHandler(AMDGPUTargetLayout &layout) + : _targetLayout(layout) {} + + std::error_code applyRelocation(ELFWriter &, llvm::FileOutputBuffer &, + const AtomLayout &, + const Reference &) const override; + +private: + AMDGPUTargetLayout &_targetLayout; +}; +} // elf +} // lld +#endif diff --git a/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPUSymbolTable.cpp b/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPUSymbolTable.cpp new file mode 100644 index 0000000..4b0414f --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPUSymbolTable.cpp @@ -0,0 +1,31 @@ +//===--------- lib/ReaderWriter/ELF/AMDGPU/AMDGPUSymbolTable.cpp ----------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "AMDGPUSymbolTable.h" +#include "ELFFile.h" +#include "Atoms.h" +#include "SectionChunks.h" + +using namespace lld::elf; + +AMDGPUSymbolTable::AMDGPUSymbolTable(const ELFLinkingContext &ctx) + : SymbolTable(ctx, ".symtab", TargetLayout<ELF64LE>::ORDER_SYMBOL_TABLE) {} + +void AMDGPUSymbolTable::addDefinedAtom(Elf_Sym &sym, const DefinedAtom *da, + int64_t addr) { + SymbolTable::addDefinedAtom(sym, da, addr); + + // FIXME: Only do this for kernel functions. + sym.setType(STT_AMDGPU_HSA_KERNEL); + + // Make st_value section relative. + // FIXME: This is hack to give kernel symbols a section relative offset. + // Because of this hack only on kernel can be included in a binary file. + sym.st_value = 0; +} diff --git a/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPUSymbolTable.h b/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPUSymbolTable.h new file mode 100644 index 0000000..41c3be5 --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPUSymbolTable.h @@ -0,0 +1,32 @@ +//===--------- lib/ReaderWriter/ELF/AMDGPU/AMDGPUSymbolTable.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_AMDGPU_AMDGPU_SYMBOL_TABLE_H +#define LLD_READER_WRITER_ELF_AMDGPU_AMDGPU_SYMBOL_TABLE_H + +#include "TargetLayout.h" + +namespace lld { +namespace elf { + +/// \brief The SymbolTable class represents the symbol table in a ELF file +class AMDGPUSymbolTable : public SymbolTable<ELF64LE> { +public: + typedef llvm::object::Elf_Sym_Impl<ELF64LE> Elf_Sym; + + AMDGPUSymbolTable(const ELFLinkingContext &ctx); + + void addDefinedAtom(Elf_Sym &sym, const DefinedAtom *da, + int64_t addr) override; +}; + +} // elf +} // lld + +#endif diff --git a/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPUTargetHandler.cpp b/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPUTargetHandler.cpp new file mode 100644 index 0000000..c86933f --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPUTargetHandler.cpp @@ -0,0 +1,65 @@ +//===- lib/ReaderWriter/ELF/AMDGPU/AMDGPUTargetHandler.cpp ----------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "TargetLayout.h" +#include "AMDGPUExecutableWriter.h" +#include "AMDGPULinkingContext.h" +#include "AMDGPUTargetHandler.h" +#include "llvm/Support/ELF.h" + +namespace lld { +namespace elf { + +AMDGPUTargetHandler::AMDGPUTargetHandler(AMDGPULinkingContext &ctx) + : _ctx(ctx), _targetLayout(new AMDGPUTargetLayout(ctx)), + _relocationHandler(new AMDGPUTargetRelocationHandler(*_targetLayout)) {} + +std::unique_ptr<Writer> AMDGPUTargetHandler::getWriter() { + switch (_ctx.getOutputELFType()) { + case llvm::ELF::ET_EXEC: + return llvm::make_unique<AMDGPUExecutableWriter>(_ctx, *_targetLayout); + case llvm::ELF::ET_DYN: + llvm_unreachable("TODO: support dynamic libraries"); + case llvm::ELF::ET_REL: + llvm_unreachable("TODO: support -r mode"); + default: + llvm_unreachable("unsupported output type"); + } +} + +HSATextSection::HSATextSection(const ELFLinkingContext &ctx) + : AtomSection(ctx, ".text", DefinedAtom::typeCode, 0, 0) { + _type = SHT_PROGBITS; + _flags = SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR | SHF_AMDGPU_HSA_AGENT | + SHF_AMDGPU_HSA_CODE; + + // FIXME: What alignment should we use here? + _alignment = 4096; +} + +void AMDGPUTargetLayout::assignSectionsToSegments() { + + TargetLayout::assignSectionsToSegments(); + for (OutputSection<ELF64LE> *osi : _outputSections) { + for (Section<ELF64LE> *section : osi->sections()) { + StringRef InputSectionName = section->inputSectionName(); + if (InputSectionName != ".text") + continue; + + Segment<ELF64LE> *segment = new (_allocator) Segment<ELF64LE>( + _ctx, "PT_AMDGPU_HSA_LOAD_CODE_AGENT", PT_AMDGPU_HSA_LOAD_CODE_AGENT); + _segments.push_back(segment); + assert(segment); + segment->append(section); + } + } +} + +} // namespace elf +} // namespace lld diff --git a/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPUTargetHandler.h b/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPUTargetHandler.h new file mode 100644 index 0000000..a944ef0 --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/AMDGPU/AMDGPUTargetHandler.h @@ -0,0 +1,80 @@ +//===- lib/ReaderWriter/ELF/AMDGPU/AMDGPUTargetHandler.h ------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef AMDGPU_TARGET_HANDLER_H +#define AMDGPU_TARGET_HANDLER_H + +#include "ELFFile.h" +#include "ELFReader.h" +#include "AMDGPURelocationHandler.h" +#include "TargetLayout.h" + +namespace lld { +namespace elf { +class AMDGPULinkingContext; + +class HSATextSection : public AtomSection<ELF64LE> { +public: + HSATextSection(const ELFLinkingContext &ctx); +}; + +/// \brief TargetLayout for AMDGPU +class AMDGPUTargetLayout final : public TargetLayout<ELF64LE> { +public: + AMDGPUTargetLayout(AMDGPULinkingContext &ctx) : TargetLayout(ctx) {} + + void assignSectionsToSegments() override; + + /// \brief Gets or creates a section. + AtomSection<ELF64LE> * + createSection(StringRef name, int32_t contentType, + DefinedAtom::ContentPermissions contentPermissions, + TargetLayout::SectionOrder sectionOrder) override { + if (name == ".text") + return new (_allocator) HSATextSection(_ctx); + + if (name == ".note") + contentType = DefinedAtom::typeRONote; + + return TargetLayout::createSection(name, contentType, contentPermissions, + sectionOrder); + } +}; + +/// \brief TargetHandler for AMDGPU +class AMDGPUTargetHandler final : public TargetHandler { +public: + AMDGPUTargetHandler(AMDGPULinkingContext &targetInfo); + + const TargetRelocationHandler &getRelocationHandler() const override { + return *_relocationHandler; + } + + std::unique_ptr<Reader> getObjReader() override { + return llvm::make_unique<ELFReader<ELFFile<ELF64LE>>>(_ctx); + } + + std::unique_ptr<Reader> getDSOReader() override { + return llvm::make_unique<ELFReader<DynamicFile<ELF64LE>>>(_ctx); + } + + std::unique_ptr<Writer> getWriter() override; + +private: + AMDGPULinkingContext &_ctx; + std::unique_ptr<AMDGPUTargetLayout> _targetLayout; + std::unique_ptr<AMDGPUTargetRelocationHandler> _relocationHandler; +}; + +void finalizeAMDGPURuntimeAtomValues(AMDGPUTargetLayout &layout); + +} // end namespace elf +} // end namespace lld + +#endif diff --git a/lld/lib/ReaderWriter/ELF/AMDGPU/CMakeLists.txt b/lld/lib/ReaderWriter/ELF/AMDGPU/CMakeLists.txt new file mode 100644 index 0000000..9c9cc10 --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/AMDGPU/CMakeLists.txt @@ -0,0 +1,13 @@ +add_llvm_library(lldAMDGPUELFTarget + AMDGPUExecutableWriter.cpp + AMDGPULinkingContext.cpp + AMDGPURelocationHandler.cpp + AMDGPUSymbolTable.cpp + AMDGPUTargetHandler.cpp + LINK_LIBS + lldELF + lldReaderWriter + lldCore + LLVMObject + LLVMSupport + ) diff --git a/lld/lib/ReaderWriter/ELF/CMakeLists.txt b/lld/lib/ReaderWriter/ELF/CMakeLists.txt index ad559bab..e3e4a02 100644 --- a/lld/lib/ReaderWriter/ELF/CMakeLists.txt +++ b/lld/lib/ReaderWriter/ELF/CMakeLists.txt @@ -27,3 +27,4 @@ add_subdirectory(Mips) add_subdirectory(Hexagon) add_subdirectory(AArch64) add_subdirectory(ARM) +add_subdirectory(AMDGPU) diff --git a/lld/lib/ReaderWriter/ELF/ELFFile.h b/lld/lib/ReaderWriter/ELF/ELFFile.h index f413471..8ed1f5e 100644 --- a/lld/lib/ReaderWriter/ELF/ELFFile.h +++ b/lld/lib/ReaderWriter/ELF/ELFFile.h @@ -196,12 +196,14 @@ protected: /// Determines if the target wants to create an atom for a section that has no /// symbol references. - bool handleSectionWithNoSymbols(const Elf_Shdr *shdr, - std::vector<const Elf_Sym *> &syms) const { + bool + handleSectionWithNoSymbols(const Elf_Shdr *shdr, + std::vector<const Elf_Sym *> &syms) const { return shdr && (shdr->sh_type == llvm::ELF::SHT_PROGBITS || shdr->sh_type == llvm::ELF::SHT_INIT_ARRAY || - shdr->sh_type == llvm::ELF::SHT_FINI_ARRAY) && + shdr->sh_type == llvm::ELF::SHT_FINI_ARRAY || + shdr->sh_type == llvm::ELF::SHT_NOTE) && syms.empty(); } diff --git a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp index 8c76a78..db5d380 100644 --- a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp +++ b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp @@ -61,6 +61,8 @@ uint16_t ELFLinkingContext::getOutputMachine() const { return llvm::ELF::EM_AARCH64; case llvm::Triple::arm: return llvm::ELF::EM_ARM; + case llvm::Triple::amdgcn: + return llvm::ELF::EM_AMDGPU; default: llvm_unreachable("Unhandled arch"); } diff --git a/lld/test/elf/AMDGPU/hsa.test b/lld/test/elf/AMDGPU/hsa.test new file mode 100644 index 0000000..89a9336 --- /dev/null +++ b/lld/test/elf/AMDGPU/hsa.test @@ -0,0 +1,53 @@ +# RUN: yaml2obj -format=elf %s > %t.obj +# RUN: lld -flavor gnu -target amdgcn--hsa %t.obj -o %t.exe --noinhibit-exec +# RUN: llvm-readobj -h -program-headers -s -symbols %t.exe | FileCheck %s + +# CHECK: ElfHeader { +# CHECK: Ident { +# CHECK: Class: 64-bit (0x2) +# CHECK: DataEncoding: LittleEndian (0x1) +# CHECK: Machine: EM_AMDGPU (0xE0) + + +# CHECK: Section { +# CHECK: Name: .text +# CHECK: Type: SHT_PROGBITS (0x1) +# CHECK: Flags [ (0xC00007 +# CHECK: SHF_ALLOC (0x2) +# CHECK: SHF_AMDGPU_HSA_AGENT (0x800000) +# CHECK: SHF_AMDGPU_HSA_CODE (0x400000) +# CHECK: SHF_EXECINSTR (0x4) +# CHECK: SHF_WRITE (0x1) +# +# CHECK: Symbol { +# CHECK: Name: kernel +# CHECK: Value: 0x0 +# CHECK: Binding: Local (0x0) +# CHECK: Type: AMDGPU_HSA_KERNEL (0xA) + +# CHECK: ProgramHeader { +# CHECK: Type: PT_AMDGPU_HSA_LOAD_CODE_AGENT (0x60000003) + +--- +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + OSABI: ELFOSABI_GNU + Type: ET_REL + Machine: EM_AMDGPU +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000004 + Content: '' + - Name: .note + Type: SHT_NOTE + AddressAlign: 0x0000000000000001 + Content: '00' +Symbols: + Local: + - Name: kernel + Type: STT_GNU_IFUNC + Section: .text +... |