1e0934bee3a4f40731169bc42b15a39ce39978175Jim Grosbach//===-- RuntimeDyldMachO.cpp - Run-time dynamic linker for MC-JIT -*- C++ -*-=// 2cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// 3cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// The LLVM Compiler Infrastructure 4cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// 5cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// This file is distributed under the University of Illinois Open Source 6cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// License. See LICENSE.TXT for details. 7cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// 8cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev//===----------------------------------------------------------------------===// 9cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// 10cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// Implementation of the MC-JIT runtime dynamic linker. 11cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// 12cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev//===----------------------------------------------------------------------===// 13cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 14d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "RuntimeDyldMachO.h" 15cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev#include "llvm/ADT/STLExtras.h" 16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/StringRef.h" 17cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "ObjectImageCommon.h" 18cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "JITRegistrar.h" 19cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevusing namespace llvm; 20cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevusing namespace llvm::object; 21cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 22dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "dyld" 23dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 24cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevnamespace llvm { 25cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 26cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesclass MachOObjectImage : public ObjectImageCommon { 27cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesprivate: 28cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines typedef SmallVector<uint64_t, 1> SectionAddrList; 29cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SectionAddrList OldSectionAddrList; 30cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 31cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesprotected: 32cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool is64; 33cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool Registered; 34cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 35cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesprivate: 36cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines void initOldAddress() { 37cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachOObjectFile *objf = static_cast<MachOObjectFile *>(ObjFile.get()); 38cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Unfortunately we need to do this, since there's information encoded 39cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // in the original addr of the section that we could not otherwise 40cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // recover. The reason for this is that symbols do not actually store 41cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // their file offset, but only their vmaddr. This means that in order 42cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // to locate the symbol correctly in the object file, we need to know 43cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // where the original start of the section was (including any padding, 44cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // etc). 45cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (section_iterator i = objf->section_begin(), e = objf->section_end(); 46cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines i != e; ++i) { 47cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t Addr; 48cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines i->getAddress(Addr); 49cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines OldSectionAddrList[i->getRawDataRefImpl().d.a] = Addr; 50cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 51cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 52cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 53cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinespublic: 54cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachOObjectImage(ObjectBuffer *Input, bool is64) 55cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines : ObjectImageCommon(Input), 56cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines OldSectionAddrList(ObjFile->section_end()->getRawDataRefImpl().d.a, 0), 57cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines is64(is64), Registered(false) { 58cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines initOldAddress(); 59cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 60cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 61cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachOObjectImage(std::unique_ptr<object::ObjectFile> Input, bool is64) 62cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines : ObjectImageCommon(std::move(Input)), 63cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines OldSectionAddrList(ObjFile->section_end()->getRawDataRefImpl().d.a, 0), 64cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines is64(is64), Registered(false) { 65cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines initOldAddress(); 66cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 67cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 68cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines virtual ~MachOObjectImage() { 69cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Registered) 70cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines deregisterWithDebugger(); 71cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 72cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 73cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Subclasses can override these methods to update the image with loaded 74cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // addresses for sections and common symbols 75cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines virtual void updateSectionAddress(const SectionRef &Sec, uint64_t Addr) { 76cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachOObjectFile *objf = static_cast<MachOObjectFile *>(ObjFile.get()); 77cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines char *data = 78cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const_cast<char *>(objf->getSectionPointer(Sec.getRawDataRefImpl())); 79cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 80cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t oldAddr = OldSectionAddrList[Sec.getRawDataRefImpl().d.a]; 81cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 82cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (is64) { 83cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ((MachO::section_64 *)data)->addr = Addr; 84cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else { 85cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ((MachO::section *)data)->addr = Addr; 86cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 87cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 88cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (symbol_iterator i = objf->symbol_begin(), e = objf->symbol_end(); 89cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines i != e; ++i) { 90cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines section_iterator symSec(objf->section_end()); 91cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines (*i).getSection(symSec); 92cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (*symSec == Sec) { 93cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t symAddr; 94cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines (*i).getAddress(symAddr); 95cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines updateSymbolAddress(*i, symAddr + Addr - oldAddr); 96cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 97cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 98cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 99cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 100cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t getOldSectionAddr(const SectionRef &Sec) const { 101cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return OldSectionAddrList[Sec.getRawDataRefImpl().d.a]; 102cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 103cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 104cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines virtual void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr) { 105cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines char *data = const_cast<char *>( 106cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines reinterpret_cast<const char *>(Sym.getRawDataRefImpl().p)); 107cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (is64) 108cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ((MachO::nlist_64 *)data)->n_value = Addr; 109cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else 110cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ((MachO::nlist *)data)->n_value = Addr; 111cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 112cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 113cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines virtual void registerWithDebugger() { 114cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines JITRegistrar::getGDBRegistrar().registerObject(*Buffer); 115cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Registered = true; 116cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 117cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 118cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines virtual void deregisterWithDebugger() { 119cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines JITRegistrar::getGDBRegistrar().deregisterObject(*Buffer); 120cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 121cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}; 122cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 123cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesObjectImage *RuntimeDyldMachO::createObjectImage(ObjectBuffer *Buffer) { 124cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint32_t magic = *((const uint32_t *)Buffer->getBufferStart()); 125cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool is64 = (magic == MachO::MH_MAGIC_64); 126cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines assert((magic == MachO::MH_MAGIC_64 || magic == MachO::MH_MAGIC) && 127cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines "Unrecognized Macho Magic"); 128cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return new MachOObjectImage(Buffer, is64); 129cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 130cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 131cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesObjectImage *RuntimeDyldMachO::createObjectImageFromFile( 132cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::unique_ptr<object::ObjectFile> ObjFile) { 133cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!ObjFile) 134cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return nullptr; 135cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 136cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MemoryBuffer *Buffer = 137cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MemoryBuffer::getMemBuffer(ObjFile->getData(), "", false); 138cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 139cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint32_t magic = *((const uint32_t *)Buffer->getBufferStart()); 140cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool is64 = (magic == MachO::MH_MAGIC_64); 141cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines assert((magic == MachO::MH_MAGIC_64 || magic == MachO::MH_MAGIC) && 142cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines "Unrecognized Macho Magic"); 143cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return new MachOObjectImage(std::move(ObjFile), is64); 144cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 145cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 14636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic unsigned char *processFDE(unsigned char *P, intptr_t DeltaForText, 14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines intptr_t DeltaForEH) { 148dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(dbgs() << "Processing FDE: Delta for text: " << DeltaForText 149dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << ", Delta for EH: " << DeltaForEH << "\n"); 15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Length = *((uint32_t *)P); 151a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola P += 4; 152a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola unsigned char *Ret = P + Length; 15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Offset = *((uint32_t *)P); 154a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola if (Offset == 0) // is a CIE 155a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola return Ret; 156a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 157a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola P += 4; 15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines intptr_t FDELocation = *((intptr_t *)P); 159a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola intptr_t NewLocation = FDELocation - DeltaForText; 16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *((intptr_t *)P) = NewLocation; 161a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola P += sizeof(intptr_t); 162a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 163a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola // Skip the FDE address range 164a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola P += sizeof(intptr_t); 165a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 166a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola uint8_t Augmentationsize = *P; 167a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola P += 1; 168a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola if (Augmentationsize != 0) { 16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines intptr_t LSDA = *((intptr_t *)P); 170a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola intptr_t NewLSDA = LSDA - DeltaForEH; 17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *((intptr_t *)P) = NewLSDA; 172a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola } 173a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 174a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola return Ret; 175a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola} 176a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 177a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindolastatic intptr_t computeDelta(SectionEntry *A, SectionEntry *B) { 17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines intptr_t ObjDistance = A->ObjAddress - B->ObjAddress; 179a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola intptr_t MemDistance = A->LoadAddress - B->LoadAddress; 180a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola return ObjDistance - MemDistance; 181a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola} 182a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 183528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylorvoid RuntimeDyldMachO::registerEHFrames() { 184528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor 185528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor if (!MemMgr) 186528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor return; 187528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) { 188528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor EHFrameRelatedSections &SectionInfo = UnregisteredEHFrameSections[i]; 189528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor if (SectionInfo.EHFrameSID == RTDYLD_INVALID_SECTION_ID || 190528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor SectionInfo.TextSID == RTDYLD_INVALID_SECTION_ID) 191528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor continue; 192528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor SectionEntry *Text = &Sections[SectionInfo.TextSID]; 193528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor SectionEntry *EHFrame = &Sections[SectionInfo.EHFrameSID]; 194dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SectionEntry *ExceptTab = nullptr; 195528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor if (SectionInfo.ExceptTabSID != RTDYLD_INVALID_SECTION_ID) 196528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor ExceptTab = &Sections[SectionInfo.ExceptTabSID]; 197528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor 198528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor intptr_t DeltaForText = computeDelta(Text, EHFrame); 199528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor intptr_t DeltaForEH = 0; 200528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor if (ExceptTab) 201528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor DeltaForEH = computeDelta(ExceptTab, EHFrame); 202a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 203528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor unsigned char *P = EHFrame->Address; 204528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor unsigned char *End = P + EHFrame->Size; 20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines do { 206528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor P = processFDE(P, DeltaForText, DeltaForEH); 20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } while (P != End); 208a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MemMgr->registerEHFrames(EHFrame->Address, EHFrame->LoadAddress, 210528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor EHFrame->Size); 211528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor } 212528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor UnregisteredEHFrameSections.clear(); 213528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor} 214a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 215dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid RuntimeDyldMachO::finalizeLoad(ObjectImage &ObjImg, 216dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjSectionToIDMap &SectionMap) { 217528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor unsigned EHFrameSID = RTDYLD_INVALID_SECTION_ID; 218528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor unsigned TextSID = RTDYLD_INVALID_SECTION_ID; 219528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor unsigned ExceptTabSID = RTDYLD_INVALID_SECTION_ID; 220528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor ObjSectionToIDMap::iterator i, e; 221528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++i) { 222528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor const SectionRef &Section = i->first; 223528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor StringRef Name; 224528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor Section.getName(Name); 225528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor if (Name == "__eh_frame") 226528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor EHFrameSID = i->second; 227528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor else if (Name == "__text") 228528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor TextSID = i->second; 229528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor else if (Name == "__gcc_except_tab") 230528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor ExceptTabSID = i->second; 231dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else if (Name == "__jump_table") 232dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines populateJumpTable(cast<MachOObjectFile>(*ObjImg.getObjectFile()), 233dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Section, i->second); 234dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else if (Name == "__pointers") 235dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines populatePointersSection(cast<MachOObjectFile>(*ObjImg.getObjectFile()), 236dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Section, i->second); 237528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor } 23836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines UnregisteredEHFrameSections.push_back( 23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EHFrameRelatedSections(EHFrameSID, TextSID, ExceptTabSID)); 240a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola} 241a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 24232bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// The target location for the relocation is described by RE.SectionID and 24332bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// RE.Offset. RE.SectionID can be used to find the SectionEntry. Each 24432bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry has three members describing its location. 24532bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry::Address is the address at which the section has been loaded 24632bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// into memory in the current (host) process. SectionEntry::LoadAddress is the 24732bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// address that the section will have in the target process. 24832bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry::ObjAddress is the address of the bits for this section in the 24932bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// original emitted object image (also in the current address space). 25032bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// 25132bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// Relocations will be applied as if the section were loaded at 25232bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry::LoadAddress, but they will be applied at an address based 25332bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// on SectionEntry::Address. SectionEntry::ObjAddress will be used to refer to 25432bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// Target memory contents if they are required for value calculations. 25532bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// 25632bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// The Value parameter here is the load address of the symbol for the 25732bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// relocation to be applied. For relocations which refer to symbols in the 25832bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// current object Value will be the LoadAddress of the section in which 25932bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// the symbol resides (RE.Addend provides additional information about the 26032bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// symbol location). For external symbols, Value will be the address of the 26132bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// symbol in the target address space. 26287b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindolavoid RuntimeDyldMachO::resolveRelocation(const RelocationEntry &RE, 26387b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola uint64_t Value) { 264dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG ( 265dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const SectionEntry &Section = Sections[RE.SectionID]; 266dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t* LocalAddress = Section.Address + RE.Offset; 267dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t FinalAddress = Section.LoadAddress + RE.Offset; 268dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 269dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines dbgs() << "resolveRelocation Section: " << RE.SectionID 270dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << " LocalAddress: " << format("%p", LocalAddress) 271dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << " FinalAddress: " << format("%p", FinalAddress) 272dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << " Value: " << format("%p", Value) 273dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << " Addend: " << RE.Addend 274dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << " isPCRel: " << RE.IsPCRel 275dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << " MachoType: " << RE.RelType 276dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << " Size: " << (1 << RE.Size) << "\n"; 277dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ); 2780e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 279cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // This just dispatches to the proper target specific routine. 2800e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev switch (Arch) { 28136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 28236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines llvm_unreachable("Unsupported CPU type!"); 2830e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::x86_64: 284dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines resolveX86_64Relocation(RE, Value); 2850e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 2860e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::x86: 287dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines resolveI386Relocation(RE, Value); 2880e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 28936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Triple::arm: // Fall through. 2900e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::thumb: 291dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines resolveARMRelocation(RE, Value); 29236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 293dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case Triple::aarch64: 29436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Triple::arm64: 295dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines resolveAArch64Relocation(RE, Value); 2960e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 297cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 298cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 299cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 300dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool RuntimeDyldMachO::resolveI386Relocation(const RelocationEntry &RE, 301dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Value) { 302dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const SectionEntry &Section = Sections[RE.SectionID]; 303dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t* LocalAddress = Section.Address + RE.Offset; 304b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan 305dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (RE.IsPCRel) { 306dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t FinalAddress = Section.LoadAddress + RE.Offset; 307dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value -= FinalAddress + 4; // see MachOX86_64::resolveRelocation. 308b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan } 309dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 310dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines switch (RE.RelType) { 311dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines default: 312dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines llvm_unreachable("Invalid relocation type!"); 313dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case MachO::GENERIC_RELOC_VANILLA: 314dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return applyRelocationValue(LocalAddress, Value + RE.Addend, 315dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1 << RE.Size); 316dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case MachO::GENERIC_RELOC_SECTDIFF: 317dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: { 318dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t SectionABase = Sections[RE.Sections.SectionA].LoadAddress; 319dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t SectionBBase = Sections[RE.Sections.SectionB].LoadAddress; 320dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert((Value == SectionABase || Value == SectionBBase) && 321dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "Unexpected SECTDIFF relocation value."); 322dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value = SectionABase - SectionBBase + RE.Addend; 323dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return applyRelocationValue(LocalAddress, Value, 1 << RE.Size); 324dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 325dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case MachO::GENERIC_RELOC_PB_LA_PTR: 326dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return Error("Relocation type not implemented yet!"); 327b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan } 328b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan} 329b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan 330dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool RuntimeDyldMachO::resolveX86_64Relocation(const RelocationEntry &RE, 331dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Value) { 332dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const SectionEntry &Section = Sections[RE.SectionID]; 333dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t* LocalAddress = Section.Address + RE.Offset; 334dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 335cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the relocation is PC-relative, the value to be encoded is the 336cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // pointer difference. 337dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (RE.IsPCRel) { 338cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: It seems this value needs to be adjusted by 4 for an effective PC 339cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // address. Is that expected? Only for branches, perhaps? 340dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t FinalAddress = Section.LoadAddress + RE.Offset; 341dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value -= FinalAddress + 4; // see MachOX86_64::resolveRelocation. 342dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 343cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 344dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines switch (RE.RelType) { 345cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 346cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 3475510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_SIGNED_1: 3485510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_SIGNED_2: 3495510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_SIGNED_4: 3505510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_SIGNED: 3515510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_UNSIGNED: 352dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case MachO::X86_64_RELOC_BRANCH: 353dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return applyRelocationValue(LocalAddress, Value + RE.Addend, 1 << RE.Size); 3545510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_GOT_LOAD: 3555510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_GOT: 3565510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_SUBTRACTOR: 3575510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_TLV: 358cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Relocation type not implemented yet!"); 359cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 360cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 361cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 362dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool RuntimeDyldMachO::resolveARMRelocation(const RelocationEntry &RE, 363dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Value) { 364dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const SectionEntry &Section = Sections[RE.SectionID]; 365dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t* LocalAddress = Section.Address + RE.Offset; 366dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 367cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the relocation is PC-relative, the value to be encoded is the 368cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // pointer difference. 369dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (RE.IsPCRel) { 370dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t FinalAddress = Section.LoadAddress + RE.Offset; 37161dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Value -= FinalAddress; 372cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // ARM PCRel relocations have an effective-PC offset of two instructions 373cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // (four bytes in Thumb mode, 8 bytes in ARM mode). 374cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: For now, assume ARM mode. 375cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value -= 8; 376cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 377cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 378dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines switch (RE.RelType) { 379cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 380cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 381dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case MachO::ARM_RELOC_VANILLA: 382dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return applyRelocationValue(LocalAddress, Value, 1 << RE.Size); 3835510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_BR24: { 384cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask the value into the target address. We know instructions are 385cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // 32-bit aligned, so we can do it all at once. 38636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t *p = (uint32_t *)LocalAddress; 387cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // The low two bits of the value are not encoded. 388cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 2; 389cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask the value to 24 bits. 390dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t FinalValue = Value & 0xffffff; 391dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Check for overflow. 392dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Value != FinalValue) 393dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return Error("ARM BR24 relocation out of range."); 394cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: If the destination is a Thumb function (and the instruction 395cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // is a non-predicated BL instruction), we need to change it to a BLX 396cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // instruction instead. 397cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 398cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Insert the value into the instruction. 399dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *p = (*p & ~0xffffff) | FinalValue; 400cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 401cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 4025510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_THUMB_RELOC_BR22: 4035510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_THUMB_32BIT_BRANCH: 4045510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_HALF: 4055510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_HALF_SECTDIFF: 4065510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_PAIR: 4075510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_SECTDIFF: 4085510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_LOCAL_SECTDIFF: 4095510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_PB_LA_PTR: 410cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Relocation type not implemented yet!"); 411cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 412cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 413cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 414cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 415dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool RuntimeDyldMachO::resolveAArch64Relocation(const RelocationEntry &RE, 416dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Value) { 417dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const SectionEntry &Section = Sections[RE.SectionID]; 418dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t* LocalAddress = Section.Address + RE.Offset; 419dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // If the relocation is PC-relative, the value to be encoded is the 42136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // pointer difference. 422dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (RE.IsPCRel) { 423dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t FinalAddress = Section.LoadAddress + RE.Offset; 42436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value -= FinalAddress; 425dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 42636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 427dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines switch (RE.RelType) { 42836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 42936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines llvm_unreachable("Invalid relocation type!"); 430dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case MachO::ARM64_RELOC_UNSIGNED: 431dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return applyRelocationValue(LocalAddress, Value, 1 << RE.Size); 43236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::ARM64_RELOC_BRANCH26: { 43336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Mask the value into the target address. We know instructions are 43436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 32-bit aligned, so we can do it all at once. 43536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t *p = (uint32_t *)LocalAddress; 43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The low two bits of the value are not encoded. 43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value >>= 2; 43836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Mask the value to 26 bits. 439dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t FinalValue = Value & 0x3ffffff; 440dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Check for overflow. 441dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (FinalValue != Value) 442dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return Error("ARM64 BRANCH26 relocation out of range."); 44336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Insert the value into the instruction. 444dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *p = (*p & ~0x3ffffff) | FinalValue; 44536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 44636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 44736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::ARM64_RELOC_SUBTRACTOR: 44836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::ARM64_RELOC_PAGE21: 44936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::ARM64_RELOC_PAGEOFF12: 45036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::ARM64_RELOC_GOT_LOAD_PAGE21: 45136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12: 45236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::ARM64_RELOC_POINTER_TO_GOT: 45336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21: 45436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12: 45536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::ARM64_RELOC_ADDEND: 45636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Error("Relocation type not implemented yet!"); 45736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 45836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 45936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 46036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 461dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid RuntimeDyldMachO::populateJumpTable(MachOObjectFile &Obj, 462dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const SectionRef &JTSection, 463dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned JTSectionID) { 464dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(!Obj.is64Bit() && 465dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "__jump_table section not supported in 64-bit MachO."); 466dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 467dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::dysymtab_command DySymTabCmd = Obj.getDysymtabLoadCommand(); 468dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::section Sec32 = Obj.getSection(JTSection.getRawDataRefImpl()); 469dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t JTSectionSize = Sec32.size; 470dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned FirstIndirectSymbol = Sec32.reserved1; 471dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned JTEntrySize = Sec32.reserved2; 472dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned NumJTEntries = JTSectionSize / JTEntrySize; 473dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t* JTSectionAddr = getSectionAddress(JTSectionID); 474dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned JTEntryOffset = 0; 475dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 476dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert((JTSectionSize % JTEntrySize) == 0 && 477dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "Jump-table section does not contain a whole number of stubs?"); 478dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 479dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (unsigned i = 0; i < NumJTEntries; ++i) { 480dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned SymbolIndex = 481dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Obj.getIndirectSymbolTableEntry(DySymTabCmd, FirstIndirectSymbol + i); 482dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines symbol_iterator SI = Obj.getSymbolByIndex(SymbolIndex); 483dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines StringRef IndirectSymbolName; 484dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SI->getName(IndirectSymbolName); 485dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t* JTEntryAddr = JTSectionAddr + JTEntryOffset; 486dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines createStubFunction(JTEntryAddr); 487dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelocationEntry RE(JTSectionID, JTEntryOffset + 1, 488dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::GENERIC_RELOC_VANILLA, 0, true, 2); 489dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines addRelocationForSymbol(RE, IndirectSymbolName); 490dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines JTEntryOffset += JTEntrySize; 491dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 492dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 493dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 494dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid RuntimeDyldMachO::populatePointersSection(MachOObjectFile &Obj, 495dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const SectionRef &PTSection, 496dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned PTSectionID) { 497dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(!Obj.is64Bit() && 498dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "__pointers section not supported in 64-bit MachO."); 499dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 500dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::dysymtab_command DySymTabCmd = Obj.getDysymtabLoadCommand(); 501dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::section Sec32 = Obj.getSection(PTSection.getRawDataRefImpl()); 502dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t PTSectionSize = Sec32.size; 503dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned FirstIndirectSymbol = Sec32.reserved1; 504dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const unsigned PTEntrySize = 4; 505dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned NumPTEntries = PTSectionSize / PTEntrySize; 506dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned PTEntryOffset = 0; 507dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 508dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert((PTSectionSize % PTEntrySize) == 0 && 509dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "Pointers section does not contain a whole number of stubs?"); 510dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 511dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(dbgs() << "Populating __pointers, Section ID " << PTSectionID 512dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << ", " << NumPTEntries << " entries, " 513dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << PTEntrySize << " bytes each:\n"); 514dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 515dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (unsigned i = 0; i < NumPTEntries; ++i) { 516dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned SymbolIndex = 517dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Obj.getIndirectSymbolTableEntry(DySymTabCmd, FirstIndirectSymbol + i); 518dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines symbol_iterator SI = Obj.getSymbolByIndex(SymbolIndex); 519dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines StringRef IndirectSymbolName; 520dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SI->getName(IndirectSymbolName); 521dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(dbgs() << " " << IndirectSymbolName << ": index " << SymbolIndex 522dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << ", PT offset: " << PTEntryOffset << "\n"); 523dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelocationEntry RE(PTSectionID, PTEntryOffset, 524dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::GENERIC_RELOC_VANILLA, 0, false, 2); 525dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines addRelocationForSymbol(RE, IndirectSymbolName); 526dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines PTEntryOffset += PTEntrySize; 527dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 528dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 529dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 530dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 531dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinessection_iterator getSectionByAddress(const MachOObjectFile &Obj, 532dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Addr) { 533dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines section_iterator SI = Obj.section_begin(); 534dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines section_iterator SE = Obj.section_end(); 535dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 536dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (; SI != SE; ++SI) { 537dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t SAddr, SSize; 538dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SI->getAddress(SAddr); 539dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SI->getSize(SSize); 540dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if ((Addr >= SAddr) && (Addr < SAddr + SSize)) 541dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return SI; 542dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 543dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 544dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return SE; 545dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 546dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 547dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesrelocation_iterator RuntimeDyldMachO::processSECTDIFFRelocation( 548dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned SectionID, 549dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines relocation_iterator RelI, 550dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjectImage &Obj, 551dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjSectionToIDMap &ObjSectionToID) { 552dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MachOObjectFile *MachO = 553dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines static_cast<const MachOObjectFile*>(Obj.getObjectFile()); 554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::any_relocation_info RE = 555dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO->getRelocation(RelI->getRawDataRefImpl()); 556dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 557dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SectionEntry &Section = Sections[SectionID]; 558dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t RelocType = MachO->getAnyRelocationType(RE); 559dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool IsPCRel = MachO->getAnyRelocationPCRel(RE); 560dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned Size = MachO->getAnyRelocationLength(RE); 561dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Offset; 562dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelI->getOffset(Offset); 563dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t *LocalAddress = Section.Address + Offset; 564dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned NumBytes = 1 << Size; 565dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines int64_t Addend = 0; 566dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines memcpy(&Addend, LocalAddress, NumBytes); 567dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 568dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ++RelI; 569dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::any_relocation_info RE2 = 570dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO->getRelocation(RelI->getRawDataRefImpl()); 571dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 572dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t AddrA = MachO->getScatteredRelocationValue(RE); 573dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines section_iterator SAI = getSectionByAddress(*MachO, AddrA); 574dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(SAI != MachO->section_end() && "Can't find section for address A"); 575dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t SectionABase; 576dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SAI->getAddress(SectionABase); 577dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t SectionAOffset = AddrA - SectionABase; 578dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SectionRef SectionA = *SAI; 579dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool IsCode; 580dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SectionA.isText(IsCode); 581dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t SectionAID = findOrEmitSection(Obj, SectionA, IsCode, 582dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjSectionToID); 583dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 584dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t AddrB = MachO->getScatteredRelocationValue(RE2); 585dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines section_iterator SBI = getSectionByAddress(*MachO, AddrB); 586dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(SBI != MachO->section_end() && "Can't find section for address B"); 587dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t SectionBBase; 588dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SBI->getAddress(SectionBBase); 589dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t SectionBOffset = AddrB - SectionBBase; 590dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SectionRef SectionB = *SBI; 591dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t SectionBID = findOrEmitSection(Obj, SectionB, IsCode, 592dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjSectionToID); 593dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 594dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Addend != AddrA - AddrB) 595dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Error("Unexpected SECTDIFF relocation addend."); 596dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 597dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(dbgs() << "Found SECTDIFF: AddrA: " << AddrA << ", AddrB: " << AddrB 598dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << ", Addend: " << Addend << ", SectionA ID: " 599dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << SectionAID << ", SectionAOffset: " << SectionAOffset 600dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << ", SectionB ID: " << SectionBID << ", SectionBOffset: " 601dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << SectionBOffset << "\n"); 602dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelocationEntry R(SectionID, Offset, RelocType, 0, 603dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SectionAID, SectionAOffset, SectionBID, SectionBOffset, 604dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IsPCRel, Size); 605dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 606dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines addRelocationForSection(R, SectionAID); 607dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines addRelocationForSection(R, SectionBID); 608dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 609dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return ++RelI; 610dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 611dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 612dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesrelocation_iterator RuntimeDyldMachO::processI386ScatteredVANILLA( 613dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned SectionID, 614dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines relocation_iterator RelI, 615dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjectImage &Obj, 616dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjSectionToIDMap &ObjSectionToID) { 617dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MachOObjectFile *MachO = 618dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines static_cast<const MachOObjectFile*>(Obj.getObjectFile()); 619dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::any_relocation_info RE = 620dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO->getRelocation(RelI->getRawDataRefImpl()); 621dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 622dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SectionEntry &Section = Sections[SectionID]; 623dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t RelocType = MachO->getAnyRelocationType(RE); 624dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool IsPCRel = MachO->getAnyRelocationPCRel(RE); 625dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned Size = MachO->getAnyRelocationLength(RE); 626dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Offset; 627dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelI->getOffset(Offset); 628dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t *LocalAddress = Section.Address + Offset; 629dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned NumBytes = 1 << Size; 630dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines int64_t Addend = 0; 631dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines memcpy(&Addend, LocalAddress, NumBytes); 632dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 633dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned SymbolBaseAddr = MachO->getScatteredRelocationValue(RE); 634dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines section_iterator TargetSI = getSectionByAddress(*MachO, SymbolBaseAddr); 635dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(TargetSI != MachO->section_end() && "Can't find section for symbol"); 636dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t SectionBaseAddr; 637dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TargetSI->getAddress(SectionBaseAddr); 638dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SectionRef TargetSection = *TargetSI; 639dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool IsCode; 640dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TargetSection.isText(IsCode); 641dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t TargetSectionID = findOrEmitSection(Obj, TargetSection, IsCode, 642dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjSectionToID); 643dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 644dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Addend -= SectionBaseAddr; 645dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelocationEntry R(SectionID, Offset, RelocType, Addend, 646dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IsPCRel, Size); 647dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 648dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines addRelocationForSection(R, TargetSectionID); 649dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 650dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return ++RelI; 651dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 652dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 65336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesrelocation_iterator RuntimeDyldMachO::processRelocationRef( 65436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned SectionID, relocation_iterator RelI, ObjectImage &Obj, 65536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols, 65636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StubMap &Stubs) { 657efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola const ObjectFile *OF = Obj.getObjectFile(); 658cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const MachOObjectImage &MachOObj = *static_cast<MachOObjectImage *>(&Obj); 65936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MachOObjectFile *MachO = static_cast<const MachOObjectFile *>(OF); 66036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachO::any_relocation_info RE = 66136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachO->getRelocation(RelI->getRawDataRefImpl()); 6620e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 663efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola uint32_t RelType = MachO->getAnyRelocationType(RE); 664623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames 665623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames // FIXME: Properly handle scattered relocations. 666dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Special case the couple of scattered relocations that we know how 667dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // to handle: SECTDIFF relocations, and scattered VANILLA relocations 668dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // on I386. 669dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // For all other scattered relocations, just bail out and hope for the 670dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // best, since the offsets computed by scattered relocations have often 671dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // been optimisticaly filled in by the compiler. This will fail 672dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // horribly where the relocations *do* need to be applied, but that was 673dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // already the case. 674dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (MachO->isRelocationScattered(RE)) { 675dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (RelType == MachO::GENERIC_RELOC_SECTDIFF || 676dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelType == MachO::GENERIC_RELOC_LOCAL_SECTDIFF) 677dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return processSECTDIFFRelocation(SectionID, RelI, Obj, ObjSectionToID); 678dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else if (Arch == Triple::x86 && RelType == MachO::GENERIC_RELOC_VANILLA) 679dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return processI386ScatteredVANILLA(SectionID, RelI, Obj, ObjSectionToID); 680dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else 681dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return ++RelI; 682dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 683623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames 6840e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev RelocationValueRef Value; 685efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola SectionEntry &Section = Sections[SectionID]; 6860e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 687dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool IsExtern = MachO->getPlainRelocationExternal(RE); 68887b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola bool IsPCRel = MachO->getAnyRelocationPCRel(RE); 68987b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola unsigned Size = MachO->getAnyRelocationLength(RE); 6908e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola uint64_t Offset; 69136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RelI->getOffset(Offset); 692e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola uint8_t *LocalAddress = Section.Address + Offset; 693e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola unsigned NumBytes = 1 << Size; 694e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola uint64_t Addend = 0; 695e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola memcpy(&Addend, LocalAddress, NumBytes); 6968e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola 697dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (IsExtern) { 698c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // Obtain the symbol name which is referenced in the relocation 69936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines symbol_iterator Symbol = RelI->getSymbol(); 7000e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StringRef TargetName; 7016c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola Symbol->getName(TargetName); 702c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // First search for the symbol in the local symbol table 703d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky SymbolTableMap::const_iterator lsi = Symbols.find(TargetName.data()); 7040e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (lsi != Symbols.end()) { 7050e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.SectionID = lsi->second.first; 7068e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola Value.Addend = lsi->second.second + Addend; 7070e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } else { 708c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // Search for the symbol in the global symbol table 70936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SymbolTableMap::const_iterator gsi = 71036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GlobalSymbolTable.find(TargetName.data()); 711d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky if (gsi != GlobalSymbolTable.end()) { 7120e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.SectionID = gsi->second.first; 7138e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola Value.Addend = gsi->second.second + Addend; 7148e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola } else { 7150e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.SymbolName = TargetName.data(); 7168e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola Value.Addend = Addend; 7178e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola } 718cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 719dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 720dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Addends for external, PC-rel relocations on i386 point back to the zero 721dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // offset. Calculate the final offset from the relocation target instead. 722dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // This allows us to use the same logic for both external and internal 723dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // relocations in resolveI386RelocationRef. 724dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Arch == Triple::x86 && IsPCRel) { 725dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t RelocAddr = 0; 726dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelI->getAddress(RelocAddr); 727dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value.Addend += RelocAddr + 4; 728dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 729dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 7300e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } else { 731e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola SectionRef Sec = MachO->getRelocationSection(RE); 73236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool IsCode = false; 73336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Sec.isText(IsCode); 73436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value.SectionID = findOrEmitSection(Obj, Sec, IsCode, ObjSectionToID); 735cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t Addr = MachOObj.getOldSectionAddr(Sec); 736cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines DEBUG(dbgs() << "\nAddr: " << Addr << "\nAddend: " << Addend); 737e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola Value.Addend = Addend - Addr; 73836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IsPCRel) 73936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value.Addend += Offset + NumBytes; 740288967dfac246c8e35dc4f85afb667e74d1d26a8Bill Wendling } 741288967dfac246c8e35dc4f85afb667e74d1d26a8Bill Wendling 7425510728d28bb1ee04abc32da3d21b7df12948053Charles Davis if (Arch == Triple::x86_64 && (RelType == MachO::X86_64_RELOC_GOT || 7435510728d28bb1ee04abc32da3d21b7df12948053Charles Davis RelType == MachO::X86_64_RELOC_GOT_LOAD)) { 744a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola assert(IsPCRel); 745a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola assert(Size == 2); 746dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 747dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // FIXME: Teach the generic code above not to prematurely conflate 748dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // relocation addends and symbol offsets. 749dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value.Addend -= Addend; 750a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola StubMap::const_iterator i = Stubs.find(Value); 751a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola uint8_t *Addr; 752a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola if (i != Stubs.end()) { 753a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola Addr = Section.Address + i->second; 754a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola } else { 755a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola Stubs[Value] = Section.StubOffset; 756a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola uint8_t *GOTEntry = Section.Address + Section.StubOffset; 757dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelocationEntry GOTRE(SectionID, Section.StubOffset, 758dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::X86_64_RELOC_UNSIGNED, Value.Addend, false, 759dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 3); 760a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola if (Value.SymbolName) 761dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines addRelocationForSymbol(GOTRE, Value.SymbolName); 762a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola else 763dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines addRelocationForSection(GOTRE, Value.SectionID); 764a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola Section.StubOffset += 8; 765a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola Addr = GOTEntry; 766a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola } 767dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelocationEntry TargetRE(SectionID, Offset, 768dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::X86_64_RELOC_UNSIGNED, Addend, true, 769dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 2); 770dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines resolveRelocation(TargetRE, (uint64_t)Addr); 77136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (Arch == Triple::arm && (RelType & 0xf) == MachO::ARM_RELOC_BR24) { 7720e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // This is an ARM branch relocation, need to use a stub function. 7730e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 7740e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Look up for existing stub. 7750e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StubMap::const_iterator i = Stubs.find(Value); 776dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t *Addr; 777dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (i != Stubs.end()) { 778dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Addr = Section.Address + i->second; 779dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else { 7800e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Create a new stub function. 7810e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Stubs[Value] = Section.StubOffset; 78236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t *StubTargetAddr = 78336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines createStubFunction(Section.Address + Section.StubOffset); 784dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelocationEntry StubRE(SectionID, StubTargetAddr - Section.Address, 785dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::GENERIC_RELOC_VANILLA, Value.Addend); 786c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky if (Value.SymbolName) 787dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines addRelocationForSymbol(StubRE, Value.SymbolName); 788c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky else 789dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines addRelocationForSection(StubRE, Value.SectionID); 790dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Addr = Section.Address + Section.StubOffset; 7910e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Section.StubOffset += getMaxStubSize(); 7920e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } 793dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelocationEntry TargetRE(Value.SectionID, Offset, RelType, 0, IsPCRel, 794dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Size); 795dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines resolveRelocation(TargetRE, (uint64_t)Addr); 796c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky } else { 79736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RelocationEntry RE(SectionID, Offset, RelType, Value.Addend, IsPCRel, Size); 798c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky if (Value.SymbolName) 799c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSymbol(RE, Value.SymbolName); 800c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky else 801c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSection(RE, Value.SectionID); 802c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky } 80336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ++RelI; 804cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 805cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 80636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool 80736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesRuntimeDyldMachO::isCompatibleFormat(const ObjectBuffer *InputBuffer) const { 8083f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor if (InputBuffer->getBufferSize() < 4) 8093f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor return false; 8103f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor StringRef Magic(InputBuffer->getBufferStart(), 4); 81136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Magic == "\xFE\xED\xFA\xCE") 81236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 81336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Magic == "\xCE\xFA\xED\xFE") 81436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 81536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Magic == "\xFE\xED\xFA\xCF") 81636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 81736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Magic == "\xCF\xFA\xED\xFE") 81836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 819cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 820cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 821cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 82236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool RuntimeDyldMachO::isCompatibleFile(const object::ObjectFile *Obj) const { 82336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Obj->isMachO(); 82436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 82536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 826cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} // end namespace llvm 827