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(Object: 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>(Val&: **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(G&: 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>(Args: "Unsupported relocation type" , |
85 | Args: 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&: *G, Config)) |
115 | return Ctx->notifyFailed(Err: std::move(Err)); |
116 | |
117 | XCOFFJITLinker_ppc64::link(Args: std::move(Ctx), Args: std::move(G), Args: std::move(Config)); |
118 | } |
119 | |
120 | } // namespace jitlink |
121 | } // namespace llvm |
122 | |