1 //===------------- JITLink.cpp - Core Run-time JIT linker APIs ------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/ExecutionEngine/JITLink/JITLink.h" 11 12 #include "llvm/BinaryFormat/Magic.h" 13 #include "llvm/ExecutionEngine/JITLink/MachO.h" 14 #include "llvm/Support/Format.h" 15 #include "llvm/Support/ManagedStatic.h" 16 #include "llvm/Support/MemoryBuffer.h" 17 #include "llvm/Support/raw_ostream.h" 18 19 using namespace llvm; 20 using namespace llvm::object; 21 22 #define DEBUG_TYPE "jitlink" 23 24 namespace { 25 26 enum JITLinkErrorCode { GenericJITLinkError = 1 }; 27 28 // FIXME: This class is only here to support the transition to llvm::Error. It 29 // will be removed once this transition is complete. Clients should prefer to 30 // deal with the Error value directly, rather than converting to error_code. 31 class JITLinkerErrorCategory : public std::error_category { 32 public: 33 const char *name() const noexcept override { return "runtimedyld"; } 34 35 std::string message(int Condition) const override { 36 switch (static_cast<JITLinkErrorCode>(Condition)) { 37 case GenericJITLinkError: 38 return "Generic JITLink error"; 39 } 40 llvm_unreachable("Unrecognized JITLinkErrorCode"); 41 } 42 }; 43 44 static ManagedStatic<JITLinkerErrorCategory> JITLinkerErrorCategory; 45 46 } // namespace 47 48 namespace llvm { 49 namespace jitlink { 50 51 char JITLinkError::ID = 0; 52 53 void JITLinkError::log(raw_ostream &OS) const { OS << ErrMsg << "\n"; } 54 55 std::error_code JITLinkError::convertToErrorCode() const { 56 return std::error_code(GenericJITLinkError, *JITLinkerErrorCategory); 57 } 58 59 const char *getGenericEdgeKindName(Edge::Kind K) { 60 switch (K) { 61 case Edge::Invalid: 62 return "INVALID RELOCATION"; 63 case Edge::KeepAlive: 64 return "Keep-Alive"; 65 default: 66 llvm_unreachable("Unrecognized relocation kind"); 67 } 68 } 69 70 const char *getLinkageName(Linkage L) { 71 switch (L) { 72 case Linkage::Strong: 73 return "strong"; 74 case Linkage::Weak: 75 return "weak"; 76 } 77 llvm_unreachable("Unrecognized llvm.jitlink.Linkage enum"); 78 } 79 80 const char *getScopeName(Scope S) { 81 switch (S) { 82 case Scope::Default: 83 return "default"; 84 case Scope::Hidden: 85 return "hidden"; 86 case Scope::Local: 87 return "local"; 88 } 89 llvm_unreachable("Unrecognized llvm.jitlink.Scope enum"); 90 } 91 92 raw_ostream &operator<<(raw_ostream &OS, const Block &B) { 93 return OS << formatv("{0:x16}", B.getAddress()) << " -- " 94 << formatv("{0:x16}", B.getAddress() + B.getSize()) << ": " 95 << (B.isZeroFill() ? "zero-fill" : "content") 96 << ", align = " << B.getAlignment() 97 << ", align-ofs = " << B.getAlignmentOffset() 98 << ", section = " << B.getSection().getName(); 99 } 100 101 raw_ostream &operator<<(raw_ostream &OS, const Symbol &Sym) { 102 OS << "<"; 103 if (Sym.getName().empty()) 104 OS << "*anon*"; 105 else 106 OS << Sym.getName(); 107 OS << ": flags = "; 108 switch (Sym.getLinkage()) { 109 case Linkage::Strong: 110 OS << 'S'; 111 break; 112 case Linkage::Weak: 113 OS << 'W'; 114 break; 115 } 116 switch (Sym.getScope()) { 117 case Scope::Default: 118 OS << 'D'; 119 break; 120 case Scope::Hidden: 121 OS << 'H'; 122 break; 123 case Scope::Local: 124 OS << 'L'; 125 break; 126 } 127 OS << (Sym.isLive() ? '+' : '-') 128 << ", size = " << formatv("{0:x8}", Sym.getSize()) 129 << ", addr = " << formatv("{0:x16}", Sym.getAddress()) << " (" 130 << formatv("{0:x16}", Sym.getAddressable().getAddress()) << " + " 131 << formatv("{0:x8}", Sym.getOffset()); 132 if (Sym.isDefined()) 133 OS << " " << Sym.getBlock().getSection().getName(); 134 OS << ")>"; 135 return OS; 136 } 137 138 void printEdge(raw_ostream &OS, const Block &B, const Edge &E, 139 StringRef EdgeKindName) { 140 OS << "edge@" << formatv("{0:x16}", B.getAddress() + E.getOffset()) << ": " 141 << formatv("{0:x16}", B.getAddress()) << " + " << E.getOffset() << " -- " 142 << EdgeKindName << " -> " << E.getTarget() << " + " << E.getAddend(); 143 } 144 145 Section::~Section() { 146 for (auto *Sym : Symbols) 147 Sym->~Symbol(); 148 } 149 150 LinkGraph::~LinkGraph() { 151 // Destroy blocks. 152 for (auto *B : Blocks) 153 B->~Block(); 154 } 155 156 void LinkGraph::dump(raw_ostream &OS, 157 std::function<StringRef(Edge::Kind)> EdgeKindToName) { 158 if (!EdgeKindToName) 159 EdgeKindToName = [](Edge::Kind K) { return StringRef(); }; 160 161 OS << "Symbols:\n"; 162 for (auto *Sym : defined_symbols()) { 163 OS << " " << format("0x%016" PRIx64, Sym->getAddress()) << ": " << *Sym 164 << "\n"; 165 if (Sym->isDefined()) { 166 for (auto &E : Sym->getBlock().edges()) { 167 OS << " "; 168 StringRef EdgeName = (E.getKind() < Edge::FirstRelocation 169 ? getGenericEdgeKindName(E.getKind()) 170 : EdgeKindToName(E.getKind())); 171 172 if (!EdgeName.empty()) 173 printEdge(OS, Sym->getBlock(), E, EdgeName); 174 else { 175 auto EdgeNumberString = std::to_string(E.getKind()); 176 printEdge(OS, Sym->getBlock(), E, EdgeNumberString); 177 } 178 OS << "\n"; 179 } 180 } 181 } 182 183 OS << "Absolute symbols:\n"; 184 for (auto *Sym : absolute_symbols()) 185 OS << " " << format("0x%016" PRIx64, Sym->getAddress()) << ": " << *Sym 186 << "\n"; 187 188 OS << "External symbols:\n"; 189 for (auto *Sym : external_symbols()) 190 OS << " " << format("0x%016" PRIx64, Sym->getAddress()) << ": " << *Sym 191 << "\n"; 192 } 193 194 void JITLinkAsyncLookupContinuation::anchor() {} 195 196 JITLinkContext::~JITLinkContext() {} 197 198 bool JITLinkContext::shouldAddDefaultTargetPasses(const Triple &TT) const { 199 return true; 200 } 201 202 LinkGraphPassFunction JITLinkContext::getMarkLivePass(const Triple &TT) const { 203 return LinkGraphPassFunction(); 204 } 205 206 Error JITLinkContext::modifyPassConfig(const Triple &TT, 207 PassConfiguration &Config) { 208 return Error::success(); 209 } 210 211 Error markAllSymbolsLive(LinkGraph &G) { 212 for (auto *Sym : G.defined_symbols()) 213 Sym->setLive(true); 214 return Error::success(); 215 } 216 217 void jitLink(std::unique_ptr<JITLinkContext> Ctx) { 218 auto Magic = identify_magic(Ctx->getObjectBuffer().getBuffer()); 219 switch (Magic) { 220 case file_magic::macho_object: 221 return jitLink_MachO(std::move(Ctx)); 222 default: 223 Ctx->notifyFailed(make_error<JITLinkError>("Unsupported file format")); 224 }; 225 } 226 227 } // end namespace jitlink 228 } // end namespace llvm 229