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 for (auto *B : Blocks) 149 B->~Block(); 150 } 151 152 Block &LinkGraph::splitBlock(Block &B, size_t SplitIndex, 153 SplitBlockCache *Cache) { 154 155 assert(SplitIndex > 0 && "splitBlock can not be called with SplitIndex == 0"); 156 157 // If the split point covers all of B then just return B. 158 if (SplitIndex == B.getSize()) 159 return B; 160 161 assert(SplitIndex < B.getSize() && "SplitIndex out of range"); 162 163 // Create the new block covering [ 0, SplitIndex ). 164 auto &NewBlock = 165 B.isZeroFill() 166 ? createZeroFillBlock(B.getSection(), SplitIndex, B.getAddress(), 167 B.getAlignment(), B.getAlignmentOffset()) 168 : createContentBlock( 169 B.getSection(), B.getContent().substr(0, SplitIndex), 170 B.getAddress(), B.getAlignment(), B.getAlignmentOffset()); 171 172 // Modify B to cover [ SplitIndex, B.size() ). 173 B.setAddress(B.getAddress() + SplitIndex); 174 B.setContent(B.getContent().substr(SplitIndex)); 175 B.setAlignmentOffset((B.getAlignmentOffset() + SplitIndex) % 176 B.getAlignment()); 177 178 // Handle edge transfer/update. 179 { 180 // Copy edges to NewBlock (recording their iterators so that we can remove 181 // them from B), and update of Edges remaining on B. 182 std::vector<Block::edge_iterator> EdgesToRemove; 183 for (auto I = B.edges().begin(); I != B.edges().end();) { 184 if (I->getOffset() < SplitIndex) { 185 NewBlock.addEdge(*I); 186 I = B.removeEdge(I); 187 } else { 188 I->setOffset(I->getOffset() - SplitIndex); 189 ++I; 190 } 191 } 192 } 193 194 // Handle symbol transfer/update. 195 { 196 // Initialize the symbols cache if necessary. 197 SplitBlockCache LocalBlockSymbolsCache; 198 if (!Cache) 199 Cache = &LocalBlockSymbolsCache; 200 if (*Cache == None) { 201 *Cache = SplitBlockCache::value_type(); 202 for (auto *Sym : B.getSection().symbols()) 203 if (&Sym->getBlock() == &B) 204 (*Cache)->push_back(Sym); 205 206 llvm::sort(**Cache, [](const Symbol *LHS, const Symbol *RHS) { 207 return LHS->getOffset() > RHS->getOffset(); 208 }); 209 } 210 auto &BlockSymbols = **Cache; 211 212 // Transfer all symbols with offset less than SplitIndex to NewBlock. 213 while (!BlockSymbols.empty() && 214 BlockSymbols.back()->getOffset() < SplitIndex) { 215 BlockSymbols.back()->setBlock(NewBlock); 216 BlockSymbols.pop_back(); 217 } 218 219 // Update offsets for all remaining symbols in B. 220 for (auto *Sym : BlockSymbols) 221 Sym->setOffset(Sym->getOffset() - SplitIndex); 222 } 223 224 return NewBlock; 225 } 226 227 void LinkGraph::dump(raw_ostream &OS, 228 std::function<StringRef(Edge::Kind)> EdgeKindToName) { 229 if (!EdgeKindToName) 230 EdgeKindToName = [](Edge::Kind K) { return StringRef(); }; 231 232 OS << "Symbols:\n"; 233 for (auto *Sym : defined_symbols()) { 234 OS << " " << format("0x%016" PRIx64, Sym->getAddress()) << ": " << *Sym 235 << "\n"; 236 if (Sym->isDefined()) { 237 for (auto &E : Sym->getBlock().edges()) { 238 OS << " "; 239 StringRef EdgeName = (E.getKind() < Edge::FirstRelocation 240 ? getGenericEdgeKindName(E.getKind()) 241 : EdgeKindToName(E.getKind())); 242 243 if (!EdgeName.empty()) 244 printEdge(OS, Sym->getBlock(), E, EdgeName); 245 else { 246 auto EdgeNumberString = std::to_string(E.getKind()); 247 printEdge(OS, Sym->getBlock(), E, EdgeNumberString); 248 } 249 OS << "\n"; 250 } 251 } 252 } 253 254 OS << "Absolute symbols:\n"; 255 for (auto *Sym : absolute_symbols()) 256 OS << " " << format("0x%016" PRIx64, Sym->getAddress()) << ": " << *Sym 257 << "\n"; 258 259 OS << "External symbols:\n"; 260 for (auto *Sym : external_symbols()) 261 OS << " " << format("0x%016" PRIx64, Sym->getAddress()) << ": " << *Sym 262 << "\n"; 263 } 264 265 raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LF) { 266 switch (LF) { 267 case SymbolLookupFlags::RequiredSymbol: 268 return OS << "RequiredSymbol"; 269 case SymbolLookupFlags::WeaklyReferencedSymbol: 270 return OS << "WeaklyReferencedSymbol"; 271 } 272 llvm_unreachable("Unrecognized lookup flags"); 273 } 274 275 void JITLinkAsyncLookupContinuation::anchor() {} 276 277 JITLinkContext::~JITLinkContext() {} 278 279 bool JITLinkContext::shouldAddDefaultTargetPasses(const Triple &TT) const { 280 return true; 281 } 282 283 LinkGraphPassFunction JITLinkContext::getMarkLivePass(const Triple &TT) const { 284 return LinkGraphPassFunction(); 285 } 286 287 Error JITLinkContext::modifyPassConfig(const Triple &TT, 288 PassConfiguration &Config) { 289 return Error::success(); 290 } 291 292 Error markAllSymbolsLive(LinkGraph &G) { 293 for (auto *Sym : G.defined_symbols()) 294 Sym->setLive(true); 295 return Error::success(); 296 } 297 298 void jitLink(std::unique_ptr<JITLinkContext> Ctx) { 299 auto Magic = identify_magic(Ctx->getObjectBuffer().getBuffer()); 300 switch (Magic) { 301 case file_magic::macho_object: 302 return jitLink_MachO(std::move(Ctx)); 303 default: 304 Ctx->notifyFailed(make_error<JITLinkError>("Unsupported file format")); 305 }; 306 } 307 308 } // end namespace jitlink 309 } // end namespace llvm 310