RuntimeDyldMachO.cpp revision 528f6d787b1a847e61eb2f1114559f423fdeb68c
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 14cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev#define DEBUG_TYPE "dyld" 15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "RuntimeDyldMachO.h" 16cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev#include "llvm/ADT/OwningPtr.h" 17cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev#include "llvm/ADT/STLExtras.h" 18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/StringRef.h" 19cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevusing namespace llvm; 20cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevusing namespace llvm::object; 21cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 22cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevnamespace llvm { 23cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 24a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindolastatic unsigned char *processFDE(unsigned char *P, intptr_t DeltaForText, intptr_t DeltaForEH) { 25a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola uint32_t Length = *((uint32_t*)P); 26a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola P += 4; 27a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola unsigned char *Ret = P + Length; 28a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola uint32_t Offset = *((uint32_t*)P); 29a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola if (Offset == 0) // is a CIE 30a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola return Ret; 31a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 32a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola P += 4; 33a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola intptr_t FDELocation = *((intptr_t*)P); 34a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola intptr_t NewLocation = FDELocation - DeltaForText; 35a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola *((intptr_t*)P) = NewLocation; 36a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola P += sizeof(intptr_t); 37a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 38a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola // Skip the FDE address range 39a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola P += sizeof(intptr_t); 40a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 41a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola uint8_t Augmentationsize = *P; 42a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola P += 1; 43a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola if (Augmentationsize != 0) { 44a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola intptr_t LSDA = *((intptr_t*)P); 45a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola intptr_t NewLSDA = LSDA - DeltaForEH; 46a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola *((intptr_t*)P) = NewLSDA; 47a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola } 48a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 49a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola return Ret; 50a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola} 51a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 52a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindolastatic intptr_t computeDelta(SectionEntry *A, SectionEntry *B) { 53a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola intptr_t ObjDistance = A->ObjAddress - B->ObjAddress; 54a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola intptr_t MemDistance = A->LoadAddress - B->LoadAddress; 55a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola return ObjDistance - MemDistance; 56a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola} 57a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 58528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylorvoid RuntimeDyldMachO::registerEHFrames() { 59528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor 60528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor if (!MemMgr) 61528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor return; 62528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) { 63528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor EHFrameRelatedSections &SectionInfo = UnregisteredEHFrameSections[i]; 64528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor if (SectionInfo.EHFrameSID == RTDYLD_INVALID_SECTION_ID || 65528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor SectionInfo.TextSID == RTDYLD_INVALID_SECTION_ID) 66528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor continue; 67528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor SectionEntry *Text = &Sections[SectionInfo.TextSID]; 68528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor SectionEntry *EHFrame = &Sections[SectionInfo.EHFrameSID]; 69528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor SectionEntry *ExceptTab = NULL; 70528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor if (SectionInfo.ExceptTabSID != RTDYLD_INVALID_SECTION_ID) 71528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor ExceptTab = &Sections[SectionInfo.ExceptTabSID]; 72528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor 73528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor intptr_t DeltaForText = computeDelta(Text, EHFrame); 74528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor intptr_t DeltaForEH = 0; 75528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor if (ExceptTab) 76528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor DeltaForEH = computeDelta(ExceptTab, EHFrame); 77a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 78528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor unsigned char *P = EHFrame->Address; 79528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor unsigned char *End = P + EHFrame->Size; 80528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor do { 81528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor P = processFDE(P, DeltaForText, DeltaForEH); 82528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor } while(P != End); 83a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 84528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor MemMgr->registerEHFrames(EHFrame->Address, 85528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor EHFrame->LoadAddress, 86528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor EHFrame->Size); 87528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor } 88528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor UnregisteredEHFrameSections.clear(); 89528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor} 90a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 91528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylorvoid RuntimeDyldMachO::finalizeLoad(ObjSectionToIDMap &SectionMap) { 92528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor unsigned EHFrameSID = RTDYLD_INVALID_SECTION_ID; 93528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor unsigned TextSID = RTDYLD_INVALID_SECTION_ID; 94528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor unsigned ExceptTabSID = RTDYLD_INVALID_SECTION_ID; 95528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor ObjSectionToIDMap::iterator i, e; 96528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++i) { 97528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor const SectionRef &Section = i->first; 98528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor StringRef Name; 99528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor Section.getName(Name); 100528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor if (Name == "__eh_frame") 101528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor EHFrameSID = i->second; 102528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor else if (Name == "__text") 103528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor TextSID = i->second; 104528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor else if (Name == "__gcc_except_tab") 105528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor ExceptTabSID = i->second; 106528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor } 107528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor UnregisteredEHFrameSections.push_back(EHFrameRelatedSections(EHFrameSID, 108528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor TextSID, 109528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor ExceptTabSID)); 110a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola} 111a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 11232bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// The target location for the relocation is described by RE.SectionID and 11332bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// RE.Offset. RE.SectionID can be used to find the SectionEntry. Each 11432bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry has three members describing its location. 11532bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry::Address is the address at which the section has been loaded 11632bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// into memory in the current (host) process. SectionEntry::LoadAddress is the 11732bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// address that the section will have in the target process. 11832bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry::ObjAddress is the address of the bits for this section in the 11932bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// original emitted object image (also in the current address space). 12032bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// 12132bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// Relocations will be applied as if the section were loaded at 12232bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry::LoadAddress, but they will be applied at an address based 12332bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// on SectionEntry::Address. SectionEntry::ObjAddress will be used to refer to 12432bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// Target memory contents if they are required for value calculations. 12532bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// 12632bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// The Value parameter here is the load address of the symbol for the 12732bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// relocation to be applied. For relocations which refer to symbols in the 12832bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// current object Value will be the LoadAddress of the section in which 12932bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// the symbol resides (RE.Addend provides additional information about the 13032bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// symbol location). For external symbols, Value will be the address of the 13132bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// symbol in the target address space. 13287b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindolavoid RuntimeDyldMachO::resolveRelocation(const RelocationEntry &RE, 13387b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola uint64_t Value) { 13487b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola const SectionEntry &Section = Sections[RE.SectionID]; 13587b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola return resolveRelocation(Section, RE.Offset, Value, RE.RelType, RE.Addend, 13687b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola RE.IsPCRel, RE.Size); 13787b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola} 13887b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola 139a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylorvoid RuntimeDyldMachO::resolveRelocation(const SectionEntry &Section, 140a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor uint64_t Offset, 1410e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint64_t Value, 1420e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint32_t Type, 14387b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola int64_t Addend, 14487b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola bool isPCRel, 14587b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola unsigned LogSize) { 146a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor uint8_t *LocalAddress = Section.Address + Offset; 147a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor uint64_t FinalAddress = Section.LoadAddress + Offset; 14887b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola unsigned MachoType = Type; 14987b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola unsigned Size = 1 << LogSize; 1500e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 1516d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky DEBUG(dbgs() << "resolveRelocation LocalAddress: " 1526d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky << format("%p", LocalAddress) 1530e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " FinalAddress: " << format("%p", FinalAddress) 1540e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " Value: " << format("%p", Value) 1550e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " Addend: " << Addend 1560e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " isPCRel: " << isPCRel 1570e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " MachoType: " << MachoType 1580e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " Size: " << Size 1590e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << "\n"); 1600e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 161cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // This just dispatches to the proper target specific routine. 1620e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev switch (Arch) { 163858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper default: llvm_unreachable("Unsupported CPU type!"); 1640e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::x86_64: 1650e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev resolveX86_64Relocation(LocalAddress, 1660e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev FinalAddress, 1670e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uintptr_t)Value, 1680e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev isPCRel, 1690e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev MachoType, 1700e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Size, 1710e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Addend); 1720e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 1730e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::x86: 1740e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev resolveI386Relocation(LocalAddress, 1756d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky FinalAddress, 1766d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky (uintptr_t)Value, 1776d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky isPCRel, 178ba9ba9f9bcb8e627ff9cc4bd11904db21762e5a2Jim Grosbach MachoType, 1796d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky Size, 1806d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky Addend); 1810e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 1820e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::arm: // Fall through. 1830e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::thumb: 1840e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev resolveARMRelocation(LocalAddress, 1850e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev FinalAddress, 1860e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uintptr_t)Value, 1870e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev isPCRel, 1880e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev MachoType, 1890e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Size, 1900e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Addend); 1910e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 192cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 193cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 194cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 1956d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::resolveI386Relocation(uint8_t *LocalAddress, 1966d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t FinalAddress, 1976d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t Value, 1986d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky bool isPCRel, 1996d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Type, 2006d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Size, 2016d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky int64_t Addend) { 202b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan if (isPCRel) 203b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan Value -= FinalAddress + 4; // see resolveX86_64Relocation 204b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan 205b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan switch (Type) { 206b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan default: 207b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan llvm_unreachable("Invalid relocation type!"); 2085510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::GENERIC_RELOC_VANILLA: { 209b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan uint8_t *p = LocalAddress; 210b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan uint64_t ValueToWrite = Value + Addend; 211b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan for (unsigned i = 0; i < Size; ++i) { 212b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan *p++ = (uint8_t)(ValueToWrite & 0xff); 213b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan ValueToWrite >>= 8; 214b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan } 2156f6f17197259edbb82cc9b0d800fe0e3cb8e201cJim Grosbach return false; 216b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan } 2175510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::GENERIC_RELOC_SECTDIFF: 2185510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: 2195510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::GENERIC_RELOC_PB_LA_PTR: 220b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan return Error("Relocation type not implemented yet!"); 221b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan } 222b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan} 223b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan 2246d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::resolveX86_64Relocation(uint8_t *LocalAddress, 2256d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t FinalAddress, 2266d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t Value, 2276d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky bool isPCRel, 2286d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Type, 2296d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Size, 2306d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky int64_t Addend) { 231cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the relocation is PC-relative, the value to be encoded is the 232cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // pointer difference. 233cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (isPCRel) 234cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: It seems this value needs to be adjusted by 4 for an effective PC 235cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // address. Is that expected? Only for branches, perhaps? 23661dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Value -= FinalAddress + 4; 237cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 238cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch(Type) { 239cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 240cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 2415510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_SIGNED_1: 2425510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_SIGNED_2: 2435510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_SIGNED_4: 2445510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_SIGNED: 2455510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_UNSIGNED: 2465510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_BRANCH: { 247652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach Value += Addend; 248cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask in the target value a byte at a time (we don't have an alignment 249cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // guarantee for the target address, so this is safest). 25061dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint8_t *p = (uint8_t*)LocalAddress; 251cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i < Size; ++i) { 252cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p++ = (uint8_t)Value; 253cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 8; 254cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 255cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 256cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 2575510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_GOT_LOAD: 2585510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_GOT: 2595510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_SUBTRACTOR: 2605510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_TLV: 261cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Relocation type not implemented yet!"); 262cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 263cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 264cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 2656d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::resolveARMRelocation(uint8_t *LocalAddress, 2666d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t FinalAddress, 2676d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t Value, 2686d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky bool isPCRel, 2696d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Type, 2706d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Size, 2716d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky int64_t Addend) { 272cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the relocation is PC-relative, the value to be encoded is the 273cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // pointer difference. 274cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (isPCRel) { 27561dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Value -= FinalAddress; 276cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // ARM PCRel relocations have an effective-PC offset of two instructions 277cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // (four bytes in Thumb mode, 8 bytes in ARM mode). 278cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: For now, assume ARM mode. 279cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value -= 8; 280cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 281cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 282cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch(Type) { 283cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 284cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 2855510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_VANILLA: { 286cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask in the target value a byte at a time (we don't have an alignment 287cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // guarantee for the target address, so this is safest). 28861dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint8_t *p = (uint8_t*)LocalAddress; 289cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i < Size; ++i) { 290f69a29b23a116a3520f185054290c445abf9aa62Charles Davis *p++ = (uint8_t)Value; 291cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 8; 292cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 293cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 294cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 2955510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_BR24: { 296cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask the value into the target address. We know instructions are 297cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // 32-bit aligned, so we can do it all at once. 29861dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint32_t *p = (uint32_t*)LocalAddress; 299cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // The low two bits of the value are not encoded. 300cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 2; 301cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask the value to 24 bits. 302cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value &= 0xffffff; 303cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: If the destination is a Thumb function (and the instruction 304cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // is a non-predicated BL instruction), we need to change it to a BLX 305cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // instruction instead. 306cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 307cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Insert the value into the instruction. 308cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p = (*p & ~0xffffff) | Value; 309cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 310cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 3115510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_THUMB_RELOC_BR22: 3125510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_THUMB_32BIT_BRANCH: 3135510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_HALF: 3145510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_HALF_SECTDIFF: 3155510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_PAIR: 3165510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_SECTDIFF: 3175510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_LOCAL_SECTDIFF: 3185510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_PB_LA_PTR: 319cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Relocation type not implemented yet!"); 320cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 321cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 322cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 323cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 324efa91f6475f6e96552986104ab4857db46185a2aRafael Espindolavoid RuntimeDyldMachO::processRelocationRef(unsigned SectionID, 325ca0e73610056110e9a175c14dd82d6d616fd830fRafael Espindola RelocationRef RelI, 326689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd ObjectImage &Obj, 3270e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev ObjSectionToIDMap &ObjSectionToID, 328d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky const SymbolTableMap &Symbols, 3290e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StubMap &Stubs) { 330efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola const ObjectFile *OF = Obj.getObjectFile(); 331efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola const MachOObjectFile *MachO = static_cast<const MachOObjectFile*>(OF); 3325510728d28bb1ee04abc32da3d21b7df12948053Charles Davis MachO::any_relocation_info RE= MachO->getRelocation(RelI.getRawDataRefImpl()); 3330e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 334efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola uint32_t RelType = MachO->getAnyRelocationType(RE); 335623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames 336623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames // FIXME: Properly handle scattered relocations. 337623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames // For now, optimistically skip these: they can often be ignored, as 338623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames // the static linker will already have applied the relocation, and it 339623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames // only needs to be reapplied if symbols move relative to one another. 340623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames // Note: This will fail horribly where the relocations *do* need to be 341623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames // applied, but that was already the case. 342623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames if (MachO->isRelocationScattered(RE)) 343623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames return; 344623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames 3450e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev RelocationValueRef Value; 346efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola SectionEntry &Section = Sections[SectionID]; 3470e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 348efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola bool isExtern = MachO->getPlainRelocationExternal(RE); 34987b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola bool IsPCRel = MachO->getAnyRelocationPCRel(RE); 35087b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola unsigned Size = MachO->getAnyRelocationLength(RE); 3518e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola uint64_t Offset; 3528e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola RelI.getOffset(Offset); 353e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola uint8_t *LocalAddress = Section.Address + Offset; 354e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola unsigned NumBytes = 1 << Size; 355e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola uint64_t Addend = 0; 356e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola memcpy(&Addend, LocalAddress, NumBytes); 3578e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola 358e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola if (isExtern) { 359c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // Obtain the symbol name which is referenced in the relocation 3606c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola symbol_iterator Symbol = RelI.getSymbol(); 3610e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StringRef TargetName; 3626c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola Symbol->getName(TargetName); 363c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // First search for the symbol in the local symbol table 364d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky SymbolTableMap::const_iterator lsi = Symbols.find(TargetName.data()); 3650e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (lsi != Symbols.end()) { 3660e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.SectionID = lsi->second.first; 3678e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola Value.Addend = lsi->second.second + Addend; 3680e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } else { 369c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // Search for the symbol in the global symbol table 370d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky SymbolTableMap::const_iterator gsi = GlobalSymbolTable.find(TargetName.data()); 371d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky if (gsi != GlobalSymbolTable.end()) { 3720e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.SectionID = gsi->second.first; 3738e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola Value.Addend = gsi->second.second + Addend; 3748e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola } else { 3750e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.SymbolName = TargetName.data(); 3768e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola Value.Addend = Addend; 3778e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola } 378cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 3790e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } else { 380e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola SectionRef Sec = MachO->getRelocationSection(RE); 381e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola Value.SectionID = findOrEmitSection(Obj, Sec, true, ObjSectionToID); 382e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola uint64_t Addr; 383e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola Sec.getAddress(Addr); 384e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola Value.Addend = Addend - Addr; 385288967dfac246c8e35dc4f85afb667e74d1d26a8Bill Wendling } 386288967dfac246c8e35dc4f85afb667e74d1d26a8Bill Wendling 3875510728d28bb1ee04abc32da3d21b7df12948053Charles Davis if (Arch == Triple::x86_64 && (RelType == MachO::X86_64_RELOC_GOT || 3885510728d28bb1ee04abc32da3d21b7df12948053Charles Davis RelType == MachO::X86_64_RELOC_GOT_LOAD)) { 389a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola assert(IsPCRel); 390a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola assert(Size == 2); 391a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola StubMap::const_iterator i = Stubs.find(Value); 392a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola uint8_t *Addr; 393a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola if (i != Stubs.end()) { 394a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola Addr = Section.Address + i->second; 395a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola } else { 396a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola Stubs[Value] = Section.StubOffset; 397a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola uint8_t *GOTEntry = Section.Address + Section.StubOffset; 398a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola RelocationEntry RE(SectionID, Section.StubOffset, 3995510728d28bb1ee04abc32da3d21b7df12948053Charles Davis MachO::X86_64_RELOC_UNSIGNED, 0, false, 3); 400a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola if (Value.SymbolName) 401a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola addRelocationForSymbol(RE, Value.SymbolName); 402a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola else 403a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola addRelocationForSection(RE, Value.SectionID); 404a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola Section.StubOffset += 8; 405a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola Addr = GOTEntry; 406a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola } 407a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola resolveRelocation(Section, Offset, (uint64_t)Addr, 4085510728d28bb1ee04abc32da3d21b7df12948053Charles Davis MachO::X86_64_RELOC_UNSIGNED, Value.Addend, true, 2); 409a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola } else if (Arch == Triple::arm && 4105510728d28bb1ee04abc32da3d21b7df12948053Charles Davis (RelType & 0xf) == MachO::ARM_RELOC_BR24) { 4110e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // This is an ARM branch relocation, need to use a stub function. 4120e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 4130e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Look up for existing stub. 4140e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StubMap::const_iterator i = Stubs.find(Value); 4150e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (i != Stubs.end()) 416efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola resolveRelocation(Section, Offset, 4170e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uint64_t)Section.Address + i->second, 41887b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola RelType, 0, IsPCRel, Size); 4190e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev else { 4200e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Create a new stub function. 4210e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Stubs[Value] = Section.StubOffset; 4220e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint8_t *StubTargetAddr = createStubFunction(Section.Address + 4230e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Section.StubOffset); 424efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola RelocationEntry RE(SectionID, StubTargetAddr - Section.Address, 4255510728d28bb1ee04abc32da3d21b7df12948053Charles Davis MachO::GENERIC_RELOC_VANILLA, Value.Addend); 426c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky if (Value.SymbolName) 427c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSymbol(RE, Value.SymbolName); 428c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky else 429c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSection(RE, Value.SectionID); 430efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola resolveRelocation(Section, Offset, 4310e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uint64_t)Section.Address + Section.StubOffset, 43287b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola RelType, 0, IsPCRel, Size); 4330e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Section.StubOffset += getMaxStubSize(); 4340e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } 435c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky } else { 43687b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola RelocationEntry RE(SectionID, Offset, RelType, Value.Addend, 43787b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola IsPCRel, Size); 438c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky if (Value.SymbolName) 439c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSymbol(RE, Value.SymbolName); 440c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky else 441c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSection(RE, Value.SectionID); 442c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky } 443cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 444cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 445cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 4466d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::isCompatibleFormat( 4473f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor const ObjectBuffer *InputBuffer) const { 4483f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor if (InputBuffer->getBufferSize() < 4) 4493f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor return false; 4503f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor StringRef Magic(InputBuffer->getBufferStart(), 4); 451cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xFE\xED\xFA\xCE") return true; 452cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xCE\xFA\xED\xFE") return true; 453cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xFE\xED\xFA\xCF") return true; 454cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xCF\xFA\xED\xFE") return true; 455cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 456cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 457cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 458cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} // end namespace llvm 459