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/ELF.h" 14 #include "llvm/ExecutionEngine/JITLink/MachO.h" 15 #include "llvm/Support/Format.h" 16 #include "llvm/Support/ManagedStatic.h" 17 #include "llvm/Support/MemoryBuffer.h" 18 #include "llvm/Support/raw_ostream.h" 19 20 using namespace llvm; 21 using namespace llvm::object; 22 23 #define DEBUG_TYPE "jitlink" 24 25 namespace { 26 27 enum JITLinkErrorCode { GenericJITLinkError = 1 }; 28 29 // FIXME: This class is only here to support the transition to llvm::Error. It 30 // will be removed once this transition is complete. Clients should prefer to 31 // deal with the Error value directly, rather than converting to error_code. 32 class JITLinkerErrorCategory : public std::error_category { 33 public: 34 const char *name() const noexcept override { return "runtimedyld"; } 35 36 std::string message(int Condition) const override { 37 switch (static_cast<JITLinkErrorCode>(Condition)) { 38 case GenericJITLinkError: 39 return "Generic JITLink error"; 40 } 41 llvm_unreachable("Unrecognized JITLinkErrorCode"); 42 } 43 }; 44 45 static ManagedStatic<JITLinkerErrorCategory> JITLinkerErrorCategory; 46 47 } // namespace 48 49 namespace llvm { 50 namespace jitlink { 51 52 char JITLinkError::ID = 0; 53 54 void JITLinkError::log(raw_ostream &OS) const { OS << ErrMsg << "\n"; } 55 56 std::error_code JITLinkError::convertToErrorCode() const { 57 return std::error_code(GenericJITLinkError, *JITLinkerErrorCategory); 58 } 59 60 const char *getGenericEdgeKindName(Edge::Kind K) { 61 switch (K) { 62 case Edge::Invalid: 63 return "INVALID RELOCATION"; 64 case Edge::KeepAlive: 65 return "Keep-Alive"; 66 default: 67 llvm_unreachable("Unrecognized relocation kind"); 68 } 69 } 70 71 const char *getLinkageName(Linkage L) { 72 switch (L) { 73 case Linkage::Strong: 74 return "strong"; 75 case Linkage::Weak: 76 return "weak"; 77 } 78 llvm_unreachable("Unrecognized llvm.jitlink.Linkage enum"); 79 } 80 81 const char *getScopeName(Scope S) { 82 switch (S) { 83 case Scope::Default: 84 return "default"; 85 case Scope::Hidden: 86 return "hidden"; 87 case Scope::Local: 88 return "local"; 89 } 90 llvm_unreachable("Unrecognized llvm.jitlink.Scope enum"); 91 } 92 93 raw_ostream &operator<<(raw_ostream &OS, const Block &B) { 94 return OS << formatv("{0:x16}", B.getAddress()) << " -- " 95 << formatv("{0:x16}", B.getAddress() + B.getSize()) << ": " 96 << (B.isZeroFill() ? "zero-fill" : "content") 97 << ", align = " << B.getAlignment() 98 << ", align-ofs = " << B.getAlignmentOffset() 99 << ", section = " << B.getSection().getName(); 100 } 101 102 raw_ostream &operator<<(raw_ostream &OS, const Symbol &Sym) { 103 OS << "<"; 104 if (Sym.getName().empty()) 105 OS << "*anon*"; 106 else 107 OS << Sym.getName(); 108 OS << ": flags = "; 109 switch (Sym.getLinkage()) { 110 case Linkage::Strong: 111 OS << 'S'; 112 break; 113 case Linkage::Weak: 114 OS << 'W'; 115 break; 116 } 117 switch (Sym.getScope()) { 118 case Scope::Default: 119 OS << 'D'; 120 break; 121 case Scope::Hidden: 122 OS << 'H'; 123 break; 124 case Scope::Local: 125 OS << 'L'; 126 break; 127 } 128 OS << (Sym.isLive() ? '+' : '-') 129 << ", size = " << formatv("{0:x8}", Sym.getSize()) 130 << ", addr = " << formatv("{0:x16}", Sym.getAddress()) << " (" 131 << formatv("{0:x16}", Sym.getAddressable().getAddress()) << " + " 132 << formatv("{0:x8}", Sym.getOffset()); 133 if (Sym.isDefined()) 134 OS << " " << Sym.getBlock().getSection().getName(); 135 OS << ")>"; 136 return OS; 137 } 138 139 void printEdge(raw_ostream &OS, const Block &B, const Edge &E, 140 StringRef EdgeKindName) { 141 OS << "edge@" << formatv("{0:x16}", B.getAddress() + E.getOffset()) << ": " 142 << formatv("{0:x16}", B.getAddress()) << " + " << E.getOffset() << " -- " 143 << EdgeKindName << " -> " << E.getTarget() << " + " << E.getAddend(); 144 } 145 146 Section::~Section() { 147 for (auto *Sym : Symbols) 148 Sym->~Symbol(); 149 for (auto *B : Blocks) 150 B->~Block(); 151 } 152 153 Block &LinkGraph::splitBlock(Block &B, size_t SplitIndex, 154 SplitBlockCache *Cache) { 155 156 assert(SplitIndex > 0 && "splitBlock can not be called with SplitIndex == 0"); 157 158 // If the split point covers all of B then just return B. 159 if (SplitIndex == B.getSize()) 160 return B; 161 162 assert(SplitIndex < B.getSize() && "SplitIndex out of range"); 163 164 // Create the new block covering [ 0, SplitIndex ). 165 auto &NewBlock = 166 B.isZeroFill() 167 ? createZeroFillBlock(B.getSection(), SplitIndex, B.getAddress(), 168 B.getAlignment(), B.getAlignmentOffset()) 169 : createContentBlock( 170 B.getSection(), B.getContent().substr(0, SplitIndex), 171 B.getAddress(), B.getAlignment(), B.getAlignmentOffset()); 172 173 // Modify B to cover [ SplitIndex, B.size() ). 174 B.setAddress(B.getAddress() + SplitIndex); 175 B.setContent(B.getContent().substr(SplitIndex)); 176 B.setAlignmentOffset((B.getAlignmentOffset() + SplitIndex) % 177 B.getAlignment()); 178 179 // Handle edge transfer/update. 180 { 181 // Copy edges to NewBlock (recording their iterators so that we can remove 182 // them from B), and update of Edges remaining on B. 183 std::vector<Block::edge_iterator> EdgesToRemove; 184 for (auto I = B.edges().begin(); I != B.edges().end();) { 185 if (I->getOffset() < SplitIndex) { 186 NewBlock.addEdge(*I); 187 I = B.removeEdge(I); 188 } else { 189 I->setOffset(I->getOffset() - SplitIndex); 190 ++I; 191 } 192 } 193 } 194 195 // Handle symbol transfer/update. 196 { 197 // Initialize the symbols cache if necessary. 198 SplitBlockCache LocalBlockSymbolsCache; 199 if (!Cache) 200 Cache = &LocalBlockSymbolsCache; 201 if (*Cache == None) { 202 *Cache = SplitBlockCache::value_type(); 203 for (auto *Sym : B.getSection().symbols()) 204 if (&Sym->getBlock() == &B) 205 (*Cache)->push_back(Sym); 206 207 llvm::sort(**Cache, [](const Symbol *LHS, const Symbol *RHS) { 208 return LHS->getOffset() > RHS->getOffset(); 209 }); 210 } 211 auto &BlockSymbols = **Cache; 212 213 // Transfer all symbols with offset less than SplitIndex to NewBlock. 214 while (!BlockSymbols.empty() && 215 BlockSymbols.back()->getOffset() < SplitIndex) { 216 BlockSymbols.back()->setBlock(NewBlock); 217 BlockSymbols.pop_back(); 218 } 219 220 // Update offsets for all remaining symbols in B. 221 for (auto *Sym : BlockSymbols) 222 Sym->setOffset(Sym->getOffset() - SplitIndex); 223 } 224 225 return NewBlock; 226 } 227 228 void LinkGraph::dump(raw_ostream &OS, 229 std::function<StringRef(Edge::Kind)> EdgeKindToName) { 230 if (!EdgeKindToName) 231 EdgeKindToName = [](Edge::Kind K) { return StringRef(); }; 232 233 OS << "Symbols:\n"; 234 for (auto *Sym : defined_symbols()) { 235 OS << " " << format("0x%016" PRIx64, Sym->getAddress()) << ": " << *Sym 236 << "\n"; 237 if (Sym->isDefined()) { 238 for (auto &E : Sym->getBlock().edges()) { 239 OS << " "; 240 StringRef EdgeName = (E.getKind() < Edge::FirstRelocation 241 ? getGenericEdgeKindName(E.getKind()) 242 : EdgeKindToName(E.getKind())); 243 244 if (!EdgeName.empty()) 245 printEdge(OS, Sym->getBlock(), E, EdgeName); 246 else { 247 auto EdgeNumberString = std::to_string(E.getKind()); 248 printEdge(OS, Sym->getBlock(), E, EdgeNumberString); 249 } 250 OS << "\n"; 251 } 252 } 253 } 254 255 OS << "Absolute symbols:\n"; 256 for (auto *Sym : absolute_symbols()) 257 OS << " " << format("0x%016" PRIx64, Sym->getAddress()) << ": " << *Sym 258 << "\n"; 259 260 OS << "External symbols:\n"; 261 for (auto *Sym : external_symbols()) 262 OS << " " << format("0x%016" PRIx64, Sym->getAddress()) << ": " << *Sym 263 << "\n"; 264 } 265 266 raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LF) { 267 switch (LF) { 268 case SymbolLookupFlags::RequiredSymbol: 269 return OS << "RequiredSymbol"; 270 case SymbolLookupFlags::WeaklyReferencedSymbol: 271 return OS << "WeaklyReferencedSymbol"; 272 } 273 llvm_unreachable("Unrecognized lookup flags"); 274 } 275 276 void JITLinkAsyncLookupContinuation::anchor() {} 277 278 JITLinkContext::~JITLinkContext() {} 279 280 bool JITLinkContext::shouldAddDefaultTargetPasses(const Triple &TT) const { 281 return true; 282 } 283 284 LinkGraphPassFunction JITLinkContext::getMarkLivePass(const Triple &TT) const { 285 return LinkGraphPassFunction(); 286 } 287 288 Error JITLinkContext::modifyPassConfig(const Triple &TT, 289 PassConfiguration &Config) { 290 return Error::success(); 291 } 292 293 Error markAllSymbolsLive(LinkGraph &G) { 294 for (auto *Sym : G.defined_symbols()) 295 Sym->setLive(true); 296 return Error::success(); 297 } 298 299 void jitLink(std::unique_ptr<JITLinkContext> Ctx) { 300 auto Magic = identify_magic(Ctx->getObjectBuffer().getBuffer()); 301 switch (Magic) { 302 case file_magic::macho_object: 303 return jitLink_MachO(std::move(Ctx)); 304 case file_magic::elf_relocatable: 305 return jitLink_ELF(std::move(Ctx)); 306 default: 307 Ctx->notifyFailed(make_error<JITLinkError>("Unsupported file format")); 308 }; 309 } 310 311 } // end namespace jitlink 312 } // end namespace llvm 313