Home | History | Annotate | Download | only in RuntimeDyld
      1 //===-- RuntimeDyldImpl.h - Run-time dynamic linker for MC-JIT ------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // Interface for the implementations of runtime dynamic linker facilities.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_RUNTIME_DYLD_IMPL_H
     15 #define LLVM_RUNTIME_DYLD_IMPL_H
     16 
     17 #include "llvm/ExecutionEngine/RuntimeDyld.h"
     18 #include "llvm/Object/MachOObject.h"
     19 #include "llvm/ADT/StringMap.h"
     20 #include "llvm/ADT/Twine.h"
     21 #include "llvm/ADT/SmallVector.h"
     22 #include "llvm/ExecutionEngine/ExecutionEngine.h"
     23 #include "llvm/Support/Format.h"
     24 #include "llvm/Support/Memory.h"
     25 #include "llvm/Support/MemoryBuffer.h"
     26 #include "llvm/Support/system_error.h"
     27 #include "llvm/Support/raw_ostream.h"
     28 #include "llvm/Support/Debug.h"
     29 #include "llvm/Support/ErrorHandling.h"
     30 
     31 using namespace llvm;
     32 using namespace llvm::object;
     33 
     34 namespace llvm {
     35 class RuntimeDyldImpl {
     36 protected:
     37   unsigned CPUType;
     38   unsigned CPUSubtype;
     39 
     40   // The MemoryManager to load objects into.
     41   RTDyldMemoryManager *MemMgr;
     42 
     43   // FIXME: This all assumes we're dealing with external symbols for anything
     44   //        explicitly referenced. I.e., we can index by name and things
     45   //        will work out. In practice, this may not be the case, so we
     46   //        should find a way to effectively generalize.
     47 
     48   // For each function, we have a MemoryBlock of it's instruction data.
     49   StringMap<sys::MemoryBlock> Functions;
     50 
     51   // Master symbol table. As modules are loaded and external symbols are
     52   // resolved, their addresses are stored here.
     53   StringMap<uint8_t*> SymbolTable;
     54 
     55   bool HasError;
     56   std::string ErrorStr;
     57 
     58   // Set the error state and record an error string.
     59   bool Error(const Twine &Msg) {
     60     ErrorStr = Msg.str();
     61     HasError = true;
     62     return true;
     63   }
     64 
     65   void extractFunction(StringRef Name, uint8_t *StartAddress,
     66                        uint8_t *EndAddress);
     67 
     68 public:
     69   RuntimeDyldImpl(RTDyldMemoryManager *mm) : MemMgr(mm), HasError(false) {}
     70 
     71   virtual ~RuntimeDyldImpl();
     72 
     73   virtual bool loadObject(MemoryBuffer *InputBuffer) = 0;
     74 
     75   void *getSymbolAddress(StringRef Name) {
     76     // FIXME: Just look up as a function for now. Overly simple of course.
     77     // Work in progress.
     78     return SymbolTable.lookup(Name);
     79   }
     80 
     81   void resolveRelocations();
     82 
     83   virtual void reassignSymbolAddress(StringRef Name, uint8_t *Addr) = 0;
     84 
     85   // Is the linker in an error state?
     86   bool hasError() { return HasError; }
     87 
     88   // Mark the error condition as handled and continue.
     89   void clearError() { HasError = false; }
     90 
     91   // Get the error message.
     92   StringRef getErrorString() { return ErrorStr; }
     93 
     94   virtual bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const = 0;
     95 };
     96 
     97 
     98 class RuntimeDyldMachO : public RuntimeDyldImpl {
     99 
    100   // For each symbol, keep a list of relocations based on it. Anytime
    101   // its address is reassigned (the JIT re-compiled the function, e.g.),
    102   // the relocations get re-resolved.
    103   struct RelocationEntry {
    104     std::string Target;     // Object this relocation is contained in.
    105     uint64_t    Offset;     // Offset into the object for the relocation.
    106     uint32_t    Data;       // Second word of the raw macho relocation entry.
    107     int64_t     Addend;     // Addend encoded in the instruction itself, if any.
    108     bool        isResolved; // Has this relocation been resolved previously?
    109 
    110     RelocationEntry(StringRef t, uint64_t offset, uint32_t data, int64_t addend)
    111       : Target(t), Offset(offset), Data(data), Addend(addend),
    112         isResolved(false) {}
    113   };
    114   typedef SmallVector<RelocationEntry, 4> RelocationList;
    115   StringMap<RelocationList> Relocations;
    116 
    117   // FIXME: Also keep a map of all the relocations contained in an object. Use
    118   // this to dynamically answer whether all of the relocations in it have
    119   // been resolved or not.
    120 
    121   bool resolveRelocation(uint8_t *Address, uint8_t *Value, bool isPCRel,
    122                          unsigned Type, unsigned Size);
    123   bool resolveX86_64Relocation(uintptr_t Address, uintptr_t Value, bool isPCRel,
    124                                unsigned Type, unsigned Size);
    125   bool resolveARMRelocation(uintptr_t Address, uintptr_t Value, bool isPCRel,
    126                             unsigned Type, unsigned Size);
    127 
    128   bool loadSegment32(const MachOObject *Obj,
    129                      const MachOObject::LoadCommandInfo *SegmentLCI,
    130                      const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC);
    131   bool loadSegment64(const MachOObject *Obj,
    132                      const MachOObject::LoadCommandInfo *SegmentLCI,
    133                      const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC);
    134 
    135 public:
    136   RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
    137 
    138   bool loadObject(MemoryBuffer *InputBuffer);
    139 
    140   void reassignSymbolAddress(StringRef Name, uint8_t *Addr);
    141 
    142   static bool isKnownFormat(const MemoryBuffer *InputBuffer);
    143 
    144   bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const {
    145     return isKnownFormat(InputBuffer);
    146   }
    147 };
    148 
    149 } // end namespace llvm
    150 
    151 
    152 #endif
    153