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(), E = B.edges().end(); I != E; ++I) { 184 if (I->getOffset() < SplitIndex) { 185 NewBlock.addEdge(*I); 186 EdgesToRemove.push_back(I); 187 } else 188 I->setOffset(I->getOffset() - SplitIndex); 189 } 190 191 // Remove edges that were transfered to NewBlock from B. 192 while (!EdgesToRemove.empty()) { 193 B.removeEdge(EdgesToRemove.back()); 194 EdgesToRemove.pop_back(); 195 } 196 } 197 198 // Handle symbol transfer/update. 199 { 200 // Initialize the symbols cache if necessary. 201 SplitBlockCache LocalBlockSymbolsCache; 202 if (!Cache) 203 Cache = &LocalBlockSymbolsCache; 204 if (*Cache == None) { 205 *Cache = SplitBlockCache::value_type(); 206 for (auto *Sym : B.getSection().symbols()) 207 if (&Sym->getBlock() == &B) 208 (*Cache)->push_back(Sym); 209 210 llvm::sort(**Cache, [](const Symbol *LHS, const Symbol *RHS) { 211 return LHS->getOffset() > RHS->getOffset(); 212 }); 213 } 214 auto &BlockSymbols = **Cache; 215 216 // Transfer all symbols with offset less than SplitIndex to NewBlock. 217 while (!BlockSymbols.empty() && 218 BlockSymbols.back()->getOffset() < SplitIndex) { 219 BlockSymbols.back()->setBlock(NewBlock); 220 BlockSymbols.pop_back(); 221 } 222 223 // Update offsets for all remaining symbols in B. 224 for (auto *Sym : BlockSymbols) 225 Sym->setOffset(Sym->getOffset() - SplitIndex); 226 } 227 228 return NewBlock; 229 } 230 231 void LinkGraph::dump(raw_ostream &OS, 232 std::function<StringRef(Edge::Kind)> EdgeKindToName) { 233 if (!EdgeKindToName) 234 EdgeKindToName = [](Edge::Kind K) { return StringRef(); }; 235 236 OS << "Symbols:\n"; 237 for (auto *Sym : defined_symbols()) { 238 OS << " " << format("0x%016" PRIx64, Sym->getAddress()) << ": " << *Sym 239 << "\n"; 240 if (Sym->isDefined()) { 241 for (auto &E : Sym->getBlock().edges()) { 242 OS << " "; 243 StringRef EdgeName = (E.getKind() < Edge::FirstRelocation 244 ? getGenericEdgeKindName(E.getKind()) 245 : EdgeKindToName(E.getKind())); 246 247 if (!EdgeName.empty()) 248 printEdge(OS, Sym->getBlock(), E, EdgeName); 249 else { 250 auto EdgeNumberString = std::to_string(E.getKind()); 251 printEdge(OS, Sym->getBlock(), E, EdgeNumberString); 252 } 253 OS << "\n"; 254 } 255 } 256 } 257 258 OS << "Absolute symbols:\n"; 259 for (auto *Sym : absolute_symbols()) 260 OS << " " << format("0x%016" PRIx64, Sym->getAddress()) << ": " << *Sym 261 << "\n"; 262 263 OS << "External symbols:\n"; 264 for (auto *Sym : external_symbols()) 265 OS << " " << format("0x%016" PRIx64, Sym->getAddress()) << ": " << *Sym 266 << "\n"; 267 } 268 269 raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LF) { 270 switch (LF) { 271 case SymbolLookupFlags::RequiredSymbol: 272 return OS << "RequiredSymbol"; 273 case SymbolLookupFlags::WeaklyReferencedSymbol: 274 return OS << "WeaklyReferencedSymbol"; 275 } 276 llvm_unreachable("Unrecognized lookup flags"); 277 } 278 279 void JITLinkAsyncLookupContinuation::anchor() {} 280 281 JITLinkContext::~JITLinkContext() {} 282 283 bool JITLinkContext::shouldAddDefaultTargetPasses(const Triple &TT) const { 284 return true; 285 } 286 287 LinkGraphPassFunction JITLinkContext::getMarkLivePass(const Triple &TT) const { 288 return LinkGraphPassFunction(); 289 } 290 291 Error JITLinkContext::modifyPassConfig(const Triple &TT, 292 PassConfiguration &Config) { 293 return Error::success(); 294 } 295 296 Error markAllSymbolsLive(LinkGraph &G) { 297 for (auto *Sym : G.defined_symbols()) 298 Sym->setLive(true); 299 return Error::success(); 300 } 301 302 void jitLink(std::unique_ptr<JITLinkContext> Ctx) { 303 auto Magic = identify_magic(Ctx->getObjectBuffer().getBuffer()); 304 switch (Magic) { 305 case file_magic::macho_object: 306 return jitLink_MachO(std::move(Ctx)); 307 default: 308 Ctx->notifyFailed(make_error<JITLinkError>("Unsupported file format")); 309 }; 310 } 311 312 } // end namespace jitlink 313 } // end namespace llvm 314