1161 lines · plain
1====================================2JITLink and ORC's ObjectLinkingLayer3====================================4 5.. contents::6 :local:7 8Introduction9============10 11This document aims to provide a high-level overview of the design and API12of the JITLink library. It assumes some familiarity with linking and13relocatable object files, but should not require deep expertise. If you know14what a section, symbol, and relocation are then you should find this document15accessible. If it is not, please submit a patch (:doc:`Contributing`) or file a16bug (:doc:`HowToSubmitABug`).17 18JITLink is a library for :ref:`jit_linking`. It was built to support the :doc:`ORC JIT19APIs<ORCv2>` and is most commonly accessed via ORC's ObjectLinkingLayer API. JITLink was20developed with the aim of supporting the full set of features provided by each21object format; including static initializers, exception handling, thread local22variables, and language runtime registration. Supporting these features enables23ORC to execute code generated from source languages which rely on these features24(e.g. C++ requires object format support for static initializers to support25static constructors, eh-frame registration for exceptions, and TLV support for26thread locals; Swift and Objective-C require language runtime registration for27many features). For some object format features support is provided entirely28within JITLink, and for others it is provided in cooperation with the29(prototype) ORC runtime.30 31JITLink aims to support the following features, some of which are still under32development:33 341. Cross-process and cross-architecture linking of single relocatable objects35 into a target *executor* process.36 372. Support for all object format features.38 393. Open linker data structures (``LinkGraph``) and pass system.40 41JITLink and ObjectLinkingLayer42==============================43 44``ObjectLinkingLayer`` is ORCs wrapper for JITLink. It is an ORC layer that45allows objects to be added to a ``JITDylib``, or emitted from some higher level46program representation. When an object is emitted, ``ObjectLinkingLayer`` uses47JITLink to construct a ``LinkGraph`` (see :ref:`constructing_linkgraphs`) and48calls JITLink's ``link`` function to link the graph into the executor process.49 50The ``ObjectLinkingLayer`` class provides a plugin API,51``ObjectLinkingLayer::Plugin``, which users can subclass in order to inspect and52modify ``LinkGraph`` instances at link time, and react to important JIT events53(such as an object being emitted into target memory). This enables many features54and optimizations that were not possible under MCJIT or RuntimeDyld.55 56ObjectLinkingLayer Plugins57--------------------------58 59The ``ObjectLinkingLayer::Plugin`` class provides the following methods:60 61* ``modifyPassConfig`` is called each time a LinkGraph is about to be linked. It62 can be overridden to install JITLink *Passes* to run during the link process.63 64 .. code-block:: c++65 66 void modifyPassConfig(MaterializationResponsibility &MR,67 jitlink::LinkGraph &G,68 jitlink::PassConfiguration &Config)69 70* ``notifyLoaded`` is called before the link begins, and can be overridden to71 set up any initial state for the given ``MaterializationResponsibility`` if72 needed.73 74 .. code-block:: c++75 76 void notifyLoaded(MaterializationResponsibility &MR)77 78* ``notifyEmitted`` is called after the link is complete and code has been79 emitted to the executor process. It can be overridden to finalize state80 for the ``MaterializationResponsibility`` if needed.81 82 .. code-block:: c++83 84 Error notifyEmitted(MaterializationResponsibility &MR)85 86* ``notifyFailed`` is called if the link fails at any point. It can be87 overridden to react to the failure (e.g. to deallocate any already allocated88 resources).89 90 .. code-block:: c++91 92 Error notifyFailed(MaterializationResponsibility &MR)93 94* ``notifyRemovingResources`` is called when a request is made to remove any95 resources associated with the ``ResourceKey`` *K* for the96 ``MaterializationResponsibility``.97 98 .. code-block:: c++99 100 Error notifyRemovingResources(JITDylib &JD, ResourceKey K)101 102* ``notifyTransferringResources`` is called if/when a request is made to103 transfer tracking of any resources associated with ``ResourceKey``104 *SrcKey* to *DstKey*.105 106 .. code-block:: c++107 108 void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,109 ResourceKey SrcKey)110 111Plugin authors are required to implement the ``notifyFailed``,112``notifyRemovingResources``, and ``notifyTransferringResources`` methods in113order to safely manage resources in the case of resource removal or transfer,114or link failure. If no resources are managed by the plugin then these methods115can be implemented as no-ops returning ``Error::success()``.116 117Plugin instances are added to an ``ObjectLinkingLayer`` by118calling the ``addPlugin`` method [1]_. E.g.119 120.. code-block:: c++121 122 // Plugin class to print the set of defined symbols in an object when that123 // object is linked.124 class MyPlugin : public ObjectLinkingLayer::Plugin {125 public:126 127 // Add passes to print the set of defined symbols after dead-stripping.128 void modifyPassConfig(MaterializationResponsibility &MR,129 jitlink::LinkGraph &G,130 jitlink::PassConfiguration &Config) override {131 Config.PostPrunePasses.push_back([this](jitlink::LinkGraph &G) {132 return printAllSymbols(G);133 });134 }135 136 // Implement mandatory overrides:137 Error notifyFailed(MaterializationResponsibility &MR) override {138 return Error::success();139 }140 Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override {141 return Error::success();142 }143 void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,144 ResourceKey SrcKey) override {}145 146 // JITLink pass to print all defined symbols in G.147 Error printAllSymbols(LinkGraph &G) {148 for (auto *Sym : G.defined_symbols())149 if (Sym->hasName())150 dbgs() << Sym->getName() << "\n";151 return Error::success();152 }153 };154 155 // Create our LLJIT instance using a custom object linking layer setup.156 // This gives us a chance to install our plugin.157 auto J = ExitOnErr(LLJITBuilder()158 .setObjectLinkingLayerCreator(159 [](ExecutionSession &ES, const Triple &T) {160 // Manually set up the ObjectLinkingLayer for our LLJIT161 // instance.162 auto OLL = std::make_unique<ObjectLinkingLayer>(163 ES, std::make_unique<jitlink::InProcessMemoryManager>());164 165 // Install our plugin:166 OLL->addPlugin(std::make_unique<MyPlugin>());167 168 return OLL;169 })170 .create());171 172 // Add an object to the JIT. Nothing happens here: linking isn't triggered173 // until we look up some symbol in our object.174 ExitOnErr(J->addObject(loadFromDisk("main.o")));175 176 // Plugin triggers here when our lookup of main triggers linking of main.o177 auto MainSym = J->lookup("main");178 179LinkGraph180=========181 182JITLink maps all relocatable object formats to a generic ``LinkGraph`` type183that is designed to make linking fast and easy (``LinkGraph`` instances can184also be created manually. See :ref:`constructing_linkgraphs`).185 186Relocatable object formats (e.g. COFF, ELF, MachO) differ in their details,187but share a common goal: to represent machine level code and data with188annotations that allow them to be relocated in a virtual address space. To189this end they usually contain names (symbols) for content defined inside the190file or externally, chunks of content that must be moved as a unit (sections191or subsections, depending on the format), and annotations describing how to192patch content based on the final address of some target symbol/section193(relocations).194 195At a high level, the ``LinkGraph`` type represents these concepts as a decorated196graph. Nodes in the graph represent symbols and content, and edges represent197relocations. Each of the elements of the graph is listed here:198 199* ``Addressable`` -- A node in the link graph that can be assigned an address200 in the executor process's virtual address space.201 202 Absolute and external symbols are represented using plain ``Addressable``203 instances. Content defined inside the object file is represented using the204 ``Block`` subclass.205 206* ``Block`` -- An ``Addressable`` node that has ``Content`` (or is marked as207 zero-filled), a parent ``Section``, a ``Size``, an ``Alignment`` (and an208 ``AlignmentOffset``), and a list of ``Edge`` instances.209 210 Blocks provide a container for binary content which must remain contiguous in211 the target address space (a *layout unit*). Many interesting low level212 operations on ``LinkGraph`` instances involve inspecting or mutating block213 content or edges.214 215 * ``Content`` is represented as an ``llvm::StringRef``, and accessible via216 the ``getContent`` method. Content is only available for content blocks,217 and not for zero-fill blocks (use ``isZeroFill`` to check, and prefer218 ``getSize`` when only the block size is needed as it works for both219 zero-fill and content blocks).220 221 * ``Section`` is represented as a ``Section&`` reference, and accessible via222 the ``getSection`` method. The ``Section`` class is described in more detail223 below.224 225 * ``Size`` is represented as a ``size_t``, and is accessible via the226 ``getSize`` method for both content and zero-filled blocks.227 228 * ``Alignment`` is represented as a ``uint64_t``, and available via the229 ``getAlignment`` method. It represents the minimum alignment requirement (in230 bytes) of the start of the block.231 232 * ``AlignmentOffset`` is represented as a ``uint64_t``, and accessible via the233 ``getAlignmentOffset`` method. It represents the offset from the alignment234 required for the start of the block. This is required to support blocks235 whose minimum alignment requirement comes from data at some non-zero offset236 inside the block. E.g. if a block consists of a single byte (with byte237 alignment) followed by a uint64_t (with 8-byte alignment), then the block238 will have 8-byte alignment with an alignment offset of 7.239 240 * list of ``Edge`` instances. An iterator range for this list is returned by241 the ``edges`` method. The ``Edge`` class is described in more detail below.242 243* ``Symbol`` -- An offset from an ``Addressable`` (often a ``Block``), with an244 optional ``Name``, a ``Linkage``, a ``Scope``, a ``Callable`` flag, and a245 ``Live`` flag.246 247 Symbols make it possible to name content (blocks and addressables are248 anonymous), or target content with an ``Edge``.249 250 * ``Name`` is represented as an ``llvm::StringRef`` (equal to251 ``llvm::StringRef()`` if the symbol has no name), and accessible via the252 ``getName`` method.253 254 * ``Linkage`` is one of *Strong* or *Weak*, and is accessible via the255 ``getLinkage`` method. The ``JITLinkContext`` can use this flag to determine256 whether this symbol definition should be kept or dropped.257 258 * ``Scope`` is one of *Default*, *Hidden*, or *Local*, and is accessible via259 the ``getScope`` method. The ``JITLinkContext`` can use this to determine260 who should be able to see the symbol. A symbol with default scope should be261 globally visible. A symbol with hidden scope should be visible to other262 definitions within the same simulated dylib (e.g. ORC ``JITDylib``) or263 executable, but not from elsewhere. A symbol with local scope should only be264 visible within the current ``LinkGraph``.265 266 * ``Callable`` is a boolean which is set to true if this symbol can be called,267 and is accessible via the ``isCallable`` method. This can be used to268 automate the introduction of call-stubs for lazy compilation.269 270 * ``Live`` is a boolean that can be set to mark this symbol as root for271 dead-stripping purposes (see :ref:`generic_link_algorithm`). JITLink's272 dead-stripping algorithm will propagate liveness flags through the graph to273 all reachable symbols before deleting any symbols (and blocks) that are not274 marked live.275 276* ``Edge`` -- A quad of an ``Offset`` (implicitly from the start of the277 containing ``Block``), a ``Kind`` (describing the relocation type), a278 ``Target``, and an ``Addend``.279 280 Edges represent relocations, and occasionally other relationships, between281 blocks and symbols.282 283 * ``Offset``, accessible via ``getOffset``, is an offset from the start of the284 ``Block`` containing the ``Edge``.285 286 * ``Kind``, accessible via ``getKind`` is a relocation type -- it describes287 what kinds of changes (if any) should be made to block content at the given288 ``Offset`` based on the address of the ``Target``.289 290 * ``Target``, accessible via ``getTarget``, is a pointer to a ``Symbol``,291 representing whose address is relevant to the fixup calculation specified by292 the edge's ``Kind``.293 294 * ``Addend``, accessible via ``getAddend``, is a constant whose interpretation295 is determined by the edge's ``Kind``.296 297* ``Section`` -- A set of ``Symbol`` instances, plus a set of ``Block``298 instances, with a ``Name``, a set of ``ProtectionFlags``, and an ``Ordinal``.299 300 Sections make it easy to iterate over the symbols or blocks associated with301 a particular section in the source object file.302 303 * ``blocks()`` returns an iterator over the set of blocks defined in the304 section (as ``Block*`` pointers).305 306 * ``symbols()`` returns an iterator over the set of symbols defined in the307 section (as ``Symbol*`` pointers).308 309 * ``Name`` is represented as an ``llvm::StringRef``, and is accessible via the310 ``getName`` method.311 312 * ``ProtectionFlags`` are represented as a sys::Memory::ProtectionFlags enum,313 and accessible via the ``getProtectionFlags`` method. These flags describe314 whether the section is readable, writable, executable, or some combination315 of these. The most common combinations are ``RW-`` for writable data,316 ``R--`` for constant data, and ``R-X`` for code.317 318 * ``SectionOrdinal``, accessible via ``getOrdinal``, is a number used to order319 the section relative to others. It is usually used to preserve section320 order within a segment (a set of sections with the same memory protections)321 when laying out memory.322 323For the graph-theorists: The ``LinkGraph`` is bipartite, with one set of324``Symbol`` nodes and one set of ``Addressable`` nodes. Each ``Symbol`` node has325one (implicit) edge to its target ``Addressable``. Each ``Block`` has a set of326edges (possibly empty, represented as ``Edge`` instances) back to elements of327the ``Symbol`` set. For convenience and performance of common algorithms,328symbols and blocks are further grouped into ``Sections``.329 330The ``LinkGraph`` itself provides operations for constructing, removing, and331iterating over sections, symbols, and blocks. It also provides metadata332and utilities relevant to the linking process:333 334* Graph element operations335 336 * ``sections`` returns an iterator over all sections in the graph.337 338 * ``findSectionByName`` returns a pointer to the section with the given339 name (as a ``Section*``) if it exists, otherwise returns a nullptr.340 341 * ``blocks`` returns an iterator over all blocks in the graph (across all342 sections).343 344 * ``defined_symbols`` returns an iterator over all defined symbols in the345 graph (across all sections).346 347 * ``external_symbols`` returns an iterator over all external symbols in the348 graph.349 350 * ``absolute_symbols`` returns an iterator over all absolute symbols in the351 graph.352 353 * ``createSection`` creates a section with a given name and protection flags.354 355 * ``createContentBlock`` creates a block with the given initial content,356 parent section, address, alignment, and alignment offset.357 358 * ``createZeroFillBlock`` creates a zero-fill block with the given size,359 parent section, address, alignment, and alignment offset.360 361 * ``addExternalSymbol`` creates a new addressable and symbol with a given362 name, size, and linkage.363 364 * ``addAbsoluteSymbol`` creates a new addressable and symbol with a given365 name, address, size, linkage, scope, and liveness.366 367 * ``addCommonSymbol`` convenience function for creating a zero-filled block368 and weak symbol with a given name, scope, section, initial address, size,369 alignment and liveness.370 371 * ``addAnonymousSymbol`` creates a new anonymous symbol for a given block,372 offset, size, callable-ness, and liveness.373 374 * ``addDefinedSymbol`` creates a new symbol for a given block with a name,375 offset, size, linkage, scope, callable-ness and liveness.376 377 * ``makeExternal`` transforms a formerly defined symbol into an external one378 by creating a new addressable and pointing the symbol at it. The existing379 block is not deleted, but can be manually removed (if unreferenced) by380 calling ``removeBlock``. All edges to the symbol remain valid, but the381 symbol must now be defined outside this ``LinkGraph``.382 383 * ``removeExternalSymbol`` removes an external symbol and its target384 addressable. The target addressable must not be referenced by any other385 symbols.386 387 * ``removeAbsoluteSymbol`` removes an absolute symbol and its target388 addressable. The target addressable must not be referenced by any other389 symbols.390 391 * ``removeDefinedSymbol`` removes a defined symbol, but *does not* remove392 its target block.393 394 * ``removeBlock`` removes the given block.395 396 * ``splitBlock`` split a given block in two at a given index (useful where397 it is known that a block contains decomposable records, e.g. CFI records398 in an eh-frame section).399 400* Graph utility operations401 402 * ``getName`` returns the name of this graph, which is usually based on the403 name of the input object file.404 405 * ``getTargetTriple`` returns an `llvm::Triple` for the executor process.406 407 * ``getPointerSize`` returns the size of a pointer (in bytes) in the executor408 process.409 410 * ``getEndianness`` returns the endianness of the executor process.411 412 * ``allocateString`` copies data from a given ``llvm::Twine`` into the413 link graph's internal allocator. This can be used to ensure that content414 created inside a pass outlives that pass's execution.415 416.. _generic_link_algorithm:417 418Generic Link Algorithm419======================420 421JITLink provides a generic link algorithm which can be extended / modified at422certain points by the introduction of JITLink :ref:`passes`.423 424At the end of each phase the linker packages its state into a *continuation*425and calls the ``JITLinkContext`` object to perform a (potentially high-latency)426asynchronous operation: allocating memory, resolving external symbols, and427finally transferring linked memory to the executing process.428 429#. Phase 1430 431 This phase is called immediately by the ``link`` function as soon as the432 initial configuration (including the pass pipeline setup) is complete.433 434 #. Run pre-prune passes.435 436 These passes are called on the graph before it is pruned. At this stage437 ``LinkGraph`` nodes still have their original vmaddrs. A mark-live pass438 (supplied by the ``JITLinkContext``) will be run at the end of this439 sequence to mark the initial set of live symbols.440 441 Notable use cases: marking nodes live, accessing/copying graph data that442 will be pruned (e.g. metadata that's important for the JIT, but not needed443 for the link process).444 445 #. Prune (dead-strip) the ``LinkGraph``.446 447 Removes all symbols and blocks not reachable from the initial set of live448 symbols.449 450 This allows JITLink to remove unreachable symbols / content, including451 overridden weak and redundant ODR definitions.452 453 #. Run post-prune passes.454 455 These passes are run on the graph after dead-stripping, but before memory456 is allocated or nodes assigned their final target vmaddrs.457 458 Passes run at this stage benefit from pruning, as dead functions and data459 have been stripped from the graph. However new content can still be added460 to the graph, as target and working memory have not been allocated yet.461 462 Notable use cases: Building Global Offset Table (GOT), Procedure Linkage463 Table (PLT), and Thread Local Variable (TLV) entries.464 465 #. Asynchronously allocate memory.466 467 Calls the ``JITLinkContext``'s ``JITLinkMemoryManager`` to allocate both468 working and target memory for the graph. As part of this process the469 ``JITLinkMemoryManager`` will update the addresses of all nodes470 defined in the graph to their assigned target address.471 472 Note: This step only updates the addresses of nodes defined in this graph.473 External symbols will still have null addresses.474 475#. Phase 2476 477 #. Run post-allocation passes.478 479 These passes are run on the graph after working and target memory have480 been allocated, but before the ``JITLinkContext`` is notified of the481 final addresses of the symbols in the graph. This gives these passes a482 chance to set up data structures associated with target addresses before483 any JITLink clients (especially ORC queries for symbol resolution) can484 attempt to access them.485 486 Notable use cases: Setting up mappings between target addresses and487 JIT data structures, such as a mapping between ``__dso_handle`` and488 ``JITDylib*``.489 490 #. Notify the ``JITLinkContext`` of the assigned symbol addresses.491 492 Calls ``JITLinkContext::notifyResolved`` on the link graph, allowing493 clients to react to the symbol address assignments made for this graph.494 In ORC this is used to notify any pending queries for *resolved* symbols,495 including pending queries from concurrently running JITLink instances that496 have reached the next step and are waiting on the address of a symbol in497 this graph to proceed with their link.498 499 #. Identify external symbols and resolve their addresses asynchronously.500 501 Calls the ``JITLinkContext`` to resolve the target address of any external502 symbols in the graph.503 504#. Phase 3505 506 #. Apply external symbol resolution results.507 508 This updates the addresses of all external symbols. At this point all509 nodes in the graph have their final target addresses, however node510 content still points back to the original data in the object file.511 512 #. Run pre-fixup passes.513 514 These passes are called on the graph after all nodes have been assigned515 their final target addresses, but before node content is copied into516 working memory and fixed up. Passes run at this stage can make late517 optimizations to the graph and content based on address layout.518 519 Notable use cases: GOT and PLT relaxation, where GOT and PLT accesses are520 bypassed for fixup targets that are directly accessible under the assigned521 memory layout.522 523 #. Copy block content to working memory and apply fixups.524 525 Copies all block content into allocated working memory (following the526 target layout) and applies fixups. Graph blocks are updated to point at527 the fixed up content.528 529 #. Run post-fixup passes.530 531 These passes are called on the graph after fixups have been applied and532 blocks updated to point to the fixed up content.533 534 Post-fixup passes can inspect blocks contents to see the exact bytes that535 will be copied to the assigned target addresses.536 537 #. Finalize memory asynchronously.538 539 Calls the ``JITLinkMemoryManager`` to copy working memory to the executor540 process and apply the requested permissions.541 542#. Phase 3.543 544 #. Notify the context that the graph has been emitted.545 546 Calls ``JITLinkContext::notifyFinalized`` and hands off the547 ``JITLinkMemoryManager::FinalizedAlloc`` object for this graph's memory548 allocation. This allows the context to track/hold memory allocations and549 react to the newly emitted definitions. In ORC this is used to update the550 ``ExecutionSession`` instance's dependence graph, which may result in551 these symbols (and possibly others) becoming *Ready* if all of their552 dependencies have also been emitted.553 554.. _passes:555 556Passes557------558 559JITLink passes are ``std::function<Error(LinkGraph&)>`` instances. They are free560to inspect and modify the given ``LinkGraph`` subject to the constraints of561whatever phase they are running in (see :ref:`generic_link_algorithm`). If a562pass returns ``Error::success()`` then linking continues. If a pass returns563a failure value then linking is stopped and the ``JITLinkContext`` is notified564that the link failed.565 566Passes may be used by both JITLink backends (e.g. MachO/x86-64 implements GOT567and PLT construction as a pass), and external clients like568``ObjectLinkingLayer::Plugin``.569 570In combination with the open ``LinkGraph`` API, JITLink passes enable the571implementation of powerful new features. For example:572 573* Relaxation optimizations -- A pre-fixup pass can inspect GOT accesses and PLT574 calls and identify situations where the addresses of the entry target and the575 access are close enough to be accessed directly. In this case the pass can576 rewrite the instruction stream of the containing block and update the fixup577 edges to make the access direct.578 579 Code for this looks like:580 581.. code-block:: c++582 583 Error relaxGOTEdges(LinkGraph &G) {584 for (auto *B : G.blocks())585 for (auto &E : B->edges())586 if (E.getKind() == x86_64::GOTLoad) {587 auto &GOTTarget = getGOTEntryTarget(E.getTarget());588 if (isInRange(B.getFixupAddress(E), GOTTarget)) {589 // Rewrite B.getContent() at fixup address from590 // MOVQ to LEAQ591 592 // Update edge target and kind.593 E.setTarget(GOTTarget);594 E.setKind(x86_64::PCRel32);595 }596 }597 598 return Error::success();599 }600 601* Metadata registration -- Post allocation passes can be used to record the602 address range of sections in the target. This can be used to register the603 metadata (e.g exception handling frames, language metadata) in the target604 once memory has been finalized.605 606.. code-block:: c++607 608 Error registerEHFrameSection(LinkGraph &G) {609 if (auto *Sec = G.findSectionByName("__eh_frame")) {610 SectionRange SR(*Sec);611 registerEHFrameSection(SR.getStart(), SR.getEnd());612 }613 614 return Error::success();615 }616 617* Record call sites for later mutation -- A post-allocation pass can record618 the call sites of all calls to a particular function, allowing those call619 sites to be updated later at runtime (e.g. for instrumentation, or to620 enable the function to be lazily compiled but still called directly after621 compilation).622 623.. code-block:: c++624 625 StringRef FunctionName = "foo";626 std::vector<ExecutorAddr> CallSitesForFunction;627 628 auto RecordCallSites =629 [&](LinkGraph &G) -> Error {630 for (auto *B : G.blocks())631 for (auto &E : B.edges())632 if (E.getKind() == CallEdgeKind &&633 E.getTarget().hasName() &&634 E.getTraget().getName() == FunctionName)635 CallSitesForFunction.push_back(B.getFixupAddress(E));636 return Error::success();637 };638 639Memory Management with JITLinkMemoryManager640-------------------------------------------641 642JIT linking requires allocation of two kinds of memory: working memory in the643JIT process and target memory in the execution process (these processes and644memory allocations may be one and the same, depending on how the user wants645to build their JIT). It also requires that these allocations conform to the646requested code model in the target process (e.g. MachO/x86-64's Small code647model requires that all code and data for a simulated dylib is allocated within6484Gb). Finally, it is natural to make the memory manager responsible for649transferring memory to the target address space and applying memory protections,650since the memory manager must know how to communicate with the executor, and651since sharing and protection assignment can often be efficiently managed (in652the common case of running across processes on the same machine for security)653via the host operating system's virtual memory management APIs.654 655To satisfy these requirements ``JITLinkMemoryManager`` adopts the following656design: The memory manager itself has just two virtual methods for asynchronous657operations (each with convenience overloads for calling synchronously):658 659.. code-block:: c++660 661 /// Called when allocation has been completed.662 using OnAllocatedFunction =663 unique_function<void(Expected<std::unique_ptr<InFlightAlloc>)>;664 665 /// Called when deallocation has completed.666 using OnDeallocatedFunction = unique_function<void(Error)>;667 668 /// Call to allocate memory.669 virtual void allocate(const JITLinkDylib *JD, LinkGraph &G,670 OnAllocatedFunction OnAllocated) = 0;671 672 /// Call to deallocate memory.673 virtual void deallocate(std::vector<FinalizedAlloc> Allocs,674 OnDeallocatedFunction OnDeallocated) = 0;675 676The ``allocate`` method takes a ``JITLinkDylib*`` representing the target677simulated dylib, a reference to the ``LinkGraph`` that must be allocated for,678and a callback to run once an ``InFlightAlloc`` has been constructed.679``JITLinkMemoryManager`` implementations can (optionally) use the ``JD``680argument to manage a per-simulated-dylib memory pool (since code model681constraints are typically imposed on a per-dylib basis, and not across682dylibs) [2]_. The ``LinkGraph`` describes the object file that we need to683allocate memory for. The allocator must allocate working memory for all of684the Blocks defined in the graph, assign address space for each Block within the685executing processes memory, and update the Blocks' addresses to reflect this686assignment. Block content should be copied to working memory, but does not need687to be transferred to executor memory yet (that will be done once the content is688fixed up). ``JITLinkMemoryManager`` implementations can take full689responsibility for these steps, or use the ``BasicLayout`` utility to reduce690the task to allocating working and executor memory for *segments*: chunks of691memory defined by permissions, alignments, content sizes, and zero-fill sizes.692Once the allocation step is complete the memory manager should construct an693``InFlightAlloc`` object to represent the allocation, and then pass this object694to the ``OnAllocated`` callback.695 696The ``InFlightAlloc`` object has two virtual methods:697 698.. code-block:: c++699 700 using OnFinalizedFunction = unique_function<void(Expected<FinalizedAlloc>)>;701 using OnAbandonedFunction = unique_function<void(Error)>;702 703 /// Called prior to finalization if the allocation should be abandoned.704 virtual void abandon(OnAbandonedFunction OnAbandoned) = 0;705 706 /// Called to transfer working memory to the target and apply finalization.707 virtual void finalize(OnFinalizedFunction OnFinalized) = 0;708 709The linking process will call the ``finalize`` method on the ``InFlightAlloc``710object if linking succeeds up to the finalization step, otherwise it will call711``abandon`` to indicate that some error occurred during linking. A call to the712``InFlightAlloc::finalize`` method should cause content for the allocation to be713transferred from working to executor memory, and permissions to be run. A call714to ``abandon`` should result in both kinds of memory being deallocated.715 716On successful finalization, the ``InFlightAlloc::finalize`` method should717construct a ``FinalizedAlloc`` object (an opaque uint64_t id that the718``JITLinkMemoryManager`` can use to identify executor memory for deallocation)719and pass it to the ``OnFinalized`` callback.720 721Finalized allocations (represented by ``FinalizedAlloc`` objects) can be722deallocated by calling the ``JITLinkMemoryManager::dealloc`` method. This method723takes a vector of ``FinalizedAlloc`` objects, since it is common to deallocate724multiple objects at the same time and this allows us to batch these requests for725transmission to the executing process.726 727JITLink provides a simple in-process implementation of this interface:728``InProcessMemoryManager``. It allocates pages once and re-uses them as both729working and target memory.730 731ORC provides a cross-process-capable ``MapperJITLinkMemoryManager`` that can use732shared memory or ORC-RPC-based communication to transfer content to the executing733process.734 735JITLinkMemoryManager and Security736---------------------------------737 738JITLink's ability to link JIT'd code for a separate executor process can be739used to improve the security of a JIT system: The executor process can be740sandboxed, run within a VM, or even run on a fully separate machine.741 742JITLink's memory manager interface is flexible enough to allow for a range of743trade-offs between performance and security. For example, on a system where code744pages must be signed (preventing code from being updated), the memory manager745can deallocate working memory pages after linking to free memory in the process746running JITLink. Alternatively, on a system that allows RWX pages, the memory747manager may use the same pages for both working and target memory by marking748them as RWX, allowing code to be modified in place without further overhead.749Finally, if RWX pages are not permitted but dual-virtual-mappings of750physical memory pages are, then the memory manager can dual map physical pages751as RW- in the JITLink process and R-X in the executor process, allowing752modification from the JITLink process but not from the executor (at the cost of753extra administrative overhead for the dual mapping).754 755Error Handling756--------------757 758JITLink makes extensive use of the ``llvm::Error`` type (see the error handling759section of :doc:`ProgrammersManual` for details). The link process itself, all760passes, the memory manager interface, and operations on the ``JITLinkContext``761are all permitted to fail. Link graph construction utilities (especially parsers762for object formats) are encouraged to validate input, and validate fixups763(e.g. with range checks) before application.764 765Any error will halt the link process and notify the context of failure. In ORC,766reported failures are propagated to queries pending on definitions provided by767the failing link, and also through edges of the dependence graph to any queries768waiting on dependent symbols.769 770.. _connection_to_orc_runtime:771 772Connection to the ORC Runtime773=============================774 775The ORC Runtime (currently under development) aims to provide runtime support776for advanced JIT features, including object format features that require777non-trivial action in the executor (e.g. running initializers, managing thread778local storage, registering with language runtimes, etc.).779 780ORC Runtime support for object format features typically requires cooperation781between the runtime (which executes in the executor process) and JITLink (which782runs in the JIT process and can inspect LinkGraphs to determine what actions783must be taken in the executor). For example: Execution of MachO static784initializers in the ORC runtime is performed by the ``jit_dlopen`` function,785which calls back to the JIT process to ask for the list of address ranges of786``__mod_init`` sections to walk. This list is collated by the787``MachOPlatformPlugin``, which installs a pass to record this information for788each object as it is linked into the target.789 790.. _constructing_linkgraphs:791 792Constructing LinkGraphs793=======================794 795Clients usually access and manipulate ``LinkGraph`` instances that were created796for them by an ``ObjectLinkingLayer`` instance, but they can be created manually:797 798#. By directly constructing and populating a ``LinkGraph`` instance.799 800#. By using the ``createLinkGraph`` family of functions to create a801 ``LinkGraph`` from an in-memory buffer containing an object file. This is how802 ``ObjectLinkingLayer`` usually creates ``LinkGraphs``.803 804 #. ``createLinkGraph_<Object-Format>_<Architecture>`` can be used when805 both the object format and architecture are known ahead of time.806 807 #. ``createLinkGraph_<Object-Format>`` can be used when the object format is808 known ahead of time, but the architecture is not. In this case the809 architecture will be determined by inspection of the object header.810 811 #. ``createLinkGraph`` can be used when neither the object format nor812 the architecture are known ahead of time. In this case the object header813 will be inspected to determine both the format and architecture.814 815.. _jit_linking:816 817JIT Linking818===========819 820The JIT linker concept was introduced in LLVM's earlier generation of JIT APIs,821MCJIT. In MCJIT the *RuntimeDyld* component enabled re-use of LLVM as an822in-memory compiler by adding an in-memory link step to the end of the usual823compiler pipeline. Rather than dumping relocatable objects to disk as a compiler824usually would, MCJIT passed them to RuntimeDyld to be linked into a target825process.826 827This approach to linking differs from standard *static* or *dynamic* linking:828 829A *static linker* takes one or more relocatable object files as input and links830them into an executable or dynamic library on disk.831 832A *dynamic linker* applies relocations to executables and dynamic libraries that833have been loaded into memory.834 835A *JIT linker* takes a single relocatable object file at a time and links it836into a target process, usually using a context object to allow the linked code837to resolve symbols in the target.838 839RuntimeDyld840-----------841 842In order to keep RuntimeDyld's implementation simple MCJIT imposed some843restrictions on compiled code:844 845#. It had to use the Large code model, and often restricted available relocation846 models in order to limit the kinds of relocations that had to be supported.847 848#. It required strong linkage and default visibility on all symbols -- behavior849 for other linkages/visibilities was not well defined.850 851#. It constrained and/or prohibited the use of features requiring runtime852 support, e.g. static initializers or thread local storage.853 854As a result of these restrictions not all language features supported by LLVM855worked under MCJIT, and objects to be loaded under the JIT had to be compiled to856target it (precluding the use of precompiled code from other sources under the857JIT).858 859RuntimeDyld also provided very limited visibility into the linking process860itself: Clients could access conservative estimates of section size861(RuntimeDyld bundled stub size and padding estimates into the section size862value) and the final relocated bytes, but could not access RuntimeDyld's863internal object representations.864 865Eliminating these restrictions and limitations was one of the primary motivations866for the development of JITLink.867 868The llvm-jitlink tool869=====================870 871The ``llvm-jitlink`` tool is a command line wrapper for the JITLink library.872It loads some set of relocatable object files and then links them using873JITLink. Depending on the options used it will then execute them, or validate874the linked memory.875 876The ``llvm-jitlink`` tool was originally designed to aid JITLink development by877providing a simple environment for testing.878 879Basic usage880-----------881 882By default, ``llvm-jitlink`` will link the set of objects passed on the command883line, then search for a "main" function and execute it:884 885.. code-block:: sh886 887 % cat hello-world.c888 #include <stdio.h>889 890 int main(int argc, char *argv[]) {891 printf("hello, world!\n");892 return 0;893 }894 895 % clang -c -o hello-world.o hello-world.c896 % llvm-jitlink hello-world.o897 Hello, World!898 899Multiple objects may be specified, and arguments may be provided to the JIT'd900main function using the -args option:901 902.. code-block:: sh903 904 % cat print-args.c905 #include <stdio.h>906 907 void print_args(int argc, char *argv[]) {908 for (int i = 0; i != argc; ++i)909 printf("arg %i is \"%s\"\n", i, argv[i]);910 }911 912 % cat print-args-main.c913 void print_args(int argc, char *argv[]);914 915 int main(int argc, char *argv[]) {916 print_args(argc, argv);917 return 0;918 }919 920 % clang -c -o print-args.o print-args.c921 % clang -c -o print-args-main.o print-args-main.c922 % llvm-jitlink print-args.o print-args-main.o -args a b c923 arg 0 is "a"924 arg 1 is "b"925 arg 2 is "c"926 927Alternative entry points may be specified using the ``-entry <entry point928name>`` option.929 930Other options can be found by calling ``llvm-jitlink -help``.931 932llvm-jitlink as a regression testing utility933--------------------------------------------934 935One of the primary aims of ``llvm-jitlink`` was to enable readable regression936tests for JITLink. To do this it supports two options:937 938The ``-noexec`` option tells llvm-jitlink to stop after looking up the entry939point, and before attempting to execute it. Since the linked code is not940executed, this can be used to link for other targets even if you do not have941access to the target being linked (the ``-define-abs`` or ``-phony-externals``942options can be used to supply any missing definitions in this case).943 944The ``-check <check-file>`` option can be used to run a set of ``jitlink-check``945expressions against working memory. It is typically used in conjunction with946``-noexec``, since the aim is to validate JIT'd memory rather than to run the947code and ``-noexec`` allows us to link for any supported target architecture948from the current process. In ``-check`` mode, ``llvm-jitlink`` will scan the949given check-file for lines of the form ``# jitlink-check: <expr>``. See950examples of this usage in ``llvm/test/ExecutionEngine/JITLink``.951 952Remote execution via llvm-jitlink-executor953------------------------------------------954 955By default ``llvm-jitlink`` will link the given objects into its own process,956but this can be overridden by two options:957 958The ``-oop-executor[=/path/to/executor]`` option tells ``llvm-jitlink`` to959execute the given executor (which defaults to ``llvm-jitlink-executor``) and960communicate with it via file descriptors which it passes to the executor961as the first argument with the format ``filedescs=<in-fd>,<out-fd>``.962 963The ``-oop-executor-connect=<host>:<port>`` option tells ``llvm-jitlink`` to964connect to an already running executor via TCP on the given host and port. To965use this option you will need to start ``llvm-jitlink-executor`` manually with966``listen=<host>:<port>`` as the first argument.967 968Harness mode969------------970 971The ``-harness`` option allows a set of input objects to be designated as a test972harness, with the regular object files implicitly treated as objects to be973tested. Definitions of symbols in the harness set override definitions in the974test set, and external references from the harness cause automatic scope975promotion of local symbols in the test set (these modifications to the usual976linker rules are accomplished via an ``ObjectLinkingLayer::Plugin`` installed by977``llvm-jitlink`` when it sees the ``-harness`` option).978 979With these modifications in place we can selectively test functions in an object980file by mocking those function's callees. For example, suppose we have an object981file, ``test_code.o``, compiled from the following C source (which we need not982have access to):983 984.. code-block:: c985 986 void irrelevant_function() { irrelevant_external(); }987 988 int function_to_mock(int X) {989 return /* some function of X */;990 }991 992 static void function_to_test() {993 ...994 int Y = function_to_mock();995 printf("Y is %i\n", Y);996 }997 998If we want to know how ``function_to_test`` behaves when we change the behavior999of ``function_to_mock`` we can test it by writing a test harness:1000 1001.. code-block:: c1002 1003 void function_to_test();1004 1005 int function_to_mock(int X) {1006 printf("used mock utility function\n");1007 return 42;1008 }1009 1010 int main(int argc, char *argv[]) {1011 function_to_test():1012 return 0;1013 }1014 1015Under normal circumstances these objects could not be linked together:1016``function_to_test`` is static and could not be resolved outside1017``test_code.o``, the two ``function_to_mock`` functions would result in a1018duplicate definition error, and ``irrelevant_external`` is undefined.1019However, using ``-harness`` and ``-phony-externals`` we can run this code1020with:1021 1022.. code-block:: sh1023 1024 % clang -c -o test_code_harness.o test_code_harness.c1025 % llvm-jitlink -phony-externals test_code.o -harness test_code_harness.o1026 used mock utility function1027 Y is 421028 1029The ``-harness`` option may be of interest to people who want to perform some1030very late testing on build products to verify that compiled code behaves as1031expected. On basic C test cases this is relatively straightforward. Mocks for1032more complicated languages (e.g. C++) are much trickier: Any code involving1033classes tends to have a lot of non-trivial surface area (e.g. vtables) that1034would require great care to mock.1035 1036Tips for JITLink backend developers1037-----------------------------------1038 1039#. Make liberal use of assert and ``llvm::Error``. Do *not* assume that the input1040 object is well formed: Return any errors produced by libObject (or your own1041 object parsing code) and validate as you construct. Think carefully about the1042 distinction between contract (which should be validated with asserts and1043 llvm_unreachable) and environmental errors (which should generate1044 ``llvm::Error`` instances).1045 1046#. Don't assume you're linking in-process. Use libSupport's sized,1047 endian-specific types when reading/writing content in the ``LinkGraph``.1048 1049As a "minimum viable" JITLink wrapper, the ``llvm-jitlink`` tool is an1050invaluable resource for developers bringing in a new JITLink backend. A standard1051workflow is to start by throwing an unsupported object at the tool and seeing1052what error is returned, then fixing that (you can often make a reasonable guess1053at what should be done based on existing code for other formats or1054architectures).1055 1056In debug builds of LLVM, the ``-debug-only=jitlink`` option dumps logs from the1057JITLink library during the link process. These can be useful for spotting some bugs at1058a glance. The ``-debug-only=llvm_jitlink`` option dumps logs from the ``llvm-jitlink``1059tool, which can be useful for debugging both testcases (it is often less verbose than1060``-debug-only=jitlink``) and the tool itself.1061 1062The ``-oop-executor`` and ``-oop-executor-connect`` options are helpful for testing1063handling of cross-process and cross-architecture use cases.1064 1065Roadmap1066=======1067 1068JITLink is under active development. Work so far has focused on the MachO1069implementation. In LLVM 12 there is limited support for ELF on x86-64.1070 1071Major outstanding projects include:1072 1073* Refactor architecture support to maximize sharing across formats.1074 1075 All formats should be able to share the bulk of the architecture-specific1076 code (especially relocations) for each supported architecture.1077 1078* Refactor ELF link graph construction.1079 1080 ELF's link graph construction is currently implemented in the `ELF_x86_64.cpp`1081 file, and tied to the x86-64 relocation parsing code. The bulk of the code is1082 generic and should be split into an ELFLinkGraphBuilder base class along the1083 same lines as the existing generic MachOLinkGraphBuilder.1084 1085* Implement support for arm32.1086 1087* Implement support for other new architectures.1088 1089JITLink Availability and Feature Status1090---------------------------------------1091 1092The following table describes the status of the JITlink backends for various1093format / architecture combinations (as of July 2023).1094 1095Support levels:1096 1097* None: No backend. JITLink will return an "architecture not supported" error.1098 Represented by empty cells in the table below.1099* Skeleton: A backend exists, but does not support commonly used relocations.1100 Even simple programs are likely to trigger an "unsupported relocation" error.1101 Backends in this state may be easy to improve by implementing new relocations.1102 Consider getting involved!1103* Basic: The backend supports simple programs, isn't ready for general use yet.1104* Usable: The backend is useable for general use for at least one code and1105 relocation model.1106* Good: The backend supports almost all relocations. Advanced features like1107 native thread local storage may not be available yet.1108* Complete: The backend supports all relocations and object format features.1109 1110.. list-table:: Availability and Status1111 :widths: 10 30 30 301112 :header-rows: 11113 :stub-columns: 11114 1115 * - Architecture1116 - ELF1117 - COFF1118 - MachO1119 * - arm321120 - Skeleton1121 -1122 -1123 * - arm641124 - Usable1125 -1126 - Good1127 * - LoongArch1128 - Good1129 -1130 -1131 * - PowerPC 641132 - Usable1133 -1134 -1135 * - RISC-V1136 - Good1137 -1138 -1139 * - x86-321140 - Basic1141 -1142 -1143 * - x86-641144 - Good1145 - Usable1146 - Good1147 1148.. [1] See ``llvm/examples/OrcV2Examples/LLJITWithObjectLinkingLayerPlugin`` for1149 a full worked example.1150 1151.. [2] If not for *hidden* scoped symbols we could eliminate the1152 ``JITLinkDylib*`` argument to ``JITLinkMemoryManager::allocate`` and1153 treat every object as a separate simulated dylib for the purposes of1154 memory layout. Hidden symbols break this by generating in-range accesses1155 to external symbols, requiring the access and symbol to be allocated1156 within range of one another. That said, providing a pre-reserved address1157 range pool for each simulated dylib guarantees that the relaxation1158 optimizations will kick in for all intra-dylib references, which is good1159 for performance (at the cost of whatever overhead is introduced by1160 reserving the address-range up-front).1161