10b57cec5SDimitry Andric //===------------- JITLink.cpp - Core Run-time JIT linker APIs ------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // The LLVM Compiler Infrastructure 40b57cec5SDimitry Andric // 50b57cec5SDimitry Andric // This file is distributed under the University of Illinois Open Source 60b57cec5SDimitry Andric // License. See LICENSE.TXT for details. 70b57cec5SDimitry Andric // 80b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 90b57cec5SDimitry Andric 100b57cec5SDimitry Andric #include "llvm/ExecutionEngine/JITLink/JITLink.h" 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "llvm/BinaryFormat/Magic.h" 13*5ffd83dbSDimitry Andric #include "llvm/ExecutionEngine/JITLink/ELF.h" 140b57cec5SDimitry Andric #include "llvm/ExecutionEngine/JITLink/MachO.h" 150b57cec5SDimitry Andric #include "llvm/Support/Format.h" 160b57cec5SDimitry Andric #include "llvm/Support/ManagedStatic.h" 170b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 180b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric using namespace llvm; 210b57cec5SDimitry Andric using namespace llvm::object; 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric #define DEBUG_TYPE "jitlink" 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric namespace { 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric enum JITLinkErrorCode { GenericJITLinkError = 1 }; 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric // FIXME: This class is only here to support the transition to llvm::Error. It 300b57cec5SDimitry Andric // will be removed once this transition is complete. Clients should prefer to 310b57cec5SDimitry Andric // deal with the Error value directly, rather than converting to error_code. 320b57cec5SDimitry Andric class JITLinkerErrorCategory : public std::error_category { 330b57cec5SDimitry Andric public: 340b57cec5SDimitry Andric const char *name() const noexcept override { return "runtimedyld"; } 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric std::string message(int Condition) const override { 370b57cec5SDimitry Andric switch (static_cast<JITLinkErrorCode>(Condition)) { 380b57cec5SDimitry Andric case GenericJITLinkError: 390b57cec5SDimitry Andric return "Generic JITLink error"; 400b57cec5SDimitry Andric } 410b57cec5SDimitry Andric llvm_unreachable("Unrecognized JITLinkErrorCode"); 420b57cec5SDimitry Andric } 430b57cec5SDimitry Andric }; 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric static ManagedStatic<JITLinkerErrorCategory> JITLinkerErrorCategory; 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric } // namespace 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric namespace llvm { 500b57cec5SDimitry Andric namespace jitlink { 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric char JITLinkError::ID = 0; 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric void JITLinkError::log(raw_ostream &OS) const { OS << ErrMsg << "\n"; } 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric std::error_code JITLinkError::convertToErrorCode() const { 570b57cec5SDimitry Andric return std::error_code(GenericJITLinkError, *JITLinkerErrorCategory); 580b57cec5SDimitry Andric } 590b57cec5SDimitry Andric 608bcb0991SDimitry Andric const char *getGenericEdgeKindName(Edge::Kind K) { 610b57cec5SDimitry Andric switch (K) { 620b57cec5SDimitry Andric case Edge::Invalid: 630b57cec5SDimitry Andric return "INVALID RELOCATION"; 640b57cec5SDimitry Andric case Edge::KeepAlive: 650b57cec5SDimitry Andric return "Keep-Alive"; 660b57cec5SDimitry Andric default: 670b57cec5SDimitry Andric llvm_unreachable("Unrecognized relocation kind"); 680b57cec5SDimitry Andric } 690b57cec5SDimitry Andric } 700b57cec5SDimitry Andric 718bcb0991SDimitry Andric const char *getLinkageName(Linkage L) { 728bcb0991SDimitry Andric switch (L) { 738bcb0991SDimitry Andric case Linkage::Strong: 748bcb0991SDimitry Andric return "strong"; 758bcb0991SDimitry Andric case Linkage::Weak: 768bcb0991SDimitry Andric return "weak"; 778bcb0991SDimitry Andric } 788bcb0991SDimitry Andric llvm_unreachable("Unrecognized llvm.jitlink.Linkage enum"); 798bcb0991SDimitry Andric } 808bcb0991SDimitry Andric 818bcb0991SDimitry Andric const char *getScopeName(Scope S) { 828bcb0991SDimitry Andric switch (S) { 838bcb0991SDimitry Andric case Scope::Default: 848bcb0991SDimitry Andric return "default"; 858bcb0991SDimitry Andric case Scope::Hidden: 868bcb0991SDimitry Andric return "hidden"; 878bcb0991SDimitry Andric case Scope::Local: 888bcb0991SDimitry Andric return "local"; 898bcb0991SDimitry Andric } 908bcb0991SDimitry Andric llvm_unreachable("Unrecognized llvm.jitlink.Scope enum"); 918bcb0991SDimitry Andric } 928bcb0991SDimitry Andric 938bcb0991SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const Block &B) { 948bcb0991SDimitry Andric return OS << formatv("{0:x16}", B.getAddress()) << " -- " 958bcb0991SDimitry Andric << formatv("{0:x16}", B.getAddress() + B.getSize()) << ": " 968bcb0991SDimitry Andric << (B.isZeroFill() ? "zero-fill" : "content") 978bcb0991SDimitry Andric << ", align = " << B.getAlignment() 988bcb0991SDimitry Andric << ", align-ofs = " << B.getAlignmentOffset() 998bcb0991SDimitry Andric << ", section = " << B.getSection().getName(); 1008bcb0991SDimitry Andric } 1018bcb0991SDimitry Andric 1028bcb0991SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const Symbol &Sym) { 1030b57cec5SDimitry Andric OS << "<"; 1048bcb0991SDimitry Andric if (Sym.getName().empty()) 1058bcb0991SDimitry Andric OS << "*anon*"; 1060b57cec5SDimitry Andric else 1078bcb0991SDimitry Andric OS << Sym.getName(); 1088bcb0991SDimitry Andric OS << ": flags = "; 1098bcb0991SDimitry Andric switch (Sym.getLinkage()) { 1108bcb0991SDimitry Andric case Linkage::Strong: 1118bcb0991SDimitry Andric OS << 'S'; 1128bcb0991SDimitry Andric break; 1138bcb0991SDimitry Andric case Linkage::Weak: 1148bcb0991SDimitry Andric OS << 'W'; 1158bcb0991SDimitry Andric break; 1168bcb0991SDimitry Andric } 1178bcb0991SDimitry Andric switch (Sym.getScope()) { 1188bcb0991SDimitry Andric case Scope::Default: 1198bcb0991SDimitry Andric OS << 'D'; 1208bcb0991SDimitry Andric break; 1218bcb0991SDimitry Andric case Scope::Hidden: 1228bcb0991SDimitry Andric OS << 'H'; 1238bcb0991SDimitry Andric break; 1248bcb0991SDimitry Andric case Scope::Local: 1258bcb0991SDimitry Andric OS << 'L'; 1268bcb0991SDimitry Andric break; 1278bcb0991SDimitry Andric } 1288bcb0991SDimitry Andric OS << (Sym.isLive() ? '+' : '-') 1298bcb0991SDimitry Andric << ", size = " << formatv("{0:x8}", Sym.getSize()) 1308bcb0991SDimitry Andric << ", addr = " << formatv("{0:x16}", Sym.getAddress()) << " (" 1318bcb0991SDimitry Andric << formatv("{0:x16}", Sym.getAddressable().getAddress()) << " + " 1328bcb0991SDimitry Andric << formatv("{0:x8}", Sym.getOffset()); 1338bcb0991SDimitry Andric if (Sym.isDefined()) 1348bcb0991SDimitry Andric OS << " " << Sym.getBlock().getSection().getName(); 1358bcb0991SDimitry Andric OS << ")>"; 1360b57cec5SDimitry Andric return OS; 1370b57cec5SDimitry Andric } 1380b57cec5SDimitry Andric 1398bcb0991SDimitry Andric void printEdge(raw_ostream &OS, const Block &B, const Edge &E, 1400b57cec5SDimitry Andric StringRef EdgeKindName) { 1418bcb0991SDimitry Andric OS << "edge@" << formatv("{0:x16}", B.getAddress() + E.getOffset()) << ": " 1428bcb0991SDimitry Andric << formatv("{0:x16}", B.getAddress()) << " + " << E.getOffset() << " -- " 1438bcb0991SDimitry Andric << EdgeKindName << " -> " << E.getTarget() << " + " << E.getAddend(); 1440b57cec5SDimitry Andric } 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric Section::~Section() { 1478bcb0991SDimitry Andric for (auto *Sym : Symbols) 1488bcb0991SDimitry Andric Sym->~Symbol(); 1498bcb0991SDimitry Andric for (auto *B : Blocks) 1508bcb0991SDimitry Andric B->~Block(); 1518bcb0991SDimitry Andric } 1528bcb0991SDimitry Andric 153480093f4SDimitry Andric Block &LinkGraph::splitBlock(Block &B, size_t SplitIndex, 154480093f4SDimitry Andric SplitBlockCache *Cache) { 155480093f4SDimitry Andric 156480093f4SDimitry Andric assert(SplitIndex > 0 && "splitBlock can not be called with SplitIndex == 0"); 157480093f4SDimitry Andric 158480093f4SDimitry Andric // If the split point covers all of B then just return B. 159480093f4SDimitry Andric if (SplitIndex == B.getSize()) 160480093f4SDimitry Andric return B; 161480093f4SDimitry Andric 162480093f4SDimitry Andric assert(SplitIndex < B.getSize() && "SplitIndex out of range"); 163480093f4SDimitry Andric 164480093f4SDimitry Andric // Create the new block covering [ 0, SplitIndex ). 165480093f4SDimitry Andric auto &NewBlock = 166480093f4SDimitry Andric B.isZeroFill() 167480093f4SDimitry Andric ? createZeroFillBlock(B.getSection(), SplitIndex, B.getAddress(), 168480093f4SDimitry Andric B.getAlignment(), B.getAlignmentOffset()) 169480093f4SDimitry Andric : createContentBlock( 170480093f4SDimitry Andric B.getSection(), B.getContent().substr(0, SplitIndex), 171480093f4SDimitry Andric B.getAddress(), B.getAlignment(), B.getAlignmentOffset()); 172480093f4SDimitry Andric 173480093f4SDimitry Andric // Modify B to cover [ SplitIndex, B.size() ). 174480093f4SDimitry Andric B.setAddress(B.getAddress() + SplitIndex); 175480093f4SDimitry Andric B.setContent(B.getContent().substr(SplitIndex)); 176480093f4SDimitry Andric B.setAlignmentOffset((B.getAlignmentOffset() + SplitIndex) % 177480093f4SDimitry Andric B.getAlignment()); 178480093f4SDimitry Andric 179480093f4SDimitry Andric // Handle edge transfer/update. 180480093f4SDimitry Andric { 181480093f4SDimitry Andric // Copy edges to NewBlock (recording their iterators so that we can remove 182480093f4SDimitry Andric // them from B), and update of Edges remaining on B. 183480093f4SDimitry Andric std::vector<Block::edge_iterator> EdgesToRemove; 184*5ffd83dbSDimitry Andric for (auto I = B.edges().begin(); I != B.edges().end();) { 185480093f4SDimitry Andric if (I->getOffset() < SplitIndex) { 186480093f4SDimitry Andric NewBlock.addEdge(*I); 187*5ffd83dbSDimitry Andric I = B.removeEdge(I); 188*5ffd83dbSDimitry Andric } else { 189480093f4SDimitry Andric I->setOffset(I->getOffset() - SplitIndex); 190*5ffd83dbSDimitry Andric ++I; 191480093f4SDimitry Andric } 192480093f4SDimitry Andric } 193480093f4SDimitry Andric } 194480093f4SDimitry Andric 195480093f4SDimitry Andric // Handle symbol transfer/update. 196480093f4SDimitry Andric { 197480093f4SDimitry Andric // Initialize the symbols cache if necessary. 198480093f4SDimitry Andric SplitBlockCache LocalBlockSymbolsCache; 199480093f4SDimitry Andric if (!Cache) 200480093f4SDimitry Andric Cache = &LocalBlockSymbolsCache; 201480093f4SDimitry Andric if (*Cache == None) { 202480093f4SDimitry Andric *Cache = SplitBlockCache::value_type(); 203480093f4SDimitry Andric for (auto *Sym : B.getSection().symbols()) 204480093f4SDimitry Andric if (&Sym->getBlock() == &B) 205480093f4SDimitry Andric (*Cache)->push_back(Sym); 206480093f4SDimitry Andric 207480093f4SDimitry Andric llvm::sort(**Cache, [](const Symbol *LHS, const Symbol *RHS) { 208480093f4SDimitry Andric return LHS->getOffset() > RHS->getOffset(); 209480093f4SDimitry Andric }); 210480093f4SDimitry Andric } 211480093f4SDimitry Andric auto &BlockSymbols = **Cache; 212480093f4SDimitry Andric 213480093f4SDimitry Andric // Transfer all symbols with offset less than SplitIndex to NewBlock. 214480093f4SDimitry Andric while (!BlockSymbols.empty() && 215480093f4SDimitry Andric BlockSymbols.back()->getOffset() < SplitIndex) { 216480093f4SDimitry Andric BlockSymbols.back()->setBlock(NewBlock); 217480093f4SDimitry Andric BlockSymbols.pop_back(); 218480093f4SDimitry Andric } 219480093f4SDimitry Andric 220480093f4SDimitry Andric // Update offsets for all remaining symbols in B. 221480093f4SDimitry Andric for (auto *Sym : BlockSymbols) 222480093f4SDimitry Andric Sym->setOffset(Sym->getOffset() - SplitIndex); 223480093f4SDimitry Andric } 224480093f4SDimitry Andric 225480093f4SDimitry Andric return NewBlock; 226480093f4SDimitry Andric } 227480093f4SDimitry Andric 2288bcb0991SDimitry Andric void LinkGraph::dump(raw_ostream &OS, 2290b57cec5SDimitry Andric std::function<StringRef(Edge::Kind)> EdgeKindToName) { 2300b57cec5SDimitry Andric if (!EdgeKindToName) 2310b57cec5SDimitry Andric EdgeKindToName = [](Edge::Kind K) { return StringRef(); }; 2320b57cec5SDimitry Andric 2338bcb0991SDimitry Andric OS << "Symbols:\n"; 2348bcb0991SDimitry Andric for (auto *Sym : defined_symbols()) { 2358bcb0991SDimitry Andric OS << " " << format("0x%016" PRIx64, Sym->getAddress()) << ": " << *Sym 2360b57cec5SDimitry Andric << "\n"; 2378bcb0991SDimitry Andric if (Sym->isDefined()) { 2388bcb0991SDimitry Andric for (auto &E : Sym->getBlock().edges()) { 2390b57cec5SDimitry Andric OS << " "; 2400b57cec5SDimitry Andric StringRef EdgeName = (E.getKind() < Edge::FirstRelocation 2410b57cec5SDimitry Andric ? getGenericEdgeKindName(E.getKind()) 2420b57cec5SDimitry Andric : EdgeKindToName(E.getKind())); 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric if (!EdgeName.empty()) 2458bcb0991SDimitry Andric printEdge(OS, Sym->getBlock(), E, EdgeName); 2460b57cec5SDimitry Andric else { 2470b57cec5SDimitry Andric auto EdgeNumberString = std::to_string(E.getKind()); 2488bcb0991SDimitry Andric printEdge(OS, Sym->getBlock(), E, EdgeNumberString); 2490b57cec5SDimitry Andric } 2500b57cec5SDimitry Andric OS << "\n"; 2510b57cec5SDimitry Andric } 2520b57cec5SDimitry Andric } 2538bcb0991SDimitry Andric } 2540b57cec5SDimitry Andric 2558bcb0991SDimitry Andric OS << "Absolute symbols:\n"; 2568bcb0991SDimitry Andric for (auto *Sym : absolute_symbols()) 2578bcb0991SDimitry Andric OS << " " << format("0x%016" PRIx64, Sym->getAddress()) << ": " << *Sym 2580b57cec5SDimitry Andric << "\n"; 2590b57cec5SDimitry Andric 2608bcb0991SDimitry Andric OS << "External symbols:\n"; 2618bcb0991SDimitry Andric for (auto *Sym : external_symbols()) 2628bcb0991SDimitry Andric OS << " " << format("0x%016" PRIx64, Sym->getAddress()) << ": " << *Sym 2630b57cec5SDimitry Andric << "\n"; 2640b57cec5SDimitry Andric } 2650b57cec5SDimitry Andric 266480093f4SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LF) { 267480093f4SDimitry Andric switch (LF) { 268480093f4SDimitry Andric case SymbolLookupFlags::RequiredSymbol: 269480093f4SDimitry Andric return OS << "RequiredSymbol"; 270480093f4SDimitry Andric case SymbolLookupFlags::WeaklyReferencedSymbol: 271480093f4SDimitry Andric return OS << "WeaklyReferencedSymbol"; 272480093f4SDimitry Andric } 273480093f4SDimitry Andric llvm_unreachable("Unrecognized lookup flags"); 274480093f4SDimitry Andric } 275480093f4SDimitry Andric 2768bcb0991SDimitry Andric void JITLinkAsyncLookupContinuation::anchor() {} 2778bcb0991SDimitry Andric 2780b57cec5SDimitry Andric JITLinkContext::~JITLinkContext() {} 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andric bool JITLinkContext::shouldAddDefaultTargetPasses(const Triple &TT) const { 2810b57cec5SDimitry Andric return true; 2820b57cec5SDimitry Andric } 2830b57cec5SDimitry Andric 2848bcb0991SDimitry Andric LinkGraphPassFunction JITLinkContext::getMarkLivePass(const Triple &TT) const { 2858bcb0991SDimitry Andric return LinkGraphPassFunction(); 2860b57cec5SDimitry Andric } 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric Error JITLinkContext::modifyPassConfig(const Triple &TT, 2890b57cec5SDimitry Andric PassConfiguration &Config) { 2900b57cec5SDimitry Andric return Error::success(); 2910b57cec5SDimitry Andric } 2920b57cec5SDimitry Andric 2938bcb0991SDimitry Andric Error markAllSymbolsLive(LinkGraph &G) { 2948bcb0991SDimitry Andric for (auto *Sym : G.defined_symbols()) 2958bcb0991SDimitry Andric Sym->setLive(true); 2960b57cec5SDimitry Andric return Error::success(); 2970b57cec5SDimitry Andric } 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric void jitLink(std::unique_ptr<JITLinkContext> Ctx) { 3000b57cec5SDimitry Andric auto Magic = identify_magic(Ctx->getObjectBuffer().getBuffer()); 3010b57cec5SDimitry Andric switch (Magic) { 3020b57cec5SDimitry Andric case file_magic::macho_object: 3030b57cec5SDimitry Andric return jitLink_MachO(std::move(Ctx)); 304*5ffd83dbSDimitry Andric case file_magic::elf_relocatable: 305*5ffd83dbSDimitry Andric return jitLink_ELF(std::move(Ctx)); 3060b57cec5SDimitry Andric default: 3070b57cec5SDimitry Andric Ctx->notifyFailed(make_error<JITLinkError>("Unsupported file format")); 3080b57cec5SDimitry Andric }; 3090b57cec5SDimitry Andric } 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric } // end namespace jitlink 3120b57cec5SDimitry Andric } // end namespace llvm 313