RuntimeDyld.cpp revision 234353
1105196Swollman//===-- RuntimeDyld.cpp - Run-time dynamic linker for MC-JIT ----*- C++ -*-===//
22742Swollman//
386464Swollman//                     The LLVM Compiler Infrastructure
42742Swollman//
52742Swollman// This file is distributed under the University of Illinois Open Source
62742Swollman// License. See LICENSE.TXT for details.
72742Swollman//
82742Swollman//===----------------------------------------------------------------------===//
92742Swollman//
1086222Swollman// Implementation of the MC-JIT runtime dynamic linker.
1186222Swollman//
122742Swollman//===----------------------------------------------------------------------===//
1358787Sru
142742Swollman#define DEBUG_TYPE "dyld"
152742Swollman#include "RuntimeDyldImpl.h"
162742Swollman#include "RuntimeDyldELF.h"
172742Swollman#include "RuntimeDyldMachO.h"
182742Swollman#include "llvm/Support/Path.h"
192742Swollman
2058787Sruusing namespace llvm;
2158787Sruusing namespace llvm::object;
2258787Sru
232742Swollman// Empty out-of-line virtual destructor as the key function.
242742SwollmanRTDyldMemoryManager::~RTDyldMemoryManager() {}
259908SwollmanRuntimeDyldImpl::~RuntimeDyldImpl() {}
262742Swollman
2730711Swollmannamespace llvm {
282742Swollman
299908Swollmannamespace {
302742Swollman  // Helper for extensive error checking in debug builds.
3158787Sru  error_code Check(error_code Err) {
3258787Sru    if (Err) {
3314343Swollman      report_fatal_error(Err.message());
3414343Swollman    }
3514343Swollman    return Err;
3614343Swollman  }
3714343Swollman} // end anonymous namespace
382742Swollman
399908Swollman// Resolve the relocations for all symbols we currently know about.
4020094Swollmanvoid RuntimeDyldImpl::resolveRelocations() {
4120094Swollman  // First, resolve relocations associated with external symbols.
4220094Swollman  resolveSymbols();
4320094Swollman
4420094Swollman  // Just iterate over the sections we have and resolve all the relocations
4520094Swollman  // in them. Gross overkill, but it gets the job done.
4620094Swollman  for (int i = 0, e = Sections.size(); i != e; ++i) {
4720094Swollman    reassignSectionAddress(i, Sections[i].LoadAddress);
4820094Swollman  }
4920094Swollman}
5020094Swollman
5120094Swollmanvoid RuntimeDyldImpl::mapSectionAddress(void *LocalAddress,
5220094Swollman                                        uint64_t TargetAddress) {
5358787Sru  for (unsigned i = 0, e = Sections.size(); i != e; ++i) {
5458787Sru    if (Sections[i].Address == LocalAddress) {
5521217Swollman      reassignSectionAddress(i, TargetAddress);
5621217Swollman      return;
5758787Sru    }
5858787Sru  }
592742Swollman  llvm_unreachable("Attempting to remap address of unknown section!");
6058787Sru}
6121217Swollman
6220094Swollmanbool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) {
6358787Sru  // FIXME: ObjectFile don't modify MemoryBuffer.
6458787Sru  //        It should use const MemoryBuffer as parameter.
6520094Swollman  OwningPtr<ObjectFile> obj(ObjectFile::createObjectFile(
662742Swollman                                       const_cast<MemoryBuffer*>(InputBuffer)));
679908Swollman  if (!obj)
682742Swollman    report_fatal_error("Unable to create object image from memory buffer!");
6914343Swollman
7014343Swollman  Arch = (Triple::ArchType)obj->getArch();
7114343Swollman
7214343Swollman  LocalSymbolMap LocalSymbols;     // Functions and data symbols from the
7314343Swollman                                   // object file.
7414343Swollman  ObjSectionToIDMap LocalSections; // Used sections from the object file
7564499Swollman  CommonSymbolMap   CommonSymbols; // Common symbols requiring allocation
7664499Swollman  uint64_t          CommonSize = 0;
7764499Swollman
7864499Swollman  error_code err;
7964499Swollman  // Parse symbols
8014343Swollman  DEBUG(dbgs() << "Parse symbols:\n");
812742Swollman  for (symbol_iterator i = obj->begin_symbols(), e = obj->end_symbols();
822742Swollman       i != e; i.increment(err)) {
832742Swollman    Check(err);
8458787Sru    object::SymbolRef::Type SymType;
852742Swollman    StringRef Name;
862742Swollman    Check(i->getType(SymType));
879908Swollman    Check(i->getName(Name));
882742Swollman
8958787Sru    uint32_t flags;
9058787Sru    Check(i->getFlags(flags));
9114343Swollman
9214343Swollman    bool isCommon = flags & SymbolRef::SF_Common;
9358787Sru    if (isCommon) {
9414343Swollman      // Add the common symbols to a list.  We'll allocate them all below.
9514343Swollman      uint64_t Size = 0;
9614343Swollman      Check(i->getSize(Size));
9758787Sru      CommonSize += Size;
9814343Swollman      CommonSymbols[*i] = Size;
9958787Sru    } else {
10058787Sru      if (SymType == object::SymbolRef::ST_Function ||
10158787Sru          SymType == object::SymbolRef::ST_Data) {
10214343Swollman        uint64_t FileOffset;
10358787Sru        StringRef sData;
10458787Sru        section_iterator si = obj->end_sections();
1052742Swollman        Check(i->getFileOffset(FileOffset));
1062742Swollman        Check(i->getSection(si));
10758787Sru        if (si == obj->end_sections()) continue;
10858787Sru        Check(si->getContents(sData));
10958787Sru        const uint8_t* SymPtr = (const uint8_t*)InputBuffer->getBufferStart() +
1102742Swollman                                (uintptr_t)FileOffset;
1112742Swollman        uintptr_t SectOffset = (uintptr_t)(SymPtr - (const uint8_t*)sData.begin());
1129908Swollman        unsigned SectionID =
1132742Swollman          findOrEmitSection(*si,
11414343Swollman                            SymType == object::SymbolRef::ST_Function,
11558787Sru                            LocalSections);
11614343Swollman        bool isGlobal = flags & SymbolRef::SF_Global;
11714343Swollman        LocalSymbols[Name.data()] = SymbolLoc(SectionID, SectOffset);
11858787Sru        DEBUG(dbgs() << "\tFileOffset: " << format("%p", (uintptr_t)FileOffset)
11958787Sru                     << " flags: " << flags
12014343Swollman                     << " SID: " << SectionID
12114343Swollman                     << " Offset: " << format("%p", SectOffset));
12258787Sru        if (isGlobal)
12343543Swollman          SymbolTable[Name] = SymbolLoc(SectionID, SectOffset);
1242742Swollman      }
1252742Swollman    }
12658787Sru    DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name << "\n");
1272742Swollman  }
1282742Swollman
1299908Swollman  // Allocate common symbols
1302742Swollman  if (CommonSize != 0)
13114343Swollman    emitCommonSymbols(CommonSymbols, CommonSize, LocalSymbols);
13214343Swollman
13314343Swollman  // Parse and proccess relocations
13414343Swollman  DEBUG(dbgs() << "Parse relocations:\n");
13514343Swollman  for (section_iterator si = obj->begin_sections(),
13614343Swollman       se = obj->end_sections(); si != se; si.increment(err)) {
13714343Swollman    Check(err);
13843543Swollman    bool isFirstRelocation = true;
13914343Swollman    unsigned SectionID = 0;
14014343Swollman    StubMap Stubs;
14158787Sru
14243543Swollman    for (relocation_iterator i = si->begin_relocations(),
1432742Swollman         e = si->end_relocations(); i != e; i.increment(err)) {
1442742Swollman      Check(err);
14558787Sru
1462742Swollman      // If it's first relocation in this section, find its SectionID
1472742Swollman      if (isFirstRelocation) {
1482742Swollman        SectionID = findOrEmitSection(*si, true, LocalSections);
1492742Swollman        DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");
15058787Sru        isFirstRelocation = false;
15158787Sru      }
15258787Sru
1538029Swollman      ObjRelocationInfo RI;
15414343Swollman      RI.SectionID = SectionID;
15514343Swollman      Check(i->getAdditionalInfo(RI.AdditionalInfo));
15675267Swollman      Check(i->getOffset(RI.Offset));
15775267Swollman      Check(i->getSymbol(RI.Symbol));
15875267Swollman      Check(i->getType(RI.Type));
15975267Swollman
16075267Swollman      DEBUG(dbgs() << "\t\tAddend: " << RI.AdditionalInfo
16175267Swollman                   << " Offset: " << format("%p", (uintptr_t)RI.Offset)
16275267Swollman                   << " Type: " << (uint32_t)(RI.Type & 0xffffffffL)
16375267Swollman                   << "\n");
16475267Swollman      processRelocationRef(RI, *obj, LocalSections, LocalSymbols, Stubs);
16575267Swollman    }
1662742Swollman  }
1672742Swollman  return false;
16814343Swollman}
1698029Swollman
17014343Swollmanunsigned RuntimeDyldImpl::emitCommonSymbols(const CommonSymbolMap &Map,
1712742Swollman                                            uint64_t TotalSize,
1722742Swollman                                            LocalSymbolMap &LocalSymbols) {
17314343Swollman  // Allocate memory for the section
17458787Sru  unsigned SectionID = Sections.size();
1752742Swollman  uint8_t *Addr = MemMgr->allocateDataSection(TotalSize, sizeof(void*),
17614343Swollman                                              SectionID);
17714343Swollman  if (!Addr)
17814343Swollman    report_fatal_error("Unable to allocate memory for common symbols!");
17914343Swollman  uint64_t Offset = 0;
18030711Swollman  Sections.push_back(SectionEntry(Addr, TotalSize, TotalSize, 0));
18130711Swollman  memset(Addr, 0, TotalSize);
18258787Sru
18358787Sru  DEBUG(dbgs() << "emitCommonSection SectionID: " << SectionID
1842742Swollman               << " new addr: " << format("%p", Addr)
18543014Swollman               << " DataSize: " << TotalSize
18643014Swollman               << "\n");
18743014Swollman
18843014Swollman  // Assign the address of each symbol
1892742Swollman  for (CommonSymbolMap::const_iterator it = Map.begin(), itEnd = Map.end();
1902742Swollman       it != itEnd; it++) {
19158787Sru    uint64_t Size = it->second;
1922742Swollman    StringRef Name;
19319878Swollman    it->first.getName(Name);
19443014Swollman    LocalSymbols[Name.data()] = SymbolLoc(SectionID, Offset);
19543014Swollman    Offset += Size;
1962742Swollman    Addr += Size;
1972742Swollman  }
19819878Swollman
19919878Swollman  return SectionID;
2002742Swollman}
2012742Swollman
2022742Swollmanunsigned RuntimeDyldImpl::emitSection(const SectionRef &Section,
2032742Swollman                                      bool IsCode) {
20419878Swollman
2052742Swollman  unsigned StubBufSize = 0,
2062742Swollman           StubSize = getMaxStubSize();
20743543Swollman  error_code err;
20875267Swollman  if (StubSize > 0) {
20975267Swollman    for (relocation_iterator i = Section.begin_relocations(),
2102742Swollman         e = Section.end_relocations(); i != e; i.increment(err), Check(err))
2112742Swollman      StubBufSize += StubSize;
21243543Swollman  }
2132742Swollman  StringRef data;
2142742Swollman  uint64_t Alignment64;
2152742Swollman  Check(Section.getContents(data));
2162742Swollman  Check(Section.getAlignment(Alignment64));
21719878Swollman
2182742Swollman  unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL;
21919878Swollman  bool IsRequired;
2202742Swollman  bool IsVirtual;
22119878Swollman  bool IsZeroInit;
22243014Swollman  uint64_t DataSize;
22343014Swollman  Check(Section.isRequiredForExecution(IsRequired));
2242742Swollman  Check(Section.isVirtual(IsVirtual));
2252742Swollman  Check(Section.isZeroInit(IsZeroInit));
2262742Swollman  Check(Section.getSize(DataSize));
22775267Swollman
22875267Swollman  unsigned Allocate;
22975267Swollman  unsigned SectionID = Sections.size();
23075267Swollman  uint8_t *Addr;
2312742Swollman  const char *pData = 0;
2322742Swollman
2332742Swollman  // Some sections, such as debug info, don't need to be loaded for execution.
2342742Swollman  // Leave those where they are.
23519878Swollman  if (IsRequired) {
2362742Swollman    Allocate = DataSize + StubBufSize;
23719878Swollman    Addr = IsCode
23819878Swollman      ? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID)
23919878Swollman      : MemMgr->allocateDataSection(Allocate, Alignment, SectionID);
2402742Swollman    if (!Addr)
24119878Swollman      report_fatal_error("Unable to allocate section memory!");
24219878Swollman
24319878Swollman    // Virtual sections have no data in the object image, so leave pData = 0
2442742Swollman    if (!IsVirtual)
24514343Swollman      pData = data.data();
24614343Swollman
24775267Swollman    // Zero-initialize or copy the data from the image
24875267Swollman    if (IsZeroInit || IsVirtual)
24919878Swollman      memset(Addr, 0, DataSize);
25075267Swollman    else
25175267Swollman      memcpy(Addr, pData, DataSize);
25214343Swollman
25314343Swollman    DEBUG(dbgs() << "emitSection SectionID: " << SectionID
25414343Swollman                 << " obj addr: " << format("%p", pData)
25514343Swollman                 << " new addr: " << format("%p", Addr)
25619878Swollman                 << " DataSize: " << DataSize
25719878Swollman                 << " StubBufSize: " << StubBufSize
25814343Swollman                 << " Allocate: " << Allocate
25919878Swollman                 << "\n");
26019878Swollman  }
26119878Swollman  else {
26214343Swollman    // Even if we didn't load the section, we need to record an entry for it
26314343Swollman    //   to handle later processing (and by 'handle' I mean don't do anything
26414343Swollman    //   with these sections).
26514343Swollman    Allocate = 0;
26619878Swollman    Addr = 0;
26719878Swollman    DEBUG(dbgs() << "emitSection SectionID: " << SectionID
26814343Swollman                 << " obj addr: " << format("%p", data.data())
26919878Swollman                 << " new addr: 0"
27014343Swollman                 << " DataSize: " << DataSize
27119878Swollman                 << " StubBufSize: " << StubBufSize
27214343Swollman                 << " Allocate: " << Allocate
27358787Sru                 << "\n");
27458787Sru  }
27558787Sru
27614343Swollman  Sections.push_back(SectionEntry(Addr, Allocate, DataSize,(uintptr_t)pData));
2772742Swollman  return SectionID;
2782742Swollman}
2792742Swollman
28019878Swollmanunsigned RuntimeDyldImpl::findOrEmitSection(const SectionRef &Section,
2812742Swollman                                            bool IsCode,
28219878Swollman                                            ObjSectionToIDMap &LocalSections) {
28319878Swollman
2842742Swollman  unsigned SectionID = 0;
2852742Swollman  ObjSectionToIDMap::iterator i = LocalSections.find(Section);
2862742Swollman  if (i != LocalSections.end())
28719878Swollman    SectionID = i->second;
28819878Swollman  else {
28943014Swollman    SectionID = emitSection(Section, IsCode);
29058787Sru    LocalSections[Section] = SectionID;
29143014Swollman  }
2922742Swollman  return SectionID;
2932742Swollman}
2942742Swollman
2952742Swollmanvoid RuntimeDyldImpl::AddRelocation(const RelocationValueRef &Value,
2962742Swollman                                   unsigned SectionID, uintptr_t Offset,
2972742Swollman                                   uint32_t RelType) {
2982742Swollman  DEBUG(dbgs() << "AddRelocation SymNamePtr: " << format("%p", Value.SymbolName)
2992742Swollman               << " SID: " << Value.SectionID
3002742Swollman               << " Addend: " << format("%p", Value.Addend)
3012742Swollman               << " Offset: " << format("%p", Offset)
3022742Swollman               << " RelType: " << format("%x", RelType)
3032742Swollman               << "\n");
30414343Swollman
3052742Swollman  if (Value.SymbolName == 0) {
30614343Swollman    Relocations[Value.SectionID].push_back(RelocationEntry(
30714343Swollman      SectionID,
3082742Swollman      Offset,
30914343Swollman      RelType,
31043014Swollman      Value.Addend));
31114343Swollman  } else
31214343Swollman    SymbolRelocations[Value.SymbolName].push_back(RelocationEntry(
31314343Swollman      SectionID,
3149908Swollman      Offset,
3159908Swollman      RelType,
3169908Swollman      Value.Addend));
3179908Swollman}
3189908Swollman
3199908Swollmanuint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr) {
3209908Swollman  // TODO: There is only ARM far stub now. We should add the Thumb stub,
32120094Swollman  // and stubs for branches Thumb - ARM and ARM - Thumb.
32220094Swollman  if (Arch == Triple::arm) {
3232742Swollman    uint32_t *StubAddr = (uint32_t*)Addr;
3242742Swollman    *StubAddr = 0xe51ff004; // ldr pc,<label>
32514343Swollman    return (uint8_t*)++StubAddr;
3262742Swollman  }
32720094Swollman  else
3282742Swollman    return Addr;
3298029Swollman}
33030711Swollman
33158787Sru// Assign an address to a symbol name and resolve all the relocations
33258787Sru// associated with it.
3332742Swollmanvoid RuntimeDyldImpl::reassignSectionAddress(unsigned SectionID,
33430711Swollman                                             uint64_t Addr) {
33558787Sru  // The address to use for relocation resolution is not
33658787Sru  // the address of the local section buffer. We must be doing
33758787Sru  // a remote execution environment of some sort. Re-apply any
33830711Swollman  // relocations referencing this section with the given address.
33930711Swollman  //
3402742Swollman  // Addr is a uint64_t because we can't assume the pointer width
3412742Swollman  // of the target is the same as that of the host. Just use a generic
3422742Swollman  // "big enough" type.
3432742Swollman  Sections[SectionID].LoadAddress = Addr;
3442742Swollman  DEBUG(dbgs() << "Resolving relocations Section #" << SectionID
3452742Swollman          << "\t" << format("%p", (uint8_t *)Addr)
34619878Swollman          << "\n");
34719878Swollman  resolveRelocationList(Relocations[SectionID], Addr);
34819878Swollman}
3492742Swollman
3502742Swollmanvoid RuntimeDyldImpl::resolveRelocationEntry(const RelocationEntry &RE,
3512742Swollman                                             uint64_t Value) {
3522742Swollman    // Ignore relocations for sections that were not loaded
35319878Swollman    if (Sections[RE.SectionID].Address != 0) {
35419878Swollman      uint8_t *Target = Sections[RE.SectionID].Address + RE.Offset;
3552742Swollman      DEBUG(dbgs() << "\tSectionID: " << RE.SectionID
35658787Sru            << " + " << RE.Offset << " (" << format("%p", Target) << ")"
3579908Swollman            << " Data: " << RE.Data
3589908Swollman            << " Addend: " << RE.Addend
35919878Swollman            << "\n");
3609908Swollman
3612742Swollman      resolveRelocation(Target, Sections[RE.SectionID].LoadAddress + RE.Offset,
3622742Swollman                        Value, RE.Data, RE.Addend);
3632742Swollman  }
36486222Swollman}
36519878Swollman
3662742Swollmanvoid RuntimeDyldImpl::resolveRelocationList(const RelocationList &Relocs,
3672742Swollman                                            uint64_t Value) {
3682742Swollman  for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
3692742Swollman    resolveRelocationEntry(Relocs[i], Value);
37058787Sru  }
37158787Sru}
3722742Swollman
37314343Swollman// resolveSymbols - Resolve any relocations to the specified symbols if
37414343Swollman// we know where it lives.
37514343Swollmanvoid RuntimeDyldImpl::resolveSymbols() {
37619878Swollman  StringMap<RelocationList>::iterator i = SymbolRelocations.begin(),
37714343Swollman                                      e = SymbolRelocations.end();
37814343Swollman  for (; i != e; i++) {
37914343Swollman    StringRef Name = i->first();
38014343Swollman    RelocationList &Relocs = i->second;
38114343Swollman    StringMap<SymbolLoc>::const_iterator Loc = SymbolTable.find(Name);
38214343Swollman    if (Loc == SymbolTable.end()) {
38314343Swollman      // This is an external symbol, try to get it address from
38419878Swollman      // MemoryManager.
38519878Swollman      uint8_t *Addr = (uint8_t*) MemMgr->getPointerToNamedFunction(Name.data(),
38614343Swollman                                                                   true);
3872742Swollman      DEBUG(dbgs() << "Resolving relocations Name: " << Name
3882742Swollman              << "\t" << format("%p", Addr)
3892742Swollman              << "\n");
3902742Swollman      resolveRelocationList(Relocs, (uintptr_t)Addr);
39119878Swollman    } else {
3922742Swollman      // Change the relocation to be section relative rather than symbol
3932742Swollman      // relative and move it to the resolved relocation list.
3942742Swollman      DEBUG(dbgs() << "Resolving symbol '" << Name << "'\n");
3952742Swollman      for (int i = 0, e = Relocs.size(); i != e; ++i) {
39619878Swollman        RelocationEntry Entry = Relocs[i];
3972742Swollman        Entry.Addend += Loc->second.second;
3982742Swollman        Relocations[Loc->second.first].push_back(Entry);
39958787Sru      }
40075267Swollman      Relocs.clear();
40175267Swollman    }
40293799Swollman  }
40393799Swollman}
4042742Swollman
4052742Swollman
40658787Sru//===----------------------------------------------------------------------===//
40758787Sru// RuntimeDyld class implementation
40858787SruRuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) {
4092742Swollman  Dyld = 0;
4102742Swollman  MM = mm;
4112742Swollman}
4122742Swollman
41319878SwollmanRuntimeDyld::~RuntimeDyld() {
4142742Swollman  delete Dyld;
41543014Swollman}
41643014Swollman
41743014Swollmanbool RuntimeDyld::loadObject(MemoryBuffer *InputBuffer) {
41843014Swollman  if (!Dyld) {
41943014Swollman    sys::LLVMFileType type = sys::IdentifyFileType(
42043014Swollman            InputBuffer->getBufferStart(),
42143014Swollman            static_cast<unsigned>(InputBuffer->getBufferSize()));
42243014Swollman    switch (type) {
42343014Swollman      case sys::ELF_Relocatable_FileType:
42443014Swollman      case sys::ELF_Executable_FileType:
42543014Swollman      case sys::ELF_SharedObject_FileType:
42643014Swollman      case sys::ELF_Core_FileType:
42743014Swollman        Dyld = new RuntimeDyldELF(MM);
42843014Swollman        break;
42943014Swollman      case sys::Mach_O_Object_FileType:
43043014Swollman      case sys::Mach_O_Executable_FileType:
43143014Swollman      case sys::Mach_O_FixedVirtualMemorySharedLib_FileType:
43243014Swollman      case sys::Mach_O_Core_FileType:
43343014Swollman      case sys::Mach_O_PreloadExecutable_FileType:
43443014Swollman      case sys::Mach_O_DynamicallyLinkedSharedLib_FileType:
43543014Swollman      case sys::Mach_O_DynamicLinker_FileType:
43643014Swollman      case sys::Mach_O_Bundle_FileType:
43743014Swollman      case sys::Mach_O_DynamicallyLinkedSharedLibStub_FileType:
43843014Swollman      case sys::Mach_O_DSYMCompanion_FileType:
43943014Swollman        Dyld = new RuntimeDyldMachO(MM);
44043014Swollman        break;
44143014Swollman      case sys::Unknown_FileType:
44243014Swollman      case sys::Bitcode_FileType:
44343014Swollman      case sys::Archive_FileType:
44443014Swollman      case sys::COFF_FileType:
44543014Swollman        report_fatal_error("Incompatible object format!");
44643014Swollman    }
44743014Swollman  } else {
4482742Swollman    if (!Dyld->isCompatibleFormat(InputBuffer))
4492742Swollman      report_fatal_error("Incompatible object format!");
45019878Swollman  }
45119878Swollman
45219878Swollman  return Dyld->loadObject(InputBuffer);
45320094Swollman}
45420094Swollman
45520094Swollmanvoid *RuntimeDyld::getSymbolAddress(StringRef Name) {
4562742Swollman  return Dyld->getSymbolAddress(Name);
4572742Swollman}
45819878Swollman
4592742Swollmanvoid RuntimeDyld::resolveRelocations() {
4602742Swollman  Dyld->resolveRelocations();
4612742Swollman}
4622742Swollman
46319878Swollmanvoid RuntimeDyld::reassignSectionAddress(unsigned SectionID,
4642742Swollman                                         uint64_t Addr) {
4652742Swollman  Dyld->reassignSectionAddress(SectionID, Addr);
4662742Swollman}
4672742Swollman
4682742Swollmanvoid RuntimeDyld::mapSectionAddress(void *LocalAddress,
4692742Swollman                                    uint64_t TargetAddress) {
4702742Swollman  Dyld->mapSectionAddress(LocalAddress, TargetAddress);
4712742Swollman}
4722742Swollman
47358787SruStringRef RuntimeDyld::getErrorString() {
4742742Swollman  return Dyld->getErrorString();
47558787Sru}
47658787Sru
4772742Swollman} // end namespace llvm
47886222Swollman