RuntimeDyldMachO.cpp revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
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" 17cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevusing namespace llvm; 18cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevusing namespace llvm::object; 19cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 20dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "dyld" 21dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 22cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevnamespace llvm { 23cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic unsigned char *processFDE(unsigned char *P, intptr_t DeltaForText, 2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines intptr_t DeltaForEH) { 26dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(dbgs() << "Processing FDE: Delta for text: " << DeltaForText 27dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << ", Delta for EH: " << DeltaForEH << "\n"); 2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Length = *((uint32_t *)P); 29a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola P += 4; 30a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola unsigned char *Ret = P + Length; 3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Offset = *((uint32_t *)P); 32a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola if (Offset == 0) // is a CIE 33a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola return Ret; 34a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 35a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola P += 4; 3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines intptr_t FDELocation = *((intptr_t *)P); 37a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola intptr_t NewLocation = FDELocation - DeltaForText; 3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *((intptr_t *)P) = NewLocation; 39a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola P += sizeof(intptr_t); 40a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 41a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola // Skip the FDE address range 42a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola P += sizeof(intptr_t); 43a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 44a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola uint8_t Augmentationsize = *P; 45a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola P += 1; 46a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola if (Augmentationsize != 0) { 4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines intptr_t LSDA = *((intptr_t *)P); 48a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola intptr_t NewLSDA = LSDA - DeltaForEH; 4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *((intptr_t *)P) = NewLSDA; 50a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola } 51a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 52a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola return Ret; 53a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola} 54a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 55a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindolastatic intptr_t computeDelta(SectionEntry *A, SectionEntry *B) { 5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines intptr_t ObjDistance = A->ObjAddress - B->ObjAddress; 57a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola intptr_t MemDistance = A->LoadAddress - B->LoadAddress; 58a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola return ObjDistance - MemDistance; 59a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola} 60a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 61528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylorvoid RuntimeDyldMachO::registerEHFrames() { 62528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor 63528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor if (!MemMgr) 64528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor return; 65528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) { 66528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor EHFrameRelatedSections &SectionInfo = UnregisteredEHFrameSections[i]; 67528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor if (SectionInfo.EHFrameSID == RTDYLD_INVALID_SECTION_ID || 68528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor SectionInfo.TextSID == RTDYLD_INVALID_SECTION_ID) 69528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor continue; 70528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor SectionEntry *Text = &Sections[SectionInfo.TextSID]; 71528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor SectionEntry *EHFrame = &Sections[SectionInfo.EHFrameSID]; 72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SectionEntry *ExceptTab = nullptr; 73528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor if (SectionInfo.ExceptTabSID != RTDYLD_INVALID_SECTION_ID) 74528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor ExceptTab = &Sections[SectionInfo.ExceptTabSID]; 75528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor 76528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor intptr_t DeltaForText = computeDelta(Text, EHFrame); 77528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor intptr_t DeltaForEH = 0; 78528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor if (ExceptTab) 79528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor DeltaForEH = computeDelta(ExceptTab, EHFrame); 80a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 81528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor unsigned char *P = EHFrame->Address; 82528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor unsigned char *End = P + EHFrame->Size; 8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines do { 84528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor P = processFDE(P, DeltaForText, DeltaForEH); 8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } while (P != End); 86a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MemMgr->registerEHFrames(EHFrame->Address, EHFrame->LoadAddress, 88528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor EHFrame->Size); 89528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor } 90528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor UnregisteredEHFrameSections.clear(); 91528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor} 92a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 93dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid RuntimeDyldMachO::finalizeLoad(ObjectImage &ObjImg, 94dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjSectionToIDMap &SectionMap) { 95528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor unsigned EHFrameSID = RTDYLD_INVALID_SECTION_ID; 96528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor unsigned TextSID = RTDYLD_INVALID_SECTION_ID; 97528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor unsigned ExceptTabSID = RTDYLD_INVALID_SECTION_ID; 98528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor ObjSectionToIDMap::iterator i, e; 99528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++i) { 100528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor const SectionRef &Section = i->first; 101528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor StringRef Name; 102528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor Section.getName(Name); 103528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor if (Name == "__eh_frame") 104528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor EHFrameSID = i->second; 105528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor else if (Name == "__text") 106528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor TextSID = i->second; 107528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor else if (Name == "__gcc_except_tab") 108528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor ExceptTabSID = i->second; 109dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else if (Name == "__jump_table") 110dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines populateJumpTable(cast<MachOObjectFile>(*ObjImg.getObjectFile()), 111dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Section, i->second); 112dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else if (Name == "__pointers") 113dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines populatePointersSection(cast<MachOObjectFile>(*ObjImg.getObjectFile()), 114dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Section, i->second); 115528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor } 11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines UnregisteredEHFrameSections.push_back( 11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EHFrameRelatedSections(EHFrameSID, TextSID, ExceptTabSID)); 118a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola} 119a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 12032bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// The target location for the relocation is described by RE.SectionID and 12132bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// RE.Offset. RE.SectionID can be used to find the SectionEntry. Each 12232bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry has three members describing its location. 12332bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry::Address is the address at which the section has been loaded 12432bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// into memory in the current (host) process. SectionEntry::LoadAddress is the 12532bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// address that the section will have in the target process. 12632bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry::ObjAddress is the address of the bits for this section in the 12732bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// original emitted object image (also in the current address space). 12832bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// 12932bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// Relocations will be applied as if the section were loaded at 13032bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// SectionEntry::LoadAddress, but they will be applied at an address based 13132bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// on SectionEntry::Address. SectionEntry::ObjAddress will be used to refer to 13232bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// Target memory contents if they are required for value calculations. 13332bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// 13432bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// The Value parameter here is the load address of the symbol for the 13532bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// relocation to be applied. For relocations which refer to symbols in the 13632bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// current object Value will be the LoadAddress of the section in which 13732bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// the symbol resides (RE.Addend provides additional information about the 13832bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// symbol location). For external symbols, Value will be the address of the 13932bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor// symbol in the target address space. 14087b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindolavoid RuntimeDyldMachO::resolveRelocation(const RelocationEntry &RE, 14187b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola uint64_t Value) { 142dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG ( 143dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const SectionEntry &Section = Sections[RE.SectionID]; 144dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t* LocalAddress = Section.Address + RE.Offset; 145dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t FinalAddress = Section.LoadAddress + RE.Offset; 146dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 147dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines dbgs() << "resolveRelocation Section: " << RE.SectionID 148dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << " LocalAddress: " << format("%p", LocalAddress) 149dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << " FinalAddress: " << format("%p", FinalAddress) 150dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << " Value: " << format("%p", Value) 151dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << " Addend: " << RE.Addend 152dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << " isPCRel: " << RE.IsPCRel 153dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << " MachoType: " << RE.RelType 154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << " Size: " << (1 << RE.Size) << "\n"; 155dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ); 1560e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 157cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // This just dispatches to the proper target specific routine. 1580e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev switch (Arch) { 15936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines llvm_unreachable("Unsupported CPU type!"); 1610e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::x86_64: 162dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines resolveX86_64Relocation(RE, Value); 1630e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 1640e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::x86: 165dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines resolveI386Relocation(RE, Value); 1660e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Triple::arm: // Fall through. 1680e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::thumb: 169dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines resolveARMRelocation(RE, Value); 17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 171dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case Triple::aarch64: 17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Triple::arm64: 173dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines resolveAArch64Relocation(RE, Value); 1740e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 175cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 176cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 177cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 178dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool RuntimeDyldMachO::resolveI386Relocation(const RelocationEntry &RE, 179dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Value) { 180dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const SectionEntry &Section = Sections[RE.SectionID]; 181dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t* LocalAddress = Section.Address + RE.Offset; 182b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan 183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (RE.IsPCRel) { 184dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t FinalAddress = Section.LoadAddress + RE.Offset; 185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value -= FinalAddress + 4; // see MachOX86_64::resolveRelocation. 186b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan } 187dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 188dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines switch (RE.RelType) { 189dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines default: 190dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines llvm_unreachable("Invalid relocation type!"); 191dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case MachO::GENERIC_RELOC_VANILLA: 192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return applyRelocationValue(LocalAddress, Value + RE.Addend, 193dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1 << RE.Size); 194dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case MachO::GENERIC_RELOC_SECTDIFF: 195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: { 196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t SectionABase = Sections[RE.Sections.SectionA].LoadAddress; 197dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t SectionBBase = Sections[RE.Sections.SectionB].LoadAddress; 198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert((Value == SectionABase || Value == SectionBBase) && 199dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "Unexpected SECTDIFF relocation value."); 200dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value = SectionABase - SectionBBase + RE.Addend; 201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return applyRelocationValue(LocalAddress, Value, 1 << RE.Size); 202dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 203dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case MachO::GENERIC_RELOC_PB_LA_PTR: 204dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return Error("Relocation type not implemented yet!"); 205b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan } 206b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan} 207b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan 208dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool RuntimeDyldMachO::resolveX86_64Relocation(const RelocationEntry &RE, 209dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Value) { 210dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const SectionEntry &Section = Sections[RE.SectionID]; 211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t* LocalAddress = Section.Address + RE.Offset; 212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 213cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the relocation is PC-relative, the value to be encoded is the 214cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // pointer difference. 215dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (RE.IsPCRel) { 216cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: It seems this value needs to be adjusted by 4 for an effective PC 217cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // address. Is that expected? Only for branches, perhaps? 218dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t FinalAddress = Section.LoadAddress + RE.Offset; 219dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value -= FinalAddress + 4; // see MachOX86_64::resolveRelocation. 220dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 221cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 222dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines switch (RE.RelType) { 223cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 224cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 2255510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_SIGNED_1: 2265510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_SIGNED_2: 2275510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_SIGNED_4: 2285510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_SIGNED: 2295510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_UNSIGNED: 230dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case MachO::X86_64_RELOC_BRANCH: 231dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return applyRelocationValue(LocalAddress, Value + RE.Addend, 1 << RE.Size); 2325510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_GOT_LOAD: 2335510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_GOT: 2345510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_SUBTRACTOR: 2355510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::X86_64_RELOC_TLV: 236cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Relocation type not implemented yet!"); 237cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 238cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 239cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 240dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool RuntimeDyldMachO::resolveARMRelocation(const RelocationEntry &RE, 241dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Value) { 242dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const SectionEntry &Section = Sections[RE.SectionID]; 243dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t* LocalAddress = Section.Address + RE.Offset; 244dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 245cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the relocation is PC-relative, the value to be encoded is the 246cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // pointer difference. 247dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (RE.IsPCRel) { 248dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t FinalAddress = Section.LoadAddress + RE.Offset; 24961dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Value -= FinalAddress; 250cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // ARM PCRel relocations have an effective-PC offset of two instructions 251cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // (four bytes in Thumb mode, 8 bytes in ARM mode). 252cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: For now, assume ARM mode. 253cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value -= 8; 254cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 255cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 256dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines switch (RE.RelType) { 257cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 258cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 259dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case MachO::ARM_RELOC_VANILLA: 260dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return applyRelocationValue(LocalAddress, Value, 1 << RE.Size); 2615510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_BR24: { 262cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask the value into the target address. We know instructions are 263cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // 32-bit aligned, so we can do it all at once. 26436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t *p = (uint32_t *)LocalAddress; 265cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // The low two bits of the value are not encoded. 266cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 2; 267cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask the value to 24 bits. 268dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t FinalValue = Value & 0xffffff; 269dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Check for overflow. 270dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Value != FinalValue) 271dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return Error("ARM BR24 relocation out of range."); 272cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: If the destination is a Thumb function (and the instruction 273cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // is a non-predicated BL instruction), we need to change it to a BLX 274cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // instruction instead. 275cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 276cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Insert the value into the instruction. 277dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *p = (*p & ~0xffffff) | FinalValue; 278cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 279cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 2805510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_THUMB_RELOC_BR22: 2815510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_THUMB_32BIT_BRANCH: 2825510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_HALF: 2835510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_HALF_SECTDIFF: 2845510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_PAIR: 2855510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_SECTDIFF: 2865510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_LOCAL_SECTDIFF: 2875510728d28bb1ee04abc32da3d21b7df12948053Charles Davis case MachO::ARM_RELOC_PB_LA_PTR: 288cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Relocation type not implemented yet!"); 289cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 290cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 291cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 292cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 293dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool RuntimeDyldMachO::resolveAArch64Relocation(const RelocationEntry &RE, 294dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Value) { 295dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const SectionEntry &Section = Sections[RE.SectionID]; 296dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t* LocalAddress = Section.Address + RE.Offset; 297dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 29836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // If the relocation is PC-relative, the value to be encoded is the 29936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // pointer difference. 300dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (RE.IsPCRel) { 301dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t FinalAddress = Section.LoadAddress + RE.Offset; 30236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value -= FinalAddress; 303dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 30436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 305dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines switch (RE.RelType) { 30636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 30736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines llvm_unreachable("Invalid relocation type!"); 308dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case MachO::ARM64_RELOC_UNSIGNED: 309dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return applyRelocationValue(LocalAddress, Value, 1 << RE.Size); 31036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::ARM64_RELOC_BRANCH26: { 31136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Mask the value into the target address. We know instructions are 31236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 32-bit aligned, so we can do it all at once. 31336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t *p = (uint32_t *)LocalAddress; 31436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The low two bits of the value are not encoded. 31536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value >>= 2; 31636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Mask the value to 26 bits. 317dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t FinalValue = Value & 0x3ffffff; 318dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Check for overflow. 319dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (FinalValue != Value) 320dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return Error("ARM64 BRANCH26 relocation out of range."); 32136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Insert the value into the instruction. 322dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *p = (*p & ~0x3ffffff) | FinalValue; 32336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 32436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::ARM64_RELOC_SUBTRACTOR: 32636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::ARM64_RELOC_PAGE21: 32736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::ARM64_RELOC_PAGEOFF12: 32836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::ARM64_RELOC_GOT_LOAD_PAGE21: 32936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12: 33036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::ARM64_RELOC_POINTER_TO_GOT: 33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21: 33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12: 33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MachO::ARM64_RELOC_ADDEND: 33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Error("Relocation type not implemented yet!"); 33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 33736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 33836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 339dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid RuntimeDyldMachO::populateJumpTable(MachOObjectFile &Obj, 340dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const SectionRef &JTSection, 341dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned JTSectionID) { 342dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(!Obj.is64Bit() && 343dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "__jump_table section not supported in 64-bit MachO."); 344dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 345dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::dysymtab_command DySymTabCmd = Obj.getDysymtabLoadCommand(); 346dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::section Sec32 = Obj.getSection(JTSection.getRawDataRefImpl()); 347dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t JTSectionSize = Sec32.size; 348dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned FirstIndirectSymbol = Sec32.reserved1; 349dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned JTEntrySize = Sec32.reserved2; 350dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned NumJTEntries = JTSectionSize / JTEntrySize; 351dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t* JTSectionAddr = getSectionAddress(JTSectionID); 352dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned JTEntryOffset = 0; 353dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 354dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert((JTSectionSize % JTEntrySize) == 0 && 355dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "Jump-table section does not contain a whole number of stubs?"); 356dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 357dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (unsigned i = 0; i < NumJTEntries; ++i) { 358dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned SymbolIndex = 359dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Obj.getIndirectSymbolTableEntry(DySymTabCmd, FirstIndirectSymbol + i); 360dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines symbol_iterator SI = Obj.getSymbolByIndex(SymbolIndex); 361dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines StringRef IndirectSymbolName; 362dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SI->getName(IndirectSymbolName); 363dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t* JTEntryAddr = JTSectionAddr + JTEntryOffset; 364dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines createStubFunction(JTEntryAddr); 365dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelocationEntry RE(JTSectionID, JTEntryOffset + 1, 366dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::GENERIC_RELOC_VANILLA, 0, true, 2); 367dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines addRelocationForSymbol(RE, IndirectSymbolName); 368dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines JTEntryOffset += JTEntrySize; 369dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 370dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 371dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 372dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid RuntimeDyldMachO::populatePointersSection(MachOObjectFile &Obj, 373dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const SectionRef &PTSection, 374dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned PTSectionID) { 375dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(!Obj.is64Bit() && 376dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "__pointers section not supported in 64-bit MachO."); 377dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 378dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::dysymtab_command DySymTabCmd = Obj.getDysymtabLoadCommand(); 379dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::section Sec32 = Obj.getSection(PTSection.getRawDataRefImpl()); 380dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t PTSectionSize = Sec32.size; 381dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned FirstIndirectSymbol = Sec32.reserved1; 382dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const unsigned PTEntrySize = 4; 383dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned NumPTEntries = PTSectionSize / PTEntrySize; 384dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned PTEntryOffset = 0; 385dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 386dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert((PTSectionSize % PTEntrySize) == 0 && 387dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "Pointers section does not contain a whole number of stubs?"); 388dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 389dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(dbgs() << "Populating __pointers, Section ID " << PTSectionID 390dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << ", " << NumPTEntries << " entries, " 391dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << PTEntrySize << " bytes each:\n"); 392dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 393dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (unsigned i = 0; i < NumPTEntries; ++i) { 394dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned SymbolIndex = 395dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Obj.getIndirectSymbolTableEntry(DySymTabCmd, FirstIndirectSymbol + i); 396dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines symbol_iterator SI = Obj.getSymbolByIndex(SymbolIndex); 397dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines StringRef IndirectSymbolName; 398dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SI->getName(IndirectSymbolName); 399dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(dbgs() << " " << IndirectSymbolName << ": index " << SymbolIndex 400dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << ", PT offset: " << PTEntryOffset << "\n"); 401dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelocationEntry RE(PTSectionID, PTEntryOffset, 402dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::GENERIC_RELOC_VANILLA, 0, false, 2); 403dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines addRelocationForSymbol(RE, IndirectSymbolName); 404dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines PTEntryOffset += PTEntrySize; 405dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 406dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 407dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 408dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 409dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinessection_iterator getSectionByAddress(const MachOObjectFile &Obj, 410dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Addr) { 411dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines section_iterator SI = Obj.section_begin(); 412dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines section_iterator SE = Obj.section_end(); 413dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 414dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (; SI != SE; ++SI) { 415dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t SAddr, SSize; 416dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SI->getAddress(SAddr); 417dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SI->getSize(SSize); 418dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if ((Addr >= SAddr) && (Addr < SAddr + SSize)) 419dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return SI; 420dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 421dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 422dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return SE; 423dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 424dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 425dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesrelocation_iterator RuntimeDyldMachO::processSECTDIFFRelocation( 426dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned SectionID, 427dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines relocation_iterator RelI, 428dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjectImage &Obj, 429dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjSectionToIDMap &ObjSectionToID) { 430dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MachOObjectFile *MachO = 431dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines static_cast<const MachOObjectFile*>(Obj.getObjectFile()); 432dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::any_relocation_info RE = 433dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO->getRelocation(RelI->getRawDataRefImpl()); 434dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 435dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SectionEntry &Section = Sections[SectionID]; 436dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t RelocType = MachO->getAnyRelocationType(RE); 437dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool IsPCRel = MachO->getAnyRelocationPCRel(RE); 438dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned Size = MachO->getAnyRelocationLength(RE); 439dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Offset; 440dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelI->getOffset(Offset); 441dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t *LocalAddress = Section.Address + Offset; 442dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned NumBytes = 1 << Size; 443dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines int64_t Addend = 0; 444dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines memcpy(&Addend, LocalAddress, NumBytes); 445dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 446dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ++RelI; 447dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::any_relocation_info RE2 = 448dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO->getRelocation(RelI->getRawDataRefImpl()); 449dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 450dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t AddrA = MachO->getScatteredRelocationValue(RE); 451dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines section_iterator SAI = getSectionByAddress(*MachO, AddrA); 452dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(SAI != MachO->section_end() && "Can't find section for address A"); 453dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t SectionABase; 454dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SAI->getAddress(SectionABase); 455dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t SectionAOffset = AddrA - SectionABase; 456dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SectionRef SectionA = *SAI; 457dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool IsCode; 458dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SectionA.isText(IsCode); 459dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t SectionAID = findOrEmitSection(Obj, SectionA, IsCode, 460dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjSectionToID); 461dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 462dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t AddrB = MachO->getScatteredRelocationValue(RE2); 463dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines section_iterator SBI = getSectionByAddress(*MachO, AddrB); 464dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(SBI != MachO->section_end() && "Can't find section for address B"); 465dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t SectionBBase; 466dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SBI->getAddress(SectionBBase); 467dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t SectionBOffset = AddrB - SectionBBase; 468dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SectionRef SectionB = *SBI; 469dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t SectionBID = findOrEmitSection(Obj, SectionB, IsCode, 470dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjSectionToID); 471dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 472dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Addend != AddrA - AddrB) 473dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Error("Unexpected SECTDIFF relocation addend."); 474dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 475dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(dbgs() << "Found SECTDIFF: AddrA: " << AddrA << ", AddrB: " << AddrB 476dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << ", Addend: " << Addend << ", SectionA ID: " 477dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << SectionAID << ", SectionAOffset: " << SectionAOffset 478dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << ", SectionB ID: " << SectionBID << ", SectionBOffset: " 479dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << SectionBOffset << "\n"); 480dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelocationEntry R(SectionID, Offset, RelocType, 0, 481dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SectionAID, SectionAOffset, SectionBID, SectionBOffset, 482dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IsPCRel, Size); 483dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 484dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines addRelocationForSection(R, SectionAID); 485dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines addRelocationForSection(R, SectionBID); 486dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 487dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return ++RelI; 488dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 489dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 490dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesrelocation_iterator RuntimeDyldMachO::processI386ScatteredVANILLA( 491dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned SectionID, 492dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines relocation_iterator RelI, 493dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjectImage &Obj, 494dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjSectionToIDMap &ObjSectionToID) { 495dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MachOObjectFile *MachO = 496dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines static_cast<const MachOObjectFile*>(Obj.getObjectFile()); 497dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::any_relocation_info RE = 498dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO->getRelocation(RelI->getRawDataRefImpl()); 499dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 500dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SectionEntry &Section = Sections[SectionID]; 501dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t RelocType = MachO->getAnyRelocationType(RE); 502dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool IsPCRel = MachO->getAnyRelocationPCRel(RE); 503dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned Size = MachO->getAnyRelocationLength(RE); 504dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Offset; 505dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelI->getOffset(Offset); 506dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t *LocalAddress = Section.Address + Offset; 507dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned NumBytes = 1 << Size; 508dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines int64_t Addend = 0; 509dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines memcpy(&Addend, LocalAddress, NumBytes); 510dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 511dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned SymbolBaseAddr = MachO->getScatteredRelocationValue(RE); 512dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines section_iterator TargetSI = getSectionByAddress(*MachO, SymbolBaseAddr); 513dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(TargetSI != MachO->section_end() && "Can't find section for symbol"); 514dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t SectionBaseAddr; 515dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TargetSI->getAddress(SectionBaseAddr); 516dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SectionRef TargetSection = *TargetSI; 517dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool IsCode; 518dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TargetSection.isText(IsCode); 519dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t TargetSectionID = findOrEmitSection(Obj, TargetSection, IsCode, 520dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjSectionToID); 521dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 522dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Addend -= SectionBaseAddr; 523dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelocationEntry R(SectionID, Offset, RelocType, Addend, 524dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IsPCRel, Size); 525dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 526dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines addRelocationForSection(R, TargetSectionID); 527dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 528dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return ++RelI; 529dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 530dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 53136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesrelocation_iterator RuntimeDyldMachO::processRelocationRef( 53236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned SectionID, relocation_iterator RelI, ObjectImage &Obj, 53336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols, 53436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StubMap &Stubs) { 535efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola const ObjectFile *OF = Obj.getObjectFile(); 53636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MachOObjectFile *MachO = static_cast<const MachOObjectFile *>(OF); 53736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachO::any_relocation_info RE = 53836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachO->getRelocation(RelI->getRawDataRefImpl()); 5390e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 540efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola uint32_t RelType = MachO->getAnyRelocationType(RE); 541623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames 542623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames // FIXME: Properly handle scattered relocations. 543dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Special case the couple of scattered relocations that we know how 544dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // to handle: SECTDIFF relocations, and scattered VANILLA relocations 545dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // on I386. 546dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // For all other scattered relocations, just bail out and hope for the 547dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // best, since the offsets computed by scattered relocations have often 548dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // been optimisticaly filled in by the compiler. This will fail 549dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // horribly where the relocations *do* need to be applied, but that was 550dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // already the case. 551dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (MachO->isRelocationScattered(RE)) { 552dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (RelType == MachO::GENERIC_RELOC_SECTDIFF || 553dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelType == MachO::GENERIC_RELOC_LOCAL_SECTDIFF) 554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return processSECTDIFFRelocation(SectionID, RelI, Obj, ObjSectionToID); 555dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else if (Arch == Triple::x86 && RelType == MachO::GENERIC_RELOC_VANILLA) 556dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return processI386ScatteredVANILLA(SectionID, RelI, Obj, ObjSectionToID); 557dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else 558dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return ++RelI; 559dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 560623f2025a7a32de68a5ab402aa2b50ca3e3a6958Lang Hames 5610e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev RelocationValueRef Value; 562efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola SectionEntry &Section = Sections[SectionID]; 5630e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 564dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool IsExtern = MachO->getPlainRelocationExternal(RE); 56587b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola bool IsPCRel = MachO->getAnyRelocationPCRel(RE); 56687b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola unsigned Size = MachO->getAnyRelocationLength(RE); 5678e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola uint64_t Offset; 56836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RelI->getOffset(Offset); 569e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola uint8_t *LocalAddress = Section.Address + Offset; 570e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola unsigned NumBytes = 1 << Size; 571e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola uint64_t Addend = 0; 572e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola memcpy(&Addend, LocalAddress, NumBytes); 5738e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola 574dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (IsExtern) { 575c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // Obtain the symbol name which is referenced in the relocation 57636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines symbol_iterator Symbol = RelI->getSymbol(); 5770e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StringRef TargetName; 5786c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola Symbol->getName(TargetName); 579c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // First search for the symbol in the local symbol table 580d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky SymbolTableMap::const_iterator lsi = Symbols.find(TargetName.data()); 5810e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (lsi != Symbols.end()) { 5820e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.SectionID = lsi->second.first; 5838e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola Value.Addend = lsi->second.second + Addend; 5840e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } else { 585c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // Search for the symbol in the global symbol table 58636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SymbolTableMap::const_iterator gsi = 58736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GlobalSymbolTable.find(TargetName.data()); 588d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky if (gsi != GlobalSymbolTable.end()) { 5890e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.SectionID = gsi->second.first; 5908e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola Value.Addend = gsi->second.second + Addend; 5918e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola } else { 5920e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.SymbolName = TargetName.data(); 5938e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola Value.Addend = Addend; 5948e6e02a41bd21f8e919e812dbd7aa9ed5474bdbfRafael Espindola } 595cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 596dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 597dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Addends for external, PC-rel relocations on i386 point back to the zero 598dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // offset. Calculate the final offset from the relocation target instead. 599dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // This allows us to use the same logic for both external and internal 600dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // relocations in resolveI386RelocationRef. 601dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Arch == Triple::x86 && IsPCRel) { 602dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t RelocAddr = 0; 603dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelI->getAddress(RelocAddr); 604dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value.Addend += RelocAddr + 4; 605dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 606dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 6070e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } else { 608e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola SectionRef Sec = MachO->getRelocationSection(RE); 60936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool IsCode = false; 61036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Sec.isText(IsCode); 61136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value.SectionID = findOrEmitSection(Obj, Sec, IsCode, ObjSectionToID); 612e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola uint64_t Addr; 613e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola Sec.getAddress(Addr); 614e87dadc44b1544c35e13cf48dfe167109929a944Rafael Espindola Value.Addend = Addend - Addr; 61536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IsPCRel) 61636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value.Addend += Offset + NumBytes; 617288967dfac246c8e35dc4f85afb667e74d1d26a8Bill Wendling } 618288967dfac246c8e35dc4f85afb667e74d1d26a8Bill Wendling 6195510728d28bb1ee04abc32da3d21b7df12948053Charles Davis if (Arch == Triple::x86_64 && (RelType == MachO::X86_64_RELOC_GOT || 6205510728d28bb1ee04abc32da3d21b7df12948053Charles Davis RelType == MachO::X86_64_RELOC_GOT_LOAD)) { 621a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola assert(IsPCRel); 622a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola assert(Size == 2); 623dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 624dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // FIXME: Teach the generic code above not to prematurely conflate 625dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // relocation addends and symbol offsets. 626dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value.Addend -= Addend; 627a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola StubMap::const_iterator i = Stubs.find(Value); 628a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola uint8_t *Addr; 629a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola if (i != Stubs.end()) { 630a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola Addr = Section.Address + i->second; 631a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola } else { 632a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola Stubs[Value] = Section.StubOffset; 633a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola uint8_t *GOTEntry = Section.Address + Section.StubOffset; 634dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelocationEntry GOTRE(SectionID, Section.StubOffset, 635dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::X86_64_RELOC_UNSIGNED, Value.Addend, false, 636dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 3); 637a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola if (Value.SymbolName) 638dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines addRelocationForSymbol(GOTRE, Value.SymbolName); 639a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola else 640dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines addRelocationForSection(GOTRE, Value.SectionID); 641a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola Section.StubOffset += 8; 642a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola Addr = GOTEntry; 643a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola } 644dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelocationEntry TargetRE(SectionID, Offset, 645dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::X86_64_RELOC_UNSIGNED, Addend, true, 646dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 2); 647dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines resolveRelocation(TargetRE, (uint64_t)Addr); 64836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (Arch == Triple::arm && (RelType & 0xf) == MachO::ARM_RELOC_BR24) { 6490e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // This is an ARM branch relocation, need to use a stub function. 6500e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 6510e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Look up for existing stub. 6520e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StubMap::const_iterator i = Stubs.find(Value); 653dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint8_t *Addr; 654dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (i != Stubs.end()) { 655dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Addr = Section.Address + i->second; 656dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else { 6570e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Create a new stub function. 6580e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Stubs[Value] = Section.StubOffset; 65936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t *StubTargetAddr = 66036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines createStubFunction(Section.Address + Section.StubOffset); 661dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelocationEntry StubRE(SectionID, StubTargetAddr - Section.Address, 662dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachO::GENERIC_RELOC_VANILLA, Value.Addend); 663c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky if (Value.SymbolName) 664dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines addRelocationForSymbol(StubRE, Value.SymbolName); 665c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky else 666dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines addRelocationForSection(StubRE, Value.SectionID); 667dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Addr = Section.Address + Section.StubOffset; 6680e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Section.StubOffset += getMaxStubSize(); 6690e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } 670dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RelocationEntry TargetRE(Value.SectionID, Offset, RelType, 0, IsPCRel, 671dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Size); 672dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines resolveRelocation(TargetRE, (uint64_t)Addr); 673c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky } else { 67436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RelocationEntry RE(SectionID, Offset, RelType, Value.Addend, IsPCRel, Size); 675c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky if (Value.SymbolName) 676c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSymbol(RE, Value.SymbolName); 677c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky else 678c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSection(RE, Value.SectionID); 679c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky } 68036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ++RelI; 681cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 682cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 68336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool 68436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesRuntimeDyldMachO::isCompatibleFormat(const ObjectBuffer *InputBuffer) const { 6853f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor if (InputBuffer->getBufferSize() < 4) 6863f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor return false; 6873f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor StringRef Magic(InputBuffer->getBufferStart(), 4); 68836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Magic == "\xFE\xED\xFA\xCE") 68936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 69036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Magic == "\xCE\xFA\xED\xFE") 69136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 69236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Magic == "\xFE\xED\xFA\xCF") 69336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 69436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Magic == "\xCF\xFA\xED\xFE") 69536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 696cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 697cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 698cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 69936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool RuntimeDyldMachO::isCompatibleFile(const object::ObjectFile *Obj) const { 70036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Obj->isMachO(); 70136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 70236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 703cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} // end namespace llvm 704