//===------- XCOFF_ppc64.cpp -JIT linker implementation for XCOFF/ppc64 //-------===// // // 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 // //===----------------------------------------------------------------------===// // // XCOFF/ppc64 jit-link implementation. // //===----------------------------------------------------------------------===// #include "llvm/ExecutionEngine/JITLink/XCOFF_ppc64.h" #include "JITLinkGeneric.h" #include "XCOFFLinkGraphBuilder.h" #include "llvm/ADT/bit.h" #include "llvm/ExecutionEngine/JITLink/JITLink.h" #include "llvm/ExecutionEngine/JITLink/ppc64.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Object/XCOFFObjectFile.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include using namespace llvm; #define DEBUG_TYPE "jitlink" namespace llvm { namespace jitlink { Expected> createLinkGraphFromXCOFFObject_ppc64( MemoryBufferRef ObjectBuffer, std::shared_ptr SSP) { LLVM_DEBUG({ dbgs() << "Building jitlink graph for new input " << ObjectBuffer.getBufferIdentifier() << "...\n"; }); auto Obj = object::ObjectFile::createObjectFile(ObjectBuffer); if (!Obj) return Obj.takeError(); assert((**Obj).isXCOFF() && "Expects and XCOFF Object"); auto Features = (*Obj)->getFeatures(); if (!Features) return Features.takeError(); LLVM_DEBUG({ dbgs() << " Features: "; (*Features).print(dbgs()); }); return XCOFFLinkGraphBuilder(cast(**Obj), std::move(SSP), Triple("powerpc64-ibm-aix"), std::move(*Features), ppc64::getEdgeKindName) .buildGraph(); } class XCOFFJITLinker_ppc64 : public JITLinker { using JITLinkerBase = JITLinker; friend JITLinkerBase; public: XCOFFJITLinker_ppc64(std::unique_ptr Ctx, std::unique_ptr G, PassConfiguration PassConfig) : JITLinkerBase(std::move(Ctx), std::move(G), std::move(PassConfig)) { // FIXME: Post allocation pass define TOC base, this is temporary to support // building until we can build the required toc entries defineTOCSymbol(getGraph()); } Error applyFixup(LinkGraph &G, Block &B, const Edge &E) const { LLVM_DEBUG(dbgs() << " Applying fixup for " << G.getName() << ", address = " << B.getAddress() << ", target = " << E.getTarget().getName() << ", kind = " << ppc64::getEdgeKindName(E.getKind()) << "\n"); switch (E.getKind()) { case ppc64::Pointer64: if (auto Err = ppc64::applyFixup(G, B, E, TOCSymbol)) return Err; break; default: return make_error("Unsupported relocation type", std::error_code()); } return Error::success(); } private: void defineTOCSymbol(LinkGraph &G) { for (Symbol *S : G.defined_symbols()) { if (S->hasName() && *S->getName() == StringRef("TOC")) { TOCSymbol = S; return; } } llvm_unreachable("LinkGraph does not contan an TOC Symbol"); } private: Symbol *TOCSymbol = nullptr; }; void link_XCOFF_ppc64(std::unique_ptr G, std::unique_ptr Ctx) { // Ctx->notifyFailed(make_error( // "link_XCOFF_ppc64 is not implemented", std::error_code())); PassConfiguration Config; // Pass insertions if (auto Err = Ctx->modifyPassConfig(*G, Config)) return Ctx->notifyFailed(std::move(Err)); XCOFFJITLinker_ppc64::link(std::move(Ctx), std::move(G), std::move(Config)); } } // namespace jitlink } // namespace llvm