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" 135ffd83dbSDimitry 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: 67*e8d8bef9SDimitry Andric return "<Unrecognized edge 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()) << ": " 96*e8d8bef9SDimitry Andric << "size = " << formatv("{0:x}", B.getSize()) << ", " 978bcb0991SDimitry Andric << (B.isZeroFill() ? "zero-fill" : "content") 988bcb0991SDimitry Andric << ", align = " << B.getAlignment() 998bcb0991SDimitry Andric << ", align-ofs = " << B.getAlignmentOffset() 1008bcb0991SDimitry Andric << ", section = " << B.getSection().getName(); 1018bcb0991SDimitry Andric } 1028bcb0991SDimitry Andric 1038bcb0991SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const Symbol &Sym) { 1040b57cec5SDimitry Andric OS << "<"; 1058bcb0991SDimitry Andric if (Sym.getName().empty()) 1068bcb0991SDimitry Andric OS << "*anon*"; 1070b57cec5SDimitry Andric else 1088bcb0991SDimitry Andric OS << Sym.getName(); 1098bcb0991SDimitry Andric OS << ": flags = "; 1108bcb0991SDimitry Andric switch (Sym.getLinkage()) { 1118bcb0991SDimitry Andric case Linkage::Strong: 1128bcb0991SDimitry Andric OS << 'S'; 1138bcb0991SDimitry Andric break; 1148bcb0991SDimitry Andric case Linkage::Weak: 1158bcb0991SDimitry Andric OS << 'W'; 1168bcb0991SDimitry Andric break; 1178bcb0991SDimitry Andric } 1188bcb0991SDimitry Andric switch (Sym.getScope()) { 1198bcb0991SDimitry Andric case Scope::Default: 1208bcb0991SDimitry Andric OS << 'D'; 1218bcb0991SDimitry Andric break; 1228bcb0991SDimitry Andric case Scope::Hidden: 1238bcb0991SDimitry Andric OS << 'H'; 1248bcb0991SDimitry Andric break; 1258bcb0991SDimitry Andric case Scope::Local: 1268bcb0991SDimitry Andric OS << 'L'; 1278bcb0991SDimitry Andric break; 1288bcb0991SDimitry Andric } 1298bcb0991SDimitry Andric OS << (Sym.isLive() ? '+' : '-') 130*e8d8bef9SDimitry Andric << ", size = " << formatv("{0:x}", Sym.getSize()) 1318bcb0991SDimitry Andric << ", addr = " << formatv("{0:x16}", Sym.getAddress()) << " (" 1328bcb0991SDimitry Andric << formatv("{0:x16}", Sym.getAddressable().getAddress()) << " + " 133*e8d8bef9SDimitry Andric << formatv("{0:x}", Sym.getOffset()); 1348bcb0991SDimitry Andric if (Sym.isDefined()) 1358bcb0991SDimitry Andric OS << " " << Sym.getBlock().getSection().getName(); 1368bcb0991SDimitry Andric OS << ")>"; 1370b57cec5SDimitry Andric return OS; 1380b57cec5SDimitry Andric } 1390b57cec5SDimitry Andric 1408bcb0991SDimitry Andric void printEdge(raw_ostream &OS, const Block &B, const Edge &E, 1410b57cec5SDimitry Andric StringRef EdgeKindName) { 1428bcb0991SDimitry Andric OS << "edge@" << formatv("{0:x16}", B.getAddress() + E.getOffset()) << ": " 143*e8d8bef9SDimitry Andric << formatv("{0:x16}", B.getAddress()) << " + " 144*e8d8bef9SDimitry Andric << formatv("{0:x}", E.getOffset()) << " -- " << EdgeKindName << " -> "; 145*e8d8bef9SDimitry Andric 146*e8d8bef9SDimitry Andric auto &TargetSym = E.getTarget(); 147*e8d8bef9SDimitry Andric if (TargetSym.hasName()) 148*e8d8bef9SDimitry Andric OS << TargetSym.getName(); 149*e8d8bef9SDimitry Andric else { 150*e8d8bef9SDimitry Andric auto &TargetBlock = TargetSym.getBlock(); 151*e8d8bef9SDimitry Andric auto &TargetSec = TargetBlock.getSection(); 152*e8d8bef9SDimitry Andric JITTargetAddress SecAddress = ~JITTargetAddress(0); 153*e8d8bef9SDimitry Andric for (auto *B : TargetSec.blocks()) 154*e8d8bef9SDimitry Andric if (B->getAddress() < SecAddress) 155*e8d8bef9SDimitry Andric SecAddress = B->getAddress(); 156*e8d8bef9SDimitry Andric 157*e8d8bef9SDimitry Andric JITTargetAddress SecDelta = TargetSym.getAddress() - SecAddress; 158*e8d8bef9SDimitry Andric OS << formatv("{0:x16}", TargetSym.getAddress()) << " (section " 159*e8d8bef9SDimitry Andric << TargetSec.getName(); 160*e8d8bef9SDimitry Andric if (SecDelta) 161*e8d8bef9SDimitry Andric OS << " + " << formatv("{0:x}", SecDelta); 162*e8d8bef9SDimitry Andric OS << " / block " << formatv("{0:x16}", TargetBlock.getAddress()); 163*e8d8bef9SDimitry Andric if (TargetSym.getOffset()) 164*e8d8bef9SDimitry Andric OS << " + " << formatv("{0:x}", TargetSym.getOffset()); 165*e8d8bef9SDimitry Andric OS << ")"; 166*e8d8bef9SDimitry Andric } 167*e8d8bef9SDimitry Andric 168*e8d8bef9SDimitry Andric if (E.getAddend() != 0) 169*e8d8bef9SDimitry Andric OS << " + " << E.getAddend(); 1700b57cec5SDimitry Andric } 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric Section::~Section() { 1738bcb0991SDimitry Andric for (auto *Sym : Symbols) 1748bcb0991SDimitry Andric Sym->~Symbol(); 1758bcb0991SDimitry Andric for (auto *B : Blocks) 1768bcb0991SDimitry Andric B->~Block(); 1778bcb0991SDimitry Andric } 1788bcb0991SDimitry Andric 179480093f4SDimitry Andric Block &LinkGraph::splitBlock(Block &B, size_t SplitIndex, 180480093f4SDimitry Andric SplitBlockCache *Cache) { 181480093f4SDimitry Andric 182480093f4SDimitry Andric assert(SplitIndex > 0 && "splitBlock can not be called with SplitIndex == 0"); 183480093f4SDimitry Andric 184480093f4SDimitry Andric // If the split point covers all of B then just return B. 185480093f4SDimitry Andric if (SplitIndex == B.getSize()) 186480093f4SDimitry Andric return B; 187480093f4SDimitry Andric 188480093f4SDimitry Andric assert(SplitIndex < B.getSize() && "SplitIndex out of range"); 189480093f4SDimitry Andric 190480093f4SDimitry Andric // Create the new block covering [ 0, SplitIndex ). 191480093f4SDimitry Andric auto &NewBlock = 192480093f4SDimitry Andric B.isZeroFill() 193480093f4SDimitry Andric ? createZeroFillBlock(B.getSection(), SplitIndex, B.getAddress(), 194480093f4SDimitry Andric B.getAlignment(), B.getAlignmentOffset()) 195480093f4SDimitry Andric : createContentBlock( 196480093f4SDimitry Andric B.getSection(), B.getContent().substr(0, SplitIndex), 197480093f4SDimitry Andric B.getAddress(), B.getAlignment(), B.getAlignmentOffset()); 198480093f4SDimitry Andric 199480093f4SDimitry Andric // Modify B to cover [ SplitIndex, B.size() ). 200480093f4SDimitry Andric B.setAddress(B.getAddress() + SplitIndex); 201480093f4SDimitry Andric B.setContent(B.getContent().substr(SplitIndex)); 202480093f4SDimitry Andric B.setAlignmentOffset((B.getAlignmentOffset() + SplitIndex) % 203480093f4SDimitry Andric B.getAlignment()); 204480093f4SDimitry Andric 205480093f4SDimitry Andric // Handle edge transfer/update. 206480093f4SDimitry Andric { 207480093f4SDimitry Andric // Copy edges to NewBlock (recording their iterators so that we can remove 208480093f4SDimitry Andric // them from B), and update of Edges remaining on B. 209480093f4SDimitry Andric std::vector<Block::edge_iterator> EdgesToRemove; 2105ffd83dbSDimitry Andric for (auto I = B.edges().begin(); I != B.edges().end();) { 211480093f4SDimitry Andric if (I->getOffset() < SplitIndex) { 212480093f4SDimitry Andric NewBlock.addEdge(*I); 2135ffd83dbSDimitry Andric I = B.removeEdge(I); 2145ffd83dbSDimitry Andric } else { 215480093f4SDimitry Andric I->setOffset(I->getOffset() - SplitIndex); 2165ffd83dbSDimitry Andric ++I; 217480093f4SDimitry Andric } 218480093f4SDimitry Andric } 219480093f4SDimitry Andric } 220480093f4SDimitry Andric 221480093f4SDimitry Andric // Handle symbol transfer/update. 222480093f4SDimitry Andric { 223480093f4SDimitry Andric // Initialize the symbols cache if necessary. 224480093f4SDimitry Andric SplitBlockCache LocalBlockSymbolsCache; 225480093f4SDimitry Andric if (!Cache) 226480093f4SDimitry Andric Cache = &LocalBlockSymbolsCache; 227480093f4SDimitry Andric if (*Cache == None) { 228480093f4SDimitry Andric *Cache = SplitBlockCache::value_type(); 229480093f4SDimitry Andric for (auto *Sym : B.getSection().symbols()) 230480093f4SDimitry Andric if (&Sym->getBlock() == &B) 231480093f4SDimitry Andric (*Cache)->push_back(Sym); 232480093f4SDimitry Andric 233480093f4SDimitry Andric llvm::sort(**Cache, [](const Symbol *LHS, const Symbol *RHS) { 234480093f4SDimitry Andric return LHS->getOffset() > RHS->getOffset(); 235480093f4SDimitry Andric }); 236480093f4SDimitry Andric } 237480093f4SDimitry Andric auto &BlockSymbols = **Cache; 238480093f4SDimitry Andric 239480093f4SDimitry Andric // Transfer all symbols with offset less than SplitIndex to NewBlock. 240480093f4SDimitry Andric while (!BlockSymbols.empty() && 241480093f4SDimitry Andric BlockSymbols.back()->getOffset() < SplitIndex) { 242480093f4SDimitry Andric BlockSymbols.back()->setBlock(NewBlock); 243480093f4SDimitry Andric BlockSymbols.pop_back(); 244480093f4SDimitry Andric } 245480093f4SDimitry Andric 246480093f4SDimitry Andric // Update offsets for all remaining symbols in B. 247480093f4SDimitry Andric for (auto *Sym : BlockSymbols) 248480093f4SDimitry Andric Sym->setOffset(Sym->getOffset() - SplitIndex); 249480093f4SDimitry Andric } 250480093f4SDimitry Andric 251480093f4SDimitry Andric return NewBlock; 252480093f4SDimitry Andric } 253480093f4SDimitry Andric 2548bcb0991SDimitry Andric void LinkGraph::dump(raw_ostream &OS, 2550b57cec5SDimitry Andric std::function<StringRef(Edge::Kind)> EdgeKindToName) { 2560b57cec5SDimitry Andric if (!EdgeKindToName) 2570b57cec5SDimitry Andric EdgeKindToName = [](Edge::Kind K) { return StringRef(); }; 2580b57cec5SDimitry Andric 2598bcb0991SDimitry Andric OS << "Symbols:\n"; 2608bcb0991SDimitry Andric for (auto *Sym : defined_symbols()) { 2618bcb0991SDimitry Andric OS << " " << format("0x%016" PRIx64, Sym->getAddress()) << ": " << *Sym 2620b57cec5SDimitry Andric << "\n"; 2638bcb0991SDimitry Andric if (Sym->isDefined()) { 2648bcb0991SDimitry Andric for (auto &E : Sym->getBlock().edges()) { 2650b57cec5SDimitry Andric OS << " "; 2660b57cec5SDimitry Andric StringRef EdgeName = (E.getKind() < Edge::FirstRelocation 2670b57cec5SDimitry Andric ? getGenericEdgeKindName(E.getKind()) 2680b57cec5SDimitry Andric : EdgeKindToName(E.getKind())); 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric if (!EdgeName.empty()) 2718bcb0991SDimitry Andric printEdge(OS, Sym->getBlock(), E, EdgeName); 2720b57cec5SDimitry Andric else { 2730b57cec5SDimitry Andric auto EdgeNumberString = std::to_string(E.getKind()); 2748bcb0991SDimitry Andric printEdge(OS, Sym->getBlock(), E, EdgeNumberString); 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric OS << "\n"; 2770b57cec5SDimitry Andric } 2780b57cec5SDimitry Andric } 2798bcb0991SDimitry Andric } 2800b57cec5SDimitry Andric 2818bcb0991SDimitry Andric OS << "Absolute symbols:\n"; 2828bcb0991SDimitry Andric for (auto *Sym : absolute_symbols()) 2838bcb0991SDimitry Andric OS << " " << format("0x%016" PRIx64, Sym->getAddress()) << ": " << *Sym 2840b57cec5SDimitry Andric << "\n"; 2850b57cec5SDimitry Andric 2868bcb0991SDimitry Andric OS << "External symbols:\n"; 2878bcb0991SDimitry Andric for (auto *Sym : external_symbols()) 2888bcb0991SDimitry Andric OS << " " << format("0x%016" PRIx64, Sym->getAddress()) << ": " << *Sym 2890b57cec5SDimitry Andric << "\n"; 2900b57cec5SDimitry Andric } 2910b57cec5SDimitry Andric 292480093f4SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LF) { 293480093f4SDimitry Andric switch (LF) { 294480093f4SDimitry Andric case SymbolLookupFlags::RequiredSymbol: 295480093f4SDimitry Andric return OS << "RequiredSymbol"; 296480093f4SDimitry Andric case SymbolLookupFlags::WeaklyReferencedSymbol: 297480093f4SDimitry Andric return OS << "WeaklyReferencedSymbol"; 298480093f4SDimitry Andric } 299480093f4SDimitry Andric llvm_unreachable("Unrecognized lookup flags"); 300480093f4SDimitry Andric } 301480093f4SDimitry Andric 3028bcb0991SDimitry Andric void JITLinkAsyncLookupContinuation::anchor() {} 3038bcb0991SDimitry Andric 3040b57cec5SDimitry Andric JITLinkContext::~JITLinkContext() {} 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andric bool JITLinkContext::shouldAddDefaultTargetPasses(const Triple &TT) const { 3070b57cec5SDimitry Andric return true; 3080b57cec5SDimitry Andric } 3090b57cec5SDimitry Andric 3108bcb0991SDimitry Andric LinkGraphPassFunction JITLinkContext::getMarkLivePass(const Triple &TT) const { 3118bcb0991SDimitry Andric return LinkGraphPassFunction(); 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andric Error JITLinkContext::modifyPassConfig(const Triple &TT, 3150b57cec5SDimitry Andric PassConfiguration &Config) { 3160b57cec5SDimitry Andric return Error::success(); 3170b57cec5SDimitry Andric } 3180b57cec5SDimitry Andric 3198bcb0991SDimitry Andric Error markAllSymbolsLive(LinkGraph &G) { 3208bcb0991SDimitry Andric for (auto *Sym : G.defined_symbols()) 3218bcb0991SDimitry Andric Sym->setLive(true); 3220b57cec5SDimitry Andric return Error::success(); 3230b57cec5SDimitry Andric } 3240b57cec5SDimitry Andric 325*e8d8bef9SDimitry Andric Expected<std::unique_ptr<LinkGraph>> 326*e8d8bef9SDimitry Andric createLinkGraphFromObject(MemoryBufferRef ObjectBuffer) { 327*e8d8bef9SDimitry Andric auto Magic = identify_magic(ObjectBuffer.getBuffer()); 3280b57cec5SDimitry Andric switch (Magic) { 3290b57cec5SDimitry Andric case file_magic::macho_object: 330*e8d8bef9SDimitry Andric return createLinkGraphFromMachOObject(std::move(ObjectBuffer)); 3315ffd83dbSDimitry Andric case file_magic::elf_relocatable: 332*e8d8bef9SDimitry Andric return createLinkGraphFromELFObject(std::move(ObjectBuffer)); 3330b57cec5SDimitry Andric default: 334*e8d8bef9SDimitry Andric return make_error<JITLinkError>("Unsupported file format"); 335*e8d8bef9SDimitry Andric }; 336*e8d8bef9SDimitry Andric } 337*e8d8bef9SDimitry Andric 338*e8d8bef9SDimitry Andric void link(std::unique_ptr<LinkGraph> G, std::unique_ptr<JITLinkContext> Ctx) { 339*e8d8bef9SDimitry Andric switch (G->getTargetTriple().getObjectFormat()) { 340*e8d8bef9SDimitry Andric case Triple::MachO: 341*e8d8bef9SDimitry Andric return link_MachO(std::move(G), std::move(Ctx)); 342*e8d8bef9SDimitry Andric case Triple::ELF: 343*e8d8bef9SDimitry Andric return link_ELF(std::move(G), std::move(Ctx)); 344*e8d8bef9SDimitry Andric default: 345*e8d8bef9SDimitry Andric Ctx->notifyFailed(make_error<JITLinkError>("Unsupported object format")); 3460b57cec5SDimitry Andric }; 3470b57cec5SDimitry Andric } 3480b57cec5SDimitry Andric 3490b57cec5SDimitry Andric } // end namespace jitlink 3500b57cec5SDimitry Andric } // end namespace llvm 351