forked from OSchip/llvm-project
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
This commit is contained in:
parent
dc8c48924a
commit
15d1fa1bcc
|
|
@ -56,7 +56,7 @@ public:
|
||||||
void setKindNamespace(KindNamespace ns) { _kindNamespace = (uint8_t)ns; }
|
void setKindNamespace(KindNamespace ns) { _kindNamespace = (uint8_t)ns; }
|
||||||
|
|
||||||
// Which architecture the kind value is for.
|
// 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; }
|
KindArch kindArch() const { return (KindArch)_kindArch; }
|
||||||
void setKindArch(KindArch a) { _kindArch = (uint8_t)a; }
|
void setKindArch(KindArch a) { _kindArch = (uint8_t)a; }
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ using llvm::object::ELF64BE;
|
||||||
class ELFWriter;
|
class ELFWriter;
|
||||||
|
|
||||||
std::unique_ptr<ELFLinkingContext> createAArch64LinkingContext(llvm::Triple);
|
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> createARMLinkingContext(llvm::Triple);
|
||||||
std::unique_ptr<ELFLinkingContext> createExampleLinkingContext(llvm::Triple);
|
std::unique_ptr<ELFLinkingContext> createExampleLinkingContext(llvm::Triple);
|
||||||
std::unique_ptr<ELFLinkingContext> createHexagonLinkingContext(llvm::Triple);
|
std::unique_ptr<ELFLinkingContext> createHexagonLinkingContext(llvm::Triple);
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ add_llvm_library(lldDriver
|
||||||
lldELF
|
lldELF
|
||||||
lldELF2
|
lldELF2
|
||||||
lldAArch64ELFTarget
|
lldAArch64ELFTarget
|
||||||
|
lldAMDGPUELFTarget
|
||||||
lldARMELFTarget
|
lldARMELFTarget
|
||||||
lldHexagonELFTarget
|
lldHexagonELFTarget
|
||||||
lldMipsELFTarget
|
lldMipsELFTarget
|
||||||
|
|
|
||||||
|
|
@ -329,6 +329,7 @@ std::unique_ptr<ELFLinkingContext>
|
||||||
GnuLdDriver::createELFLinkingContext(llvm::Triple triple) {
|
GnuLdDriver::createELFLinkingContext(llvm::Triple triple) {
|
||||||
std::unique_ptr<ELFLinkingContext> p;
|
std::unique_ptr<ELFLinkingContext> p;
|
||||||
if ((p = elf::createAArch64LinkingContext(triple))) return 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::createARMLinkingContext(triple))) return p;
|
||||||
if ((p = elf::createExampleLinkingContext(triple))) return p;
|
if ((p = elf::createExampleLinkingContext(triple))) return p;
|
||||||
if ((p = elf::createHexagonLinkingContext(triple))) return p;
|
if ((p = elf::createHexagonLinkingContext(triple))) return p;
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
)
|
||||||
|
|
@ -27,3 +27,4 @@ add_subdirectory(Mips)
|
||||||
add_subdirectory(Hexagon)
|
add_subdirectory(Hexagon)
|
||||||
add_subdirectory(AArch64)
|
add_subdirectory(AArch64)
|
||||||
add_subdirectory(ARM)
|
add_subdirectory(ARM)
|
||||||
|
add_subdirectory(AMDGPU)
|
||||||
|
|
|
||||||
|
|
@ -196,12 +196,14 @@ protected:
|
||||||
|
|
||||||
/// Determines if the target wants to create an atom for a section that has no
|
/// Determines if the target wants to create an atom for a section that has no
|
||||||
/// symbol references.
|
/// symbol references.
|
||||||
bool handleSectionWithNoSymbols(const Elf_Shdr *shdr,
|
bool
|
||||||
std::vector<const Elf_Sym *> &syms) const {
|
handleSectionWithNoSymbols(const Elf_Shdr *shdr,
|
||||||
|
std::vector<const Elf_Sym *> &syms) const {
|
||||||
return shdr &&
|
return shdr &&
|
||||||
(shdr->sh_type == llvm::ELF::SHT_PROGBITS ||
|
(shdr->sh_type == llvm::ELF::SHT_PROGBITS ||
|
||||||
shdr->sh_type == llvm::ELF::SHT_INIT_ARRAY ||
|
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();
|
syms.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,8 @@ uint16_t ELFLinkingContext::getOutputMachine() const {
|
||||||
return llvm::ELF::EM_AARCH64;
|
return llvm::ELF::EM_AARCH64;
|
||||||
case llvm::Triple::arm:
|
case llvm::Triple::arm:
|
||||||
return llvm::ELF::EM_ARM;
|
return llvm::ELF::EM_ARM;
|
||||||
|
case llvm::Triple::amdgcn:
|
||||||
|
return llvm::ELF::EM_AMDGPU;
|
||||||
default:
|
default:
|
||||||
llvm_unreachable("Unhandled arch");
|
llvm_unreachable("Unhandled arch");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
...
|
||||||
Loading…
Reference in New Issue