Home | History | Annotate | Line # | Download | only in llvm-jitlink
      1 //===---- llvm-jitlink.h - Session and format-specific decls ----*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // llvm-jitlink Session class and tool utilities.
     10 //
     11 //===----------------------------------------------------------------------===//
     12 
     13 #ifndef LLVM_TOOLS_LLVM_JITLINK_LLVM_JITLINK_H
     14 #define LLVM_TOOLS_LLVM_JITLINK_LLVM_JITLINK_H
     15 
     16 #include "llvm/ADT/Optional.h"
     17 #include "llvm/ADT/StringSet.h"
     18 #include "llvm/ADT/Triple.h"
     19 #include "llvm/ExecutionEngine/Orc/Core.h"
     20 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
     21 #include "llvm/ExecutionEngine/Orc/OrcRPCTargetProcessControl.h"
     22 #include "llvm/ExecutionEngine/Orc/Shared/FDRawByteChannel.h"
     23 #include "llvm/ExecutionEngine/Orc/Shared/RPCUtils.h"
     24 #include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
     25 #include "llvm/ExecutionEngine/RuntimeDyldChecker.h"
     26 #include "llvm/Support/Error.h"
     27 #include "llvm/Support/Regex.h"
     28 #include "llvm/Support/raw_ostream.h"
     29 
     30 #include <vector>
     31 
     32 namespace llvm {
     33 
     34 struct Session;
     35 
     36 /// ObjectLinkingLayer with additional support for symbol promotion.
     37 class LLVMJITLinkObjectLinkingLayer : public orc::ObjectLinkingLayer {
     38 public:
     39   using orc::ObjectLinkingLayer::add;
     40 
     41   LLVMJITLinkObjectLinkingLayer(Session &S,
     42                                 jitlink::JITLinkMemoryManager &MemMgr);
     43 
     44   Error add(orc::ResourceTrackerSP RT,
     45             std::unique_ptr<MemoryBuffer> O) override;
     46 
     47 private:
     48   Session &S;
     49 };
     50 
     51 using LLVMJITLinkChannel = orc::shared::FDRawByteChannel;
     52 using LLVMJITLinkRPCEndpoint =
     53     orc::shared::MultiThreadedRPCEndpoint<LLVMJITLinkChannel>;
     54 using LLVMJITLinkRemoteMemoryAccess =
     55     orc::OrcRPCTPCMemoryAccess<LLVMJITLinkRPCEndpoint>;
     56 
     57 class LLVMJITLinkRemoteTargetProcessControl
     58     : public orc::OrcRPCTargetProcessControlBase<LLVMJITLinkRPCEndpoint> {
     59 public:
     60   using BaseT = orc::OrcRPCTargetProcessControlBase<LLVMJITLinkRPCEndpoint>;
     61   static Expected<std::unique_ptr<TargetProcessControl>> LaunchExecutor();
     62 
     63   static Expected<std::unique_ptr<TargetProcessControl>> ConnectToExecutor();
     64 
     65   Error disconnect() override;
     66 
     67 private:
     68   using LLVMJITLinkRemoteMemoryAccess =
     69       orc::OrcRPCTPCMemoryAccess<LLVMJITLinkRemoteTargetProcessControl>;
     70 
     71   using LLVMJITLinkRemoteMemoryManager =
     72       orc::OrcRPCTPCJITLinkMemoryManager<LLVMJITLinkRemoteTargetProcessControl>;
     73 
     74   LLVMJITLinkRemoteTargetProcessControl(
     75       std::shared_ptr<orc::SymbolStringPool> SSP,
     76       std::unique_ptr<LLVMJITLinkChannel> Channel,
     77       std::unique_ptr<LLVMJITLinkRPCEndpoint> Endpoint,
     78       ErrorReporter ReportError, Error &Err)
     79       : BaseT(std::move(SSP), *Endpoint, std::move(ReportError)),
     80         Channel(std::move(Channel)), Endpoint(std::move(Endpoint)) {
     81     ErrorAsOutParameter _(&Err);
     82 
     83     ListenerThread = std::thread([&]() {
     84       while (!Finished) {
     85         if (auto Err = this->Endpoint->handleOne()) {
     86           reportError(std::move(Err));
     87           return;
     88         }
     89       }
     90     });
     91 
     92     if (auto Err2 = initializeORCRPCTPCBase()) {
     93       Err = joinErrors(std::move(Err2), disconnect());
     94       return;
     95     }
     96 
     97     OwnedMemAccess = std::make_unique<LLVMJITLinkRemoteMemoryAccess>(*this);
     98     MemAccess = OwnedMemAccess.get();
     99     OwnedMemMgr = std::make_unique<LLVMJITLinkRemoteMemoryManager>(*this);
    100     MemMgr = OwnedMemMgr.get();
    101   }
    102 
    103   std::unique_ptr<LLVMJITLinkChannel> Channel;
    104   std::unique_ptr<LLVMJITLinkRPCEndpoint> Endpoint;
    105   std::unique_ptr<TargetProcessControl::MemoryAccess> OwnedMemAccess;
    106   std::unique_ptr<jitlink::JITLinkMemoryManager> OwnedMemMgr;
    107   std::atomic<bool> Finished{false};
    108   std::thread ListenerThread;
    109 };
    110 
    111 struct Session {
    112   std::unique_ptr<orc::TargetProcessControl> TPC;
    113   orc::ExecutionSession ES;
    114   orc::JITDylib *MainJD;
    115   LLVMJITLinkObjectLinkingLayer ObjLayer;
    116   std::vector<orc::JITDylib *> JDSearchOrder;
    117 
    118   ~Session();
    119 
    120   static Expected<std::unique_ptr<Session>> Create(Triple TT);
    121   void dumpSessionInfo(raw_ostream &OS);
    122   void modifyPassConfig(const Triple &FTT,
    123                         jitlink::PassConfiguration &PassConfig);
    124 
    125   using MemoryRegionInfo = RuntimeDyldChecker::MemoryRegionInfo;
    126 
    127   struct FileInfo {
    128     StringMap<MemoryRegionInfo> SectionInfos;
    129     StringMap<MemoryRegionInfo> StubInfos;
    130     StringMap<MemoryRegionInfo> GOTEntryInfos;
    131   };
    132 
    133   using SymbolInfoMap = StringMap<MemoryRegionInfo>;
    134   using FileInfoMap = StringMap<FileInfo>;
    135 
    136   Expected<FileInfo &> findFileInfo(StringRef FileName);
    137   Expected<MemoryRegionInfo &> findSectionInfo(StringRef FileName,
    138                                                StringRef SectionName);
    139   Expected<MemoryRegionInfo &> findStubInfo(StringRef FileName,
    140                                             StringRef TargetName);
    141   Expected<MemoryRegionInfo &> findGOTEntryInfo(StringRef FileName,
    142                                                 StringRef TargetName);
    143 
    144   bool isSymbolRegistered(StringRef Name);
    145   Expected<MemoryRegionInfo &> findSymbolInfo(StringRef SymbolName,
    146                                               Twine ErrorMsgStem);
    147 
    148   SymbolInfoMap SymbolInfos;
    149   FileInfoMap FileInfos;
    150   uint64_t SizeBeforePruning = 0;
    151   uint64_t SizeAfterFixups = 0;
    152 
    153   StringSet<> HarnessFiles;
    154   StringSet<> HarnessExternals;
    155   StringSet<> HarnessDefinitions;
    156   DenseMap<StringRef, StringRef> CanonicalWeakDefs;
    157 
    158 private:
    159   Session(std::unique_ptr<orc::TargetProcessControl> TPC, Error &Err);
    160 };
    161 
    162 /// Record symbols, GOT entries, stubs, and sections for ELF file.
    163 Error registerELFGraphInfo(Session &S, jitlink::LinkGraph &G);
    164 
    165 /// Record symbols, GOT entries, stubs, and sections for MachO file.
    166 Error registerMachOGraphInfo(Session &S, jitlink::LinkGraph &G);
    167 
    168 } // end namespace llvm
    169 
    170 #endif // LLVM_TOOLS_LLVM_JITLINK_LLVM_JITLINK_H
    171