[llvm] Partial work on JITLink ARM64-COFF (PR #89697)
Vassil Vassilev via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 24 23:12:46 PDT 2024
================
@@ -0,0 +1,347 @@
+//===----- COFF_arm64.cpp - JIT linker implementation for COFF/arm64 ----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// COFF/arm64 jit-link implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ExecutionEngine/JITLink/COFF_arm64.h"
+#include "COFFLinkGraphBuilder.h"
+#include "SEHFrameSupport.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/ExecutionEngine/JITLink/aarch64.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Support/Endian.h"
+
+#define DEBUG_TYPE "jitlink"
+
+using namespace llvm;
+using namespace llvm::jitlink;
+
+namespace {
+
+enum EdgeKind_coff_arm64 : Edge::Kind {
+ Pointer32 = aarch64::FirstPlatformRelocation,
+ Pointer32NB,
+ Branch26,
+ PageBase_Rel21,
+ Rel21,
+ PageOffset_12L,
+ Secrel,
+ Secrel_Low12A,
+ Secrel_High12A,
+ Secrel_Low12L,
+ Token,
+ Sec,
+ Pointer64,
+ Branch19,
+ Branch14,
+ Rel32
+};
+
+class COFFJITLinker_arm64 : public JITLinker<COFFJITLinker_arm64> {
+ friend class JITLinker<COFFJITLinker_arm64>;
+
+public:
+ COFFJITLinker_arm64(std::unique_ptr<JITLinkContext> Ctx,
+ std::unique_ptr<LinkGraph> G,
+ PassConfiguration PassConfig)
+ : JITLinker(std::move(Ctx), std::move(G), std::move(PassConfig)) {}
+
+private:
+ Error applyFixup(LinkGraph &G, Block &B, const Edge &E) const {
+ return aarch64::applyFixup(G, B, E);
+ }
+};
+
+class COFFLinkGraphBuilder_arm64 : public COFFLinkGraphBuilder {
+private:
+ Error addRelocations() override {
+ LLVM_DEBUG(dbgs() << "Processing relocations:\n");
+
+ for (const auto &RelSect : sections())
+ if (Error Err = COFFLinkGraphBuilder::forEachRelocation(
+ RelSect, this, &COFFLinkGraphBuilder_arm64::addSingleRelocation))
+ return Err;
+
+ return Error::success();
+ }
+
+ Error addSingleRelocation(const object::RelocationRef &Rel,
+ const object::SectionRef &FixupSect,
+ Block &BlockToFix) {
+ const object::coff_relocation *COFFRel = getObject().getCOFFRelocation(Rel);
+ auto SymbolIt = Rel.getSymbol();
+ if (SymbolIt == getObject().symbol_end()) {
+ return make_error<StringError>(
+ formatv("Invalid symbol index in relocation entry. "
+ "index: {0}, section: {1}",
+ COFFRel->SymbolTableIndex, FixupSect.getIndex()),
+ inconvertibleErrorCode());
+ }
+
+ object::COFFSymbolRef COFFSymbol = getObject().getCOFFSymbol(*SymbolIt);
+ COFFSymbolIndex SymIndex = getObject().getSymbolIndex(COFFSymbol);
+
+ Symbol *GraphSymbol = getGraphSymbol(SymIndex);
+ if (!GraphSymbol)
+ return make_error<StringError>(
+ formatv("Could not find symbol at given index, did you add it to "
+ "JITSymbolTable? index: {0}, section: {1}",
+ SymIndex, FixupSect.getIndex()),
+ inconvertibleErrorCode());
+
+ int64_t Addend = 0;
+ orc::ExecutorAddr FixupAddress =
+ orc::ExecutorAddr(FixupSect.getAddress()) + Rel.getOffset();
+ Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress();
+
+ Edge::Kind Kind = Edge::Invalid;
+ const char *FixupPtr = BlockToFix.getContent().data() + Offset;
+
+ switch (Rel.getType()) {
+ case COFF::RelocationTypesARM64::IMAGE_REL_ARM64_ADDR32: {
+ Kind = EdgeKind_coff_arm64::Pointer32;
+ Addend = *reinterpret_cast<const support::little32_t *>(FixupPtr);
+ break;
+ }
+ case COFF::RelocationTypesARM64::IMAGE_REL_ARM64_ADDR32NB: {
+ Kind = EdgeKind_coff_arm64::Pointer32NB;
+ Addend = *reinterpret_cast<const support::little32_t *>(FixupPtr);
+ break;
+ }
+ case COFF::RelocationTypesARM64::IMAGE_REL_ARM64_BRANCH26: {
+ Kind = EdgeKind_coff_arm64::Branch26;
+ Addend = *reinterpret_cast<const support::little32_t *>(FixupPtr) >> 4;
+ break;
+ }
+ case COFF::RelocationTypesARM64::IMAGE_REL_ARM64_PAGEBASE_REL21: {
+ Kind = EdgeKind_coff_arm64::PageBase_Rel21;
+ Addend = *reinterpret_cast<const support::little32_t *>(FixupPtr);
+ break;
+ }
+ case COFF::RelocationTypesARM64::IMAGE_REL_ARM64_REL21: {
+ Kind = EdgeKind_coff_arm64::Rel21;
+ Addend = *reinterpret_cast<const support::little32_t *>(FixupPtr);
+ break;
+ }
+ case COFF::RelocationTypesARM64::IMAGE_REL_ARM64_BRANCH19: {
+ Kind = EdgeKind_coff_arm64::Branch19;
+ Addend = *reinterpret_cast<const support::little32_t *>(FixupPtr) >> 11;
+ break;
+ }
+ case COFF::RelocationTypesARM64::IMAGE_REL_ARM64_BRANCH14: {
+ Kind = EdgeKind_coff_arm64::Branch14;
+ Addend = *reinterpret_cast<const support::little32_t *>(FixupPtr) >> 16;
+ break;
+ }
+ default: {
+ return make_error<JITLinkError>("Unsupported arm64 relocation:" +
+ formatv("{0:d}", Rel.getType()));
+ }
+ }
+
+ Edge GE(Kind, Offset, *GraphSymbol, Addend);
+ LLVM_DEBUG({
+ dbgs() << " ";
+ printEdge(dbgs(), BlockToFix, GE, getCOFFARM64RelocationKindName(Kind));
+ dbgs() << "\n";
+ });
+
+ BlockToFix.addEdge(std::move(GE));
+
+ return Error::success();
+ }
+
+public:
+ COFFLinkGraphBuilder_arm64(const object::COFFObjectFile &Obj, const Triple T,
+ const SubtargetFeatures Features)
+ : COFFLinkGraphBuilder(Obj, std::move(T), std::move(Features),
+ getCOFFARM64RelocationKindName) {}
+};
+
+class COFFLinkGraphLowering_arm64 {
+public:
+ // Lowers COFF arm64 specific edges to generic arm64 edges.
+ Error lowerCOFFRelocationEdges(LinkGraph &G, JITLinkContext &Ctx) {
+ for (auto *B : G.blocks()) {
+ for (auto &E : B->edges()) {
+ switch (E.getKind()) {
+ case EdgeKind_coff_arm64::Pointer32: {
+ E.setKind(aarch64::Pointer32);
+ break;
+ }
+ case EdgeKind_coff_arm64::Pointer32NB: {
+ E.setKind(aarch64::Pointer32);
+ break;
+ }
+ case EdgeKind_coff_arm64::Branch26: {
+ E.setKind(aarch64::Branch26PCRel);
+ break;
+ }
+ case EdgeKind_coff_arm64::PageBase_Rel21: {
+ E.setKind(aarch64::Page21);
+ break;
+ }
+ case EdgeKind_coff_arm64::Rel21: {
+ // TODO
+ break;
+ }
+ case EdgeKind_coff_arm64::PageOffset_12L: {
+ E.setKind(aarch64::PageOffset12);
+ break;
+ }
+ case EdgeKind_coff_arm64::Secrel: {
+ // TODO
----------------
vgvassilev wrote:
Do we want to issue a sensible diagnostic in these cases?
https://github.com/llvm/llvm-project/pull/89697
More information about the llvm-commits
mailing list