RuntimeDyld.cpp revision 354362524a72b3fa43a6c09380b7ae3b2380cbba
1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski//===-- RuntimeDyld.cpp - Run-time dynamic linker for MC-JIT ----*- C++ -*-===// 2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// The LLVM Compiler Infrastructure 4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// This file is distributed under the University of Illinois Open Source 6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// License. See LICENSE.TXT for details. 7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski//===----------------------------------------------------------------------===// 9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Implementation of the MC-JIT runtime dynamic linker. 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski//===----------------------------------------------------------------------===// 13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#define DEBUG_TYPE "dyld" 15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "llvm/ExecutionEngine/RuntimeDyld.h" 16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "JITRegistrar.h" 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "ObjectImageCommon.h" 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "RuntimeDyldELF.h" 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "RuntimeDyldImpl.h" 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "RuntimeDyldMachO.h" 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "llvm/Support/FileSystem.h" 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "llvm/Support/MathExtras.h" 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "llvm/Support/MutexGuard.h" 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "llvm/Object/ELF.h" 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiusing namespace llvm; 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiusing namespace llvm::object; 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Empty out-of-line virtual destructor as the key function. 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiRuntimeDyldImpl::~RuntimeDyldImpl() {} 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Pin the JITRegistrar's and ObjectImage*'s vtables to this file. 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid JITRegistrar::anchor() {} 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ObjectImage::anchor() {} 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ObjectImageCommon::anchor() {} 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskinamespace llvm { 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid RuntimeDyldImpl::registerEHFrames() { 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid RuntimeDyldImpl::deregisterEHFrames() { 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Resolve the relocations for all symbols we currently know about. 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid RuntimeDyldImpl::resolveRelocations() { 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MutexGuard locked(lock); 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // First, resolve relocations associated with external symbols. 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resolveExternalSymbols(); 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Just iterate over the sections we have and resolve all the relocations 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // in them. Gross overkill, but it gets the job done. 54edc4664d60af1f124d05f0a2b6ba58b837630f51Alan Viverette for (int i = 0, e = Sections.size(); i != e; ++i) { 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // The Section here (Sections[i]) refers to the section in which the 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // symbol for the relocation is located. The SectionID in the relocation 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // entry provides the section to which the relocation will be applied. 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint64_t Addr = Sections[i].LoadAddress; 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DEBUG(dbgs() << "Resolving relocations Section #" << i 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << "\t" << format("%p", (uint8_t *)Addr) 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << "\n"); 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resolveRelocationList(Relocations[i], Addr); 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Relocations.erase(i); 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid RuntimeDyldImpl::mapSectionAddress(const void *LocalAddress, 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint64_t TargetAddress) { 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MutexGuard locked(lock); 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (unsigned i = 0, e = Sections.size(); i != e; ++i) { 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (Sections[i].Address == LocalAddress) { 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski reassignSectionAddress(i, TargetAddress); 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski llvm_unreachable("Attempting to remap address of unknown section!"); 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Subclasses can implement this method to create specialized image instances. 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// The caller owns the pointer that is returned. 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiObjectImage *RuntimeDyldImpl::createObjectImage(ObjectBuffer *InputBuffer) { 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new ObjectImageCommon(InputBuffer); 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiObjectImage *RuntimeDyldImpl::loadObject(ObjectBuffer *InputBuffer) { 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MutexGuard locked(lock); 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski OwningPtr<ObjectImage> obj(createObjectImage(InputBuffer)); 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!obj) 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski report_fatal_error("Unable to create object image from memory buffer!"); 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Save information about our target 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Arch = (Triple::ArchType)obj->getArch(); 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski IsTargetLittleEndian = obj->getObjectFile()->isLittleEndian(); 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Symbols found in this object 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringMap<SymbolLoc> LocalSymbols; 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Used sections from the object file 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ObjSectionToIDMap LocalSections; 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Common symbols requiring allocation, with their sizes and alignments 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski CommonSymbolMap CommonSymbols; 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Maximum required total memory to allocate all common symbols 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint64_t CommonSize = 0; 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error_code err; 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Parse symbols 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DEBUG(dbgs() << "Parse symbols:\n"); 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (symbol_iterator i = obj->begin_symbols(), e = obj->end_symbols(); 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski i != e; i.increment(err)) { 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Check(err); 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski object::SymbolRef::Type SymType; 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringRef Name; 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Check(i->getType(SymType)); 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Check(i->getName(Name)); 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t flags; 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Check(i->getFlags(flags)); 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isCommon = flags & SymbolRef::SF_Common; 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isCommon) { 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Add the common symbols to a list. We'll allocate them all below. 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t Align; 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Check(i->getAlignment(Align)); 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint64_t Size = 0; 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Check(i->getSize(Size)); 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski CommonSize += Size + Align; 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski CommonSymbols[*i] = CommonSymbolInfo(Size, Align); 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (SymType == object::SymbolRef::ST_Function || 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SymType == object::SymbolRef::ST_Data || 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SymType == object::SymbolRef::ST_Unknown) { 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint64_t FileOffset; 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringRef SectionData; 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool IsCode; 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski section_iterator si = obj->end_sections(); 137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Check(i->getFileOffset(FileOffset)); 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Check(i->getSection(si)); 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (si == obj->end_sections()) continue; 140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Check(si->getContents(SectionData)); 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Check(si->isText(IsCode)); 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const uint8_t* SymPtr = (const uint8_t*)InputBuffer->getBufferStart() + 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (uintptr_t)FileOffset; 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uintptr_t SectOffset = (uintptr_t)(SymPtr - 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (const uint8_t*)SectionData.begin()); 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski unsigned SectionID = findOrEmitSection(*obj, *si, IsCode, LocalSections); 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LocalSymbols[Name.data()] = SymbolLoc(SectionID, SectOffset); 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DEBUG(dbgs() << "\tFileOffset: " << format("%p", (uintptr_t)FileOffset) 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << " flags: " << flags 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << " SID: " << SectionID 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << " Offset: " << format("%p", SectOffset)); 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski GlobalSymbolTable[Name] = SymbolLoc(SectionID, SectOffset); 153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name << "\n"); 156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1588250a825c39a2f1f63920669cf233db3d8944b51Deepanshu Gupta // Allocate common symbols 1598250a825c39a2f1f63920669cf233db3d8944b51Deepanshu Gupta if (CommonSize != 0) 1608250a825c39a2f1f63920669cf233db3d8944b51Deepanshu Gupta emitCommonSymbols(*obj, CommonSymbols, CommonSize, LocalSymbols); 1618250a825c39a2f1f63920669cf233db3d8944b51Deepanshu Gupta 1628250a825c39a2f1f63920669cf233db3d8944b51Deepanshu Gupta // Parse and process relocations 163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DEBUG(dbgs() << "Parse relocations:\n"); 164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (section_iterator si = obj->begin_sections(), 165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski se = obj->end_sections(); si != se; si.increment(err)) { 1664a605c6fa0027ee116beb29fbc9625721f0441f0Deepanshu Gupta Check(err); 167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool isFirstRelocation = true; 168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski unsigned SectionID = 0; 169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StubMap Stubs; 170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski section_iterator RelocatedSection = si->getRelocatedSection(); 171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (relocation_iterator i = si->begin_relocations(), 173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e = si->end_relocations(); i != e; i.increment(err)) { 174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Check(err); 175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If it's the first relocation in this section, find its SectionID 177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isFirstRelocation) { 178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SectionID = 179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski findOrEmitSection(*obj, *RelocatedSection, true, LocalSections); 180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n"); 181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski isFirstRelocation = false; 182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski processRelocationRef(SectionID, *i, *obj, LocalSections, LocalSymbols, 185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Stubs); 186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Give the subclasses a chance to tie-up any loose ends. 190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski finalizeLoad(LocalSections); 191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return obj.take(); 193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj, 196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const CommonSymbolMap &CommonSymbols, 197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint64_t TotalSize, 198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SymbolTableMap &SymbolTable) { 199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Allocate memory for the section 200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski unsigned SectionID = Sections.size(); 201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint8_t *Addr = MemMgr->allocateDataSection( 202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski TotalSize, sizeof(void*), SectionID, StringRef(), false); 203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!Addr) 204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski report_fatal_error("Unable to allocate memory for common symbols!"); 205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint64_t Offset = 0; 206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Sections.push_back(SectionEntry(StringRef(), Addr, TotalSize, 0)); 207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(Addr, 0, TotalSize); 208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DEBUG(dbgs() << "emitCommonSection SectionID: " << SectionID 210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << " new addr: " << format("%p", Addr) 211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << " DataSize: " << TotalSize 212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << "\n"); 213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Assign the address of each symbol 215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (CommonSymbolMap::const_iterator it = CommonSymbols.begin(), 216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski itEnd = CommonSymbols.end(); it != itEnd; it++) { 217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint64_t Size = it->second.first; 218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint64_t Align = it->second.second; 219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringRef Name; 220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski it->first.getName(Name); 221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (Align) { 222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This symbol has an alignment requirement. 223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint64_t AlignOffset = OffsetToAlignment((uint64_t)Addr, Align); 224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Addr += AlignOffset; 225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Offset += AlignOffset; 226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DEBUG(dbgs() << "Allocating common symbol " << Name << " address " << 227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski format("%p\n", Addr)); 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Obj.updateSymbolAddress(it->first, (uint64_t)Addr); 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SymbolTable[Name.data()] = SymbolLoc(SectionID, Offset); 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Offset += Size; 232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Addr += Size; 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiunsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj, 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SectionRef &Section, 238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool IsCode) { 239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski unsigned StubBufSize = 0, 241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StubSize = getMaxStubSize(); 242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski error_code err; 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ObjectFile *ObjFile = Obj.getObjectFile(); 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // FIXME: this is an inefficient way to handle this. We should computed the 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // necessary section allocation size in loadObject by walking all the sections 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // once. 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (StubSize > 0) { 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (section_iterator SI = ObjFile->begin_sections(), 249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SE = ObjFile->end_sections(); 250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SI != SE; SI.increment(err), Check(err)) { 251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski section_iterator RelSecI = SI->getRelocatedSection(); 252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!(RelSecI == Section)) 253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (relocation_iterator I = SI->begin_relocations(), 256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski E = SI->end_relocations(); I != E; I.increment(err), Check(err)) { 257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StubBufSize += StubSize; 258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringRef data; 263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint64_t Alignment64; 264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Check(Section.getContents(data)); 265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Check(Section.getAlignment(Alignment64)); 266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL; 268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool IsRequired; 269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool IsVirtual; 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool IsZeroInit; 271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool IsReadOnly; 272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint64_t DataSize; 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski unsigned PaddingSize = 0; 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringRef Name; 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Check(Section.isRequiredForExecution(IsRequired)); 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Check(Section.isVirtual(IsVirtual)); 277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Check(Section.isZeroInit(IsZeroInit)); 278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Check(Section.isReadOnlyData(IsReadOnly)); 279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Check(Section.getSize(DataSize)); 280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Check(Section.getName(Name)); 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (StubSize > 0) { 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski unsigned StubAlignment = getStubAlignment(); 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski unsigned EndAlignment = (DataSize | Alignment) & -(DataSize | Alignment); 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (StubAlignment > EndAlignment) 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StubBufSize += StubAlignment - EndAlignment; 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // The .eh_frame section (at least on Linux) needs an extra four bytes padded 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // with zeroes added at the end. For MachO objects, this section has a 290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // slightly different name, so this won't have any effect for MachO objects. 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (Name == ".eh_frame") 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PaddingSize = 4; 293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski unsigned Allocate; 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski unsigned SectionID = Sections.size(); 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint8_t *Addr; 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const char *pData = 0; 298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Some sections, such as debug info, don't need to be loaded for execution. 300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Leave those where they are. 301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (IsRequired) { 302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Allocate = DataSize + PaddingSize + StubBufSize; 303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Addr = IsCode 304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID, Name) 305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski : MemMgr->allocateDataSection(Allocate, Alignment, SectionID, Name, 306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski IsReadOnly); 307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!Addr) 308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski report_fatal_error("Unable to allocate section memory!"); 309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Virtual sections have no data in the object image, so leave pData = 0 311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!IsVirtual) 312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski pData = data.data(); 313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Zero-initialize or copy the data from the image 315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (IsZeroInit || IsVirtual) 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(Addr, 0, DataSize); 317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memcpy(Addr, pData, DataSize); 319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Fill in any extra bytes we allocated for padding 321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (PaddingSize != 0) { 322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(Addr + DataSize, 0, PaddingSize); 323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Update the DataSize variable so that the stub offset is set correctly. 324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DataSize += PaddingSize; 325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DEBUG(dbgs() << "emitSection SectionID: " << SectionID 328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << " Name: " << Name 329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << " obj addr: " << format("%p", pData) 330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << " new addr: " << format("%p", Addr) 331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << " DataSize: " << DataSize 332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << " StubBufSize: " << StubBufSize 333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << " Allocate: " << Allocate 334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << "\n"); 335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Obj.updateSectionAddress(Section, (uint64_t)Addr); 336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else { 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Even if we didn't load the section, we need to record an entry for it 339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // to handle later processing (and by 'handle' I mean don't do anything 340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // with these sections). 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Allocate = 0; 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Addr = 0; 343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DEBUG(dbgs() << "emitSection SectionID: " << SectionID 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << " Name: " << Name 345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << " obj addr: " << format("%p", data.data()) 346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << " new addr: 0" 347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << " DataSize: " << DataSize 348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << " StubBufSize: " << StubBufSize 349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << " Allocate: " << Allocate 350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << "\n"); 351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Sections.push_back(SectionEntry(Name, Addr, DataSize, (uintptr_t)pData)); 354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return SectionID; 355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiunsigned RuntimeDyldImpl::findOrEmitSection(ObjectImage &Obj, 358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const SectionRef &Section, 359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool IsCode, 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ObjSectionToIDMap &LocalSections) { 361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski unsigned SectionID = 0; 363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ObjSectionToIDMap::iterator i = LocalSections.find(Section); 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (i != LocalSections.end()) 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SectionID = i->second; 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else { 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SectionID = emitSection(Obj, Section, IsCode); 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LocalSections[Section] = SectionID; 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return SectionID; 371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid RuntimeDyldImpl::addRelocationForSection(const RelocationEntry &RE, 374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski unsigned SectionID) { 375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Relocations[SectionID].push_back(RE); 376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid RuntimeDyldImpl::addRelocationForSymbol(const RelocationEntry &RE, 379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringRef SymbolName) { 380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Relocation by symbol. If the symbol is found in the global symbol table, 381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // create an appropriate section relocation. Otherwise, add it to 382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // ExternalSymbolRelocations. 383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SymbolTableMap::const_iterator Loc = 384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski GlobalSymbolTable.find(SymbolName); 385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (Loc == GlobalSymbolTable.end()) { 386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ExternalSymbolRelocations[SymbolName].push_back(RE); 387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Copy the RE since we want to modify its addend. 389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RelocationEntry RECopy = RE; 390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RECopy.Addend += Loc->second.second; 391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Relocations[Loc->second.first].push_back(RECopy); 392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr) { 396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (Arch == Triple::aarch64) { 397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This stub has to be able to access the full address space, 398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // since symbol lookup won't necessarily find a handy, in-range, 399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // PLT stub for functions which could be anywhere. 400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t *StubAddr = (uint32_t*)Addr; 401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Stub can use ip0 (== x16) to calculate address 403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *StubAddr = 0xd2e00010; // movz ip0, #:abs_g3:<addr> 404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StubAddr++; 405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *StubAddr = 0xf2c00010; // movk ip0, #:abs_g2_nc:<addr> 406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StubAddr++; 407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *StubAddr = 0xf2a00010; // movk ip0, #:abs_g1_nc:<addr> 408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StubAddr++; 409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *StubAddr = 0xf2800010; // movk ip0, #:abs_g0_nc:<addr> 410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StubAddr++; 411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *StubAddr = 0xd61f0200; // br ip0 412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return Addr; 414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (Arch == Triple::arm) { 415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // TODO: There is only ARM far stub now. We should add the Thumb stub, 416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // and stubs for branches Thumb - ARM and ARM - Thumb. 417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t *StubAddr = (uint32_t*)Addr; 418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *StubAddr = 0xe51ff004; // ldr pc,<label> 419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (uint8_t*)++StubAddr; 420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (Arch == Triple::mipsel || Arch == Triple::mips) { 421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint32_t *StubAddr = (uint32_t*)Addr; 422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // 0: 3c190000 lui t9,%hi(addr). 423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // 4: 27390000 addiu t9,t9,%lo(addr). 424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // 8: 03200008 jr t9. 425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // c: 00000000 nop. 426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const unsigned LuiT9Instr = 0x3c190000, AdduiT9Instr = 0x27390000; 427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const unsigned JrT9Instr = 0x03200008, NopInstr = 0x0; 428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *StubAddr = LuiT9Instr; 430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StubAddr++; 431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *StubAddr = AdduiT9Instr; 432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StubAddr++; 433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *StubAddr = JrT9Instr; 434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StubAddr++; 435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *StubAddr = NopInstr; 436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return Addr; 437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) { 438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // PowerPC64 stub: the address points to a function descriptor 439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // instead of the function itself. Load the function address 440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // on r11 and sets it to control register. Also loads the function 441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // TOC in r2 and environment pointer to r11. 442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writeInt32BE(Addr, 0x3D800000); // lis r12, highest(addr) 443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writeInt32BE(Addr+4, 0x618C0000); // ori r12, higher(addr) 444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writeInt32BE(Addr+8, 0x798C07C6); // sldi r12, r12, 32 445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writeInt32BE(Addr+12, 0x658C0000); // oris r12, r12, h(addr) 446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writeInt32BE(Addr+16, 0x618C0000); // ori r12, r12, l(addr) 447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writeInt32BE(Addr+20, 0xF8410028); // std r2, 40(r1) 448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writeInt32BE(Addr+24, 0xE96C0000); // ld r11, 0(r12) 449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writeInt32BE(Addr+28, 0xE84C0008); // ld r2, 0(r12) 450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writeInt32BE(Addr+32, 0x7D6903A6); // mtctr r11 451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writeInt32BE(Addr+36, 0xE96C0010); // ld r11, 16(r2) 452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writeInt32BE(Addr+40, 0x4E800420); // bctr 453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return Addr; 455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (Arch == Triple::systemz) { 456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writeInt16BE(Addr, 0xC418); // lgrl %r1,.+8 457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writeInt16BE(Addr+2, 0x0000); 458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writeInt16BE(Addr+4, 0x0004); 459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski writeInt16BE(Addr+6, 0x07F1); // brc 15,%r1 460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // 8-byte address stored at Addr + 8 461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return Addr; 462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (Arch == Triple::x86_64) { 463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *Addr = 0xFF; // jmp 464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *(Addr+1) = 0x25; // rip 465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // 32-bit PC-relative address of the GOT entry will be stored at Addr+2 466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return Addr; 468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Assign an address to a symbol name and resolve all the relocations 471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// associated with it. 472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid RuntimeDyldImpl::reassignSectionAddress(unsigned SectionID, 473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint64_t Addr) { 474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // The address to use for relocation resolution is not 475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the address of the local section buffer. We must be doing 476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // a remote execution environment of some sort. Relocations can't 477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // be applied until all the sections have been moved. The client must 478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // trigger this with a call to MCJIT::finalize() or 479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // RuntimeDyld::resolveRelocations(). 480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // 481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Addr is a uint64_t because we can't assume the pointer width 482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // of the target is the same as that of the host. Just use a generic 483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // "big enough" type. 484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Sections[SectionID].LoadAddress = Addr; 485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid RuntimeDyldImpl::resolveRelocationList(const RelocationList &Relocs, 488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint64_t Value) { 489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const RelocationEntry &RE = Relocs[i]; 491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Ignore relocations for sections that were not loaded 492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (Sections[RE.SectionID].Address == 0) 493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski continue; 494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resolveRelocation(RE, Value); 495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid RuntimeDyldImpl::resolveExternalSymbols() { 499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while(!ExternalSymbolRelocations.empty()) { 500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringMap<RelocationList>::iterator i = ExternalSymbolRelocations.begin(); 501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StringRef Name = i->first(); 503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (Name.size() == 0) { 504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This is an absolute symbol, use an address of zero. 505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DEBUG(dbgs() << "Resolving absolute relocations." << "\n"); 506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RelocationList &Relocs = i->second; 507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resolveRelocationList(Relocs, 0); 508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint64_t Addr = 0; 510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SymbolTableMap::const_iterator Loc = GlobalSymbolTable.find(Name); 511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (Loc == GlobalSymbolTable.end()) { 512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This is an external symbol, try to get its address from 513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // MemoryManager. 514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Addr = MemMgr->getSymbolAddress(Name.data()); 515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // The call to getSymbolAddress may have caused additional modules to 516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // be loaded, which may have added new entries to the 517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // ExternalSymbolRelocations map. Consquently, we need to update our 518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // iterator. This is also why retrieval of the relocation list 519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // associated with this symbol is deferred until below this point. 520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // New entries may have been added to the relocation list. 521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski i = ExternalSymbolRelocations.find(Name); 522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We found the symbol in our global table. It was probably in a 524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Module that we loaded previously. 525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SymbolLoc SymLoc = Loc->second; 526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Addr = getSectionLoadAddress(SymLoc.first) + SymLoc.second; 527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // FIXME: Implement error handling that doesn't kill the host program! 530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!Addr) 531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski report_fatal_error("Program used external function '" + Name + 532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "' which could not be resolved!"); 533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski updateGOTEntries(Name, Addr); 535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DEBUG(dbgs() << "Resolving relocations Name: " << Name 536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << "\t" << format("0x%lx", Addr) 537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski << "\n"); 538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This list may have been updated when we called getSymbolAddress, so 539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // don't change this code to get the list earlier. 540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RelocationList &Relocs = i->second; 541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resolveRelocationList(Relocs, Addr); 542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ExternalSymbolRelocations.erase(i); 545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski//===----------------------------------------------------------------------===// 550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// RuntimeDyld class implementation 551282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiRuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) { 552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // FIXME: There's a potential issue lurking here if a single instance of 553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // RuntimeDyld is used to load multiple objects. The current implementation 554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // associates a single memory manager with a RuntimeDyld instance. Even 555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // though the public class spawns a new 'impl' instance for each load, 556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // they share a single memory manager. This can become a problem when page 557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // permissions are applied. 558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Dyld = 0; 559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MM = mm; 560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 562282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiRuntimeDyld::~RuntimeDyld() { 563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete Dyld; 564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 566282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiObjectImage *RuntimeDyld::loadObject(ObjectBuffer *InputBuffer) { 567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!Dyld) { 568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sys::fs::file_magic Type = 569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sys::fs::identify_magic(InputBuffer->getBuffer()); 570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski switch (Type) { 571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::elf_relocatable: 572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::elf_executable: 573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::elf_shared_object: 574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::elf_core: 575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Dyld = new RuntimeDyldELF(MM); 576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::macho_object: 578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::macho_executable: 579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib: 580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::macho_core: 581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::macho_preload_executable: 582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::macho_dynamically_linked_shared_lib: 583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::macho_dynamic_linker: 584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::macho_bundle: 585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub: 586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::macho_dsym_companion: 587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Dyld = new RuntimeDyldMachO(MM); 588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::unknown: 590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::bitcode: 591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::archive: 592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::coff_object: 593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::coff_import_library: 594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::pecoff_executable: 595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::macho_universal_binary: 596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case sys::fs::file_magic::windows_resource: 597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski report_fatal_error("Incompatible object format!"); 598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!Dyld->isCompatibleFormat(InputBuffer)) 601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski report_fatal_error("Incompatible object format!"); 602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return Dyld->loadObject(InputBuffer); 605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid *RuntimeDyld::getSymbolAddress(StringRef Name) { 608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!Dyld) 609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NULL; 610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return Dyld->getSymbolAddress(Name); 611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint64_t RuntimeDyld::getSymbolLoadAddress(StringRef Name) { 614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!Dyld) 615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return Dyld->getSymbolLoadAddress(Name); 617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid RuntimeDyld::resolveRelocations() { 620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Dyld->resolveRelocations(); 621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid RuntimeDyld::reassignSectionAddress(unsigned SectionID, 624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint64_t Addr) { 625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Dyld->reassignSectionAddress(SectionID, Addr); 626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid RuntimeDyld::mapSectionAddress(const void *LocalAddress, 629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski uint64_t TargetAddress) { 630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Dyld->mapSectionAddress(LocalAddress, TargetAddress); 631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 633282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiStringRef RuntimeDyld::getErrorString() { 634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return Dyld->getErrorString(); 635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid RuntimeDyld::registerEHFrames() { 638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (Dyld) 639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Dyld->registerEHFrames(); 640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid RuntimeDyld::deregisterEHFrames() { 643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (Dyld) 644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Dyld->deregisterEHFrames(); 645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} // end namespace llvm 648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski