1 //===------- XCOFF_ppc64.cpp -JIT linker implementation for XCOFF/ppc64 2 //-------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // XCOFF/ppc64 jit-link implementation. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/ExecutionEngine/JITLink/XCOFF_ppc64.h" 15 #include "JITLinkGeneric.h" 16 #include "XCOFFLinkGraphBuilder.h" 17 #include "llvm/ADT/bit.h" 18 #include "llvm/ExecutionEngine/JITLink/JITLink.h" 19 #include "llvm/ExecutionEngine/JITLink/ppc64.h" 20 #include "llvm/Object/ObjectFile.h" 21 #include "llvm/Object/XCOFFObjectFile.h" 22 #include "llvm/Support/Error.h" 23 #include "llvm/Support/ErrorHandling.h" 24 #include <system_error> 25 26 using namespace llvm; 27 28 #define DEBUG_TYPE "jitlink" 29 30 namespace llvm { 31 namespace jitlink { 32 33 Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromXCOFFObject_ppc64( 34 MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP) { 35 LLVM_DEBUG({ 36 dbgs() << "Building jitlink graph for new input " 37 << ObjectBuffer.getBufferIdentifier() << "...\n"; 38 }); 39 40 auto Obj = object::ObjectFile::createObjectFile(ObjectBuffer); 41 if (!Obj) 42 return Obj.takeError(); 43 assert((**Obj).isXCOFF() && "Expects and XCOFF Object"); 44 45 auto Features = (*Obj)->getFeatures(); 46 if (!Features) 47 return Features.takeError(); 48 LLVM_DEBUG({ 49 dbgs() << " Features: "; 50 (*Features).print(dbgs()); 51 }); 52 53 return XCOFFLinkGraphBuilder(cast<object::XCOFFObjectFile>(**Obj), 54 std::move(SSP), Triple("powerpc64-ibm-aix"), 55 std::move(*Features), ppc64::getEdgeKindName) 56 .buildGraph(); 57 } 58 59 class XCOFFJITLinker_ppc64 : public JITLinker<XCOFFJITLinker_ppc64> { 60 using JITLinkerBase = JITLinker<XCOFFJITLinker_ppc64>; 61 friend JITLinkerBase; 62 63 public: 64 XCOFFJITLinker_ppc64(std::unique_ptr<JITLinkContext> Ctx, 65 std::unique_ptr<LinkGraph> G, 66 PassConfiguration PassConfig) 67 : JITLinkerBase(std::move(Ctx), std::move(G), std::move(PassConfig)) { 68 // FIXME: Post allocation pass define TOC base, this is temporary to support 69 // building until we can build the required toc entries 70 defineTOCSymbol(getGraph()); 71 } 72 73 Error applyFixup(LinkGraph &G, Block &B, const Edge &E) const { 74 LLVM_DEBUG(dbgs() << " Applying fixup for " << G.getName() 75 << ", address = " << B.getAddress() 76 << ", target = " << E.getTarget().getName() << ", kind = " 77 << ppc64::getEdgeKindName(E.getKind()) << "\n"); 78 switch (E.getKind()) { 79 case ppc64::Pointer64: 80 if (auto Err = ppc64::applyFixup<endianness::big>(G, B, E, TOCSymbol)) 81 return Err; 82 break; 83 default: 84 return make_error<StringError>("Unsupported relocation type", 85 std::error_code()); 86 } 87 return Error::success(); 88 } 89 90 private: 91 void defineTOCSymbol(LinkGraph &G) { 92 for (Symbol *S : G.defined_symbols()) { 93 if (S->hasName() && *S->getName() == StringRef("TOC")) { 94 TOCSymbol = S; 95 return; 96 } 97 } 98 llvm_unreachable("LinkGraph does not contan an TOC Symbol"); 99 } 100 101 private: 102 Symbol *TOCSymbol = nullptr; 103 }; 104 105 void link_XCOFF_ppc64(std::unique_ptr<LinkGraph> G, 106 std::unique_ptr<JITLinkContext> Ctx) { 107 // Ctx->notifyFailed(make_error<StringError>( 108 // "link_XCOFF_ppc64 is not implemented", std::error_code())); 109 110 PassConfiguration Config; 111 112 // Pass insertions 113 114 if (auto Err = Ctx->modifyPassConfig(*G, Config)) 115 return Ctx->notifyFailed(std::move(Err)); 116 117 XCOFFJITLinker_ppc64::link(std::move(Ctx), std::move(G), std::move(Config)); 118 } 119 120 } // namespace jitlink 121 } // namespace llvm 122