RuntimeDyldMachO.cpp revision 3e29671cca14f8fce1ea6b602175880cb3df7199
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" 15cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev#include "llvm/ADT/OwningPtr.h" 16cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev#include "llvm/ADT/StringRef.h" 17cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev#include "llvm/ADT/STLExtras.h" 1876463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky#include "RuntimeDyldMachO.h" 19cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevusing namespace llvm; 20cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevusing namespace llvm::object; 21cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 22cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevnamespace llvm { 23cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 243e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruthbool RuntimeDyldMachO:: 253e29671cca14f8fce1ea6b602175880cb3df7199Chandler CarruthresolveRelocation(uint8_t *LocalAddress, 263e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint64_t FinalAddress, 273e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint64_t Value, 283e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth bool isPCRel, 293e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth unsigned Type, 303e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth unsigned Size, 313e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth int64_t Addend) { 32cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // This just dispatches to the proper target specific routine. 333e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth switch (CPUType) { 34858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper default: llvm_unreachable("Unsupported CPU type!"); 353e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth case mach::CTM_x86_64: 363e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return resolveX86_64Relocation(LocalAddress, 373e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth FinalAddress, 383e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth (uintptr_t)Value, 393e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth isPCRel, 403e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Type, 413e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Size, 423e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Addend); 433e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth case mach::CTM_ARM: 443e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return resolveARMRelocation(LocalAddress, 453e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth FinalAddress, 463e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth (uintptr_t)Value, 473e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth isPCRel, 483e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Type, 493e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Size, 503e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Addend); 51cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 52cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 53cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 54cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevbool RuntimeDyldMachO:: 5561dfa77fce2b6b6261e43334aec060129eac5c6cSean CallananresolveX86_64Relocation(uint8_t *LocalAddress, 5661dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint64_t FinalAddress, 5761dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint64_t Value, 5861dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan bool isPCRel, 5961dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan unsigned Type, 6061dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan unsigned Size, 6161dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan int64_t Addend) { 62cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the relocation is PC-relative, the value to be encoded is the 63cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // pointer difference. 64cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (isPCRel) 65cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: It seems this value needs to be adjusted by 4 for an effective PC 66cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // address. Is that expected? Only for branches, perhaps? 6761dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Value -= FinalAddress + 4; 68cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 69cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch(Type) { 70cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 71cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 72652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed1: 73652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed2: 74652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed4: 75652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed: 76cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Unsigned: 77cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Branch: { 78652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach Value += Addend; 79cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask in the target value a byte at a time (we don't have an alignment 80cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // guarantee for the target address, so this is safest). 8161dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint8_t *p = (uint8_t*)LocalAddress; 82cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i < Size; ++i) { 83cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p++ = (uint8_t)Value; 84cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 8; 85cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 86cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 87cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 88cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_GOTLoad: 89cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_GOT: 90cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Subtractor: 91cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_TLV: 92cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Relocation type not implemented yet!"); 93cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 94cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 95cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 9661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbachbool RuntimeDyldMachO:: 9761dfa77fce2b6b6261e43334aec060129eac5c6cSean CallananresolveARMRelocation(uint8_t *LocalAddress, 9861dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint64_t FinalAddress, 9961dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint64_t Value, 10061dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan bool isPCRel, 10161dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan unsigned Type, 10261dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan unsigned Size, 10361dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan int64_t Addend) { 104cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the relocation is PC-relative, the value to be encoded is the 105cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // pointer difference. 106cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (isPCRel) { 10761dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Value -= FinalAddress; 108cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // ARM PCRel relocations have an effective-PC offset of two instructions 109cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // (four bytes in Thumb mode, 8 bytes in ARM mode). 110cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: For now, assume ARM mode. 111cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value -= 8; 112cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 113cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 114cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch(Type) { 115cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 116cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 117cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_Vanilla: { 118cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask in the target value a byte at a time (we don't have an alignment 119cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // guarantee for the target address, so this is safest). 12061dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint8_t *p = (uint8_t*)LocalAddress; 121cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i < Size; ++i) { 122cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p++ = (uint8_t)Value; 123cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 8; 124cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 125cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 126cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 127cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_Branch24Bit: { 128cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask the value into the target address. We know instructions are 129cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // 32-bit aligned, so we can do it all at once. 13061dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint32_t *p = (uint32_t*)LocalAddress; 131cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // The low two bits of the value are not encoded. 132cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 2; 133cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask the value to 24 bits. 134cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value &= 0xffffff; 135cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: If the destination is a Thumb function (and the instruction 136cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // is a non-predicated BL instruction), we need to change it to a BLX 137cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // instruction instead. 138cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 139cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Insert the value into the instruction. 140cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p = (*p & ~0xffffff) | Value; 141cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 142cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 143cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_ThumbBranch22Bit: 144cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_ThumbBranch32Bit: 145cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_Half: 146cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_HalfDifference: 147cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_Pair: 148cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_Difference: 149cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_LocalDifference: 150cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_PreboundLazyPointer: 151cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Relocation type not implemented yet!"); 152cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 153cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 154cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 155cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 1563e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruthbool RuntimeDyldMachO:: 1573e29671cca14f8fce1ea6b602175880cb3df7199Chandler CarruthloadSegment32(const MachOObject *Obj, 1583e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth const MachOObject::LoadCommandInfo *SegmentLCI, 1593e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC) { 1603e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // FIXME: This should really be combined w/ loadSegment64. Templatized 1613e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // function on the 32/64 datatypes maybe? 1623e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth InMemoryStruct<macho::SegmentLoadCommand> SegmentLC; 1633e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Obj->ReadSegmentLoadCommand(*SegmentLCI, SegmentLC); 1643e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (!SegmentLC) 1653e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return Error("unable to load segment load command"); 1663e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 1673e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 1683e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SmallVector<unsigned, 16> SectionMap; 1693e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) { 1703e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth InMemoryStruct<macho::Section> Sect; 1713e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Obj->ReadSection(*SegmentLCI, SectNum, Sect); 1723e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (!Sect) 1733e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return Error("unable to load section: '" + Twine(SectNum) + "'"); 1743e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 1753e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Allocate memory via the MM for the section. 1763e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint8_t *Buffer; 1773e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint32_t SectionID = Sections.size(); 1783e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (Sect->Flags == 0x80000400) 1793e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Buffer = MemMgr->allocateCodeSection(Sect->Size, Sect->Align, SectionID); 1803e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth else 1813e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Buffer = MemMgr->allocateDataSection(Sect->Size, Sect->Align, SectionID); 1823e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 1833e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth DEBUG(dbgs() << "Loading " 1843e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << ((Sect->Flags == 0x80000400) ? "text" : "data") 1853e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << " (ID #" << SectionID << ")" 1863e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << " '" << Sect->SegmentName << "," 1873e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << Sect->Name << "' of size " << Sect->Size 1883e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << " to address " << Buffer << ".\n"); 1893e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 1903e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Copy the payload from the object file into the allocated buffer. 1913e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint8_t *Base = (uint8_t*)Obj->getData(SegmentLC->FileOffset, 1923e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SegmentLC->FileSize).data(); 1933e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth memcpy(Buffer, Base + Sect->Address, Sect->Size); 1943e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 1953e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Remember what got allocated for this SectionID. 1963e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Sections.push_back(sys::MemoryBlock(Buffer, Sect->Size)); 1973e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SectionLocalMemToID[Buffer] = SectionID; 1983e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 1993e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // By default, the load address of a section is its memory buffer. 2003e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SectionLoadAddress.push_back((uint64_t)Buffer); 2013e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 2023e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Keep a map of object file section numbers to corresponding SectionIDs 2033e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // while processing the file. 2043e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SectionMap.push_back(SectionID); 2053e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth } 2063e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 2073e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Process the symbol table. 2083e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SmallVector<StringRef, 64> SymbolNames; 2093e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth processSymbols32(Obj, SectionMap, SymbolNames, SymtabLC); 2103e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 2113e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Process the relocations for each section we're loading. 2123e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Relocations.grow(Relocations.size() + SegmentLC->NumSections); 2133e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Referrers.grow(Referrers.size() + SegmentLC->NumSections); 2143e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) { 2153e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth InMemoryStruct<macho::Section> Sect; 2163e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Obj->ReadSection(*SegmentLCI, SectNum, Sect); 2173e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (!Sect) 2183e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return Error("unable to load section: '" + Twine(SectNum) + "'"); 2193e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth for (unsigned j = 0; j != Sect->NumRelocationTableEntries; ++j) { 2203e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth InMemoryStruct<macho::RelocationEntry> RE; 2213e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Obj->ReadRelocationEntry(Sect->RelocationTableOffset, j, RE); 2223e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (RE->Word0 & macho::RF_Scattered) 2233e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return Error("NOT YET IMPLEMENTED: scattered relocations."); 2243e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Word0 of the relocation is the offset into the section where the 2253e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // relocation should be applied. We need to translate that into an 2263e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // offset into a function since that's our atom. 2273e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint32_t Offset = RE->Word0; 2283e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth bool isExtern = (RE->Word1 >> 27) & 1; 2293e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 2303e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // FIXME: Get the relocation addend from the target address. 2313e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // FIXME: VERY imporant for internal relocations. 2323e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 2333e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Figure out the source symbol of the relocation. If isExtern is true, 2343e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // this relocation references the symbol table, otherwise it references 2353e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // a section in the same object, numbered from 1 through NumSections 2363e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // (SectionBases is [0, NumSections-1]). 2373e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint32_t SourceNum = RE->Word1 & 0xffffff; // 24-bit value 2383e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (!isExtern) { 2393e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth assert(SourceNum > 0 && "Invalid relocation section number!"); 2403e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth unsigned SectionID = SectionMap[SourceNum - 1]; 2413e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth unsigned TargetID = SectionMap[SectNum]; 2423e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth DEBUG(dbgs() << "Internal relocation at Section #" 2433e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << TargetID << " + " << Offset 2443e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << " from Section #" 2453e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << SectionID << " (Word1: " 2463e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << format("0x%x", RE->Word1) << ")\n"); 2473e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 2483e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Store the relocation information. It will get resolved when 2493e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // the section addresses are assigned. 2503e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint32_t RelocationIndex = Relocations[SectionID].size(); 2513e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Relocations[SectionID].push_back(RelocationEntry(TargetID, 2523e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Offset, 2533e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth RE->Word1, 2543e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 0 /*Addend*/)); 2553e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Referrers[TargetID].push_back(Referrer(SectionID, RelocationIndex)); 2563e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth } else { 2573e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth StringRef SourceName = SymbolNames[SourceNum]; 2583e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 2593e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Now store the relocation information. Associate it with the source 2603e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // symbol. Just add it to the unresolved list and let the general 2613e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // path post-load resolve it if we know where the symbol is. 2623e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth UnresolvedRelocations[SourceName].push_back(RelocationEntry(SectNum, 2633e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Offset, 2643e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth RE->Word1, 2653e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 0 /*Addend*/)); 2663e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth DEBUG(dbgs() << "Relocation at Section #" << SectNum << " + " << Offset 2673e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << " from '" << SourceName << "(Word1: " 2683e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << format("0x%x", RE->Word1) << ")\n"); 2693e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth } 27061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } 2713e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth } 2723e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 2733e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Resolve the addresses of any symbols that were defined in this segment. 2743e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth for (int i = 0, e = SymbolNames.size(); i != e; ++i) 2753e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth resolveSymbol(SymbolNames[i]); 2763e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 2773e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return false; 2783e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth} 2793e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 2803e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 2813e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruthbool RuntimeDyldMachO:: 2823e29671cca14f8fce1ea6b602175880cb3df7199Chandler CarruthloadSegment64(const MachOObject *Obj, 2833e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth const MachOObject::LoadCommandInfo *SegmentLCI, 2843e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC) { 2853e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth InMemoryStruct<macho::Segment64LoadCommand> Segment64LC; 2863e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Obj->ReadSegment64LoadCommand(*SegmentLCI, Segment64LC); 2873e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (!Segment64LC) 2883e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return Error("unable to load segment load command"); 2893e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 2903e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 2913e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SmallVector<unsigned, 16> SectionMap; 2923e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections; ++SectNum) { 2933e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth InMemoryStruct<macho::Section64> Sect; 2943e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Obj->ReadSection64(*SegmentLCI, SectNum, Sect); 2953e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (!Sect) 2963e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return Error("unable to load section: '" + Twine(SectNum) + "'"); 2973e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 2983e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Allocate memory via the MM for the section. 2993e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint8_t *Buffer; 3003e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint32_t SectionID = Sections.size(); 3013e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth unsigned Align = 1 << Sect->Align; // .o file has log2 alignment. 3023e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (Sect->Flags == 0x80000400) 3033e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Buffer = MemMgr->allocateCodeSection(Sect->Size, Align, SectionID); 3043e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth else 3053e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Buffer = MemMgr->allocateDataSection(Sect->Size, Align, SectionID); 3063e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 3073e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth DEBUG(dbgs() << "Loading " 3083e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << ((Sect->Flags == 0x80000400) ? "text" : "data") 3093e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << " (ID #" << SectionID << ")" 3103e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << " '" << Sect->SegmentName << "," 3113e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << Sect->Name << "' of size " << Sect->Size 3123e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << " (align " << Align << ")" 3133e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << " to address " << Buffer << ".\n"); 3143e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 3153e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Copy the payload from the object file into the allocated buffer. 3163e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint8_t *Base = (uint8_t*)Obj->getData(Segment64LC->FileOffset, 3173e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Segment64LC->FileSize).data(); 3183e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth memcpy(Buffer, Base + Sect->Address, Sect->Size); 3193e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 3203e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Remember what got allocated for this SectionID. 3213e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Sections.push_back(sys::MemoryBlock(Buffer, Sect->Size)); 3223e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SectionLocalMemToID[Buffer] = SectionID; 3233e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 3243e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // By default, the load address of a section is its memory buffer. 3253e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SectionLoadAddress.push_back((uint64_t)Buffer); 3263e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 3273e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Keep a map of object file section numbers to corresponding SectionIDs 3283e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // while processing the file. 3293e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SectionMap.push_back(SectionID); 3303e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth } 3313e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 3323e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Process the symbol table. 3333e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SmallVector<StringRef, 64> SymbolNames; 3343e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth processSymbols64(Obj, SectionMap, SymbolNames, SymtabLC); 3353e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 3363e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Process the relocations for each section we're loading. 3373e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Relocations.grow(Relocations.size() + Segment64LC->NumSections); 3383e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Referrers.grow(Referrers.size() + Segment64LC->NumSections); 3393e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections; ++SectNum) { 3403e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth InMemoryStruct<macho::Section64> Sect; 3413e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Obj->ReadSection64(*SegmentLCI, SectNum, Sect); 3423e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (!Sect) 3433e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return Error("unable to load section: '" + Twine(SectNum) + "'"); 3443e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth for (unsigned j = 0; j != Sect->NumRelocationTableEntries; ++j) { 3453e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth InMemoryStruct<macho::RelocationEntry> RE; 3463e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Obj->ReadRelocationEntry(Sect->RelocationTableOffset, j, RE); 3473e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (RE->Word0 & macho::RF_Scattered) 3483e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return Error("NOT YET IMPLEMENTED: scattered relocations."); 3493e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Word0 of the relocation is the offset into the section where the 3503e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // relocation should be applied. We need to translate that into an 3513e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // offset into a function since that's our atom. 3523e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint32_t Offset = RE->Word0; 3533e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth bool isExtern = (RE->Word1 >> 27) & 1; 3543e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 3553e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // FIXME: Get the relocation addend from the target address. 3563e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // FIXME: VERY imporant for internal relocations. 3573e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 3583e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Figure out the source symbol of the relocation. If isExtern is true, 3593e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // this relocation references the symbol table, otherwise it references 3603e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // a section in the same object, numbered from 1 through NumSections 3613e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // (SectionBases is [0, NumSections-1]). 3623e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint32_t SourceNum = RE->Word1 & 0xffffff; // 24-bit value 3633e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (!isExtern) { 3643e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth assert(SourceNum > 0 && "Invalid relocation section number!"); 3653e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth unsigned SectionID = SectionMap[SourceNum - 1]; 3663e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth unsigned TargetID = SectionMap[SectNum]; 3673e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth DEBUG(dbgs() << "Internal relocation at Section #" 3683e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << TargetID << " + " << Offset 3693e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << " from Section #" 3703e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << SectionID << " (Word1: " 3713e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << format("0x%x", RE->Word1) << ")\n"); 3723e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 3733e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Store the relocation information. It will get resolved when 3743e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // the section addresses are assigned. 3753e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint32_t RelocationIndex = Relocations[SectionID].size(); 3763e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Relocations[SectionID].push_back(RelocationEntry(TargetID, 3773e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Offset, 3783e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth RE->Word1, 3793e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 0 /*Addend*/)); 3803e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Referrers[TargetID].push_back(Referrer(SectionID, RelocationIndex)); 3813e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth } else { 3823e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth StringRef SourceName = SymbolNames[SourceNum]; 3833e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 3843e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Now store the relocation information. Associate it with the source 3853e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // symbol. Just add it to the unresolved list and let the general 3863e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // path post-load resolve it if we know where the symbol is. 3873e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth UnresolvedRelocations[SourceName].push_back(RelocationEntry(SectNum, 3883e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Offset, 3893e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth RE->Word1, 3903e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 0 /*Addend*/)); 3913e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth DEBUG(dbgs() << "Relocation at Section #" << SectNum << " + " << Offset 3923e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << " from '" << SourceName << "(Word1: " 3933e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << format("0x%x", RE->Word1) << ")\n"); 3943e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth } 395cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 396cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 397cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 3983e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Resolve the addresses of any symbols that were defined in this segment. 3993e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth for (int i = 0, e = SymbolNames.size(); i != e; ++i) 4003e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth resolveSymbol(SymbolNames[i]); 4013e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 4023e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return false; 4033e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth} 4043e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 4053e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruthbool RuntimeDyldMachO:: 4063e29671cca14f8fce1ea6b602175880cb3df7199Chandler CarruthprocessSymbols32(const MachOObject *Obj, 4073e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SmallVectorImpl<unsigned> &SectionMap, 4083e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SmallVectorImpl<StringRef> &SymbolNames, 4093e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC) { 4103e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // FIXME: Combine w/ processSymbols64. Factor 64/32 datatype and such. 4113e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) { 4123e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth InMemoryStruct<macho::SymbolTableEntry> STE; 4133e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Obj->ReadSymbolTableEntry(SymtabLC->SymbolTableOffset, i, STE); 4143e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (!STE) 4153e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return Error("unable to read symbol: '" + Twine(i) + "'"); 4163e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Get the symbol name. 4173e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth StringRef Name = Obj->getStringAtIndex(STE->StringIndex); 4183e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SymbolNames.push_back(Name); 4193e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 4203e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // FIXME: Check the symbol type and flags. 4213e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (STE->Type != 0xF) // external, defined in this segment. 4223e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth continue; 4233e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Flags in the upper nibble we don't care about. 4243e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if ((STE->Flags & 0xf) != 0x0) 4253e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth continue; 4263e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 4273e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Remember the symbol. 4283e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint32_t SectionID = SectionMap[STE->SectionIndex - 1]; 4293e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SymbolTable[Name] = SymbolLoc(SectionID, STE->Value); 4303e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 4313e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth DEBUG(dbgs() << "Symbol: '" << Name << "' @ " 4323e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << (getSectionAddress(SectionID) + STE->Value) 4333e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << "\n"); 4343e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth } 4353e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return false; 4363e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth} 4373e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 4383e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruthbool RuntimeDyldMachO:: 4393e29671cca14f8fce1ea6b602175880cb3df7199Chandler CarruthprocessSymbols64(const MachOObject *Obj, 4403e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SmallVectorImpl<unsigned> &SectionMap, 4413e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SmallVectorImpl<StringRef> &SymbolNames, 4423e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC) { 4433e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) { 4443e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth InMemoryStruct<macho::Symbol64TableEntry> STE; 4453e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Obj->ReadSymbol64TableEntry(SymtabLC->SymbolTableOffset, i, STE); 4463e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (!STE) 4473e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return Error("unable to read symbol: '" + Twine(i) + "'"); 4483e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Get the symbol name. 4493e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth StringRef Name = Obj->getStringAtIndex(STE->StringIndex); 4503e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SymbolNames.push_back(Name); 4513e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 4523e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // FIXME: Check the symbol type and flags. 4533e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (STE->Type != 0xF) // external, defined in this segment. 4543e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth continue; 4553e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Flags in the upper nibble we don't care about. 4563e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if ((STE->Flags & 0xf) != 0x0) 4573e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth continue; 4583e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 4593e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Remember the symbol. 4603e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint32_t SectionID = SectionMap[STE->SectionIndex - 1]; 4613e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SymbolTable[Name] = SymbolLoc(SectionID, STE->Value); 4623e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 4633e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth DEBUG(dbgs() << "Symbol: '" << Name << "' @ " 4643e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << (getSectionAddress(SectionID) + STE->Value) 4653e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << "\n"); 4663e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth } 4673e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return false; 4683e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth} 4693e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 4703e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth// resolveSymbol - Resolve any relocations to the specified symbol if 4713e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth// we know where it lives. 4723e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruthvoid RuntimeDyldMachO::resolveSymbol(StringRef Name) { 4733e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth StringMap<SymbolLoc>::const_iterator Loc = SymbolTable.find(Name); 4743e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (Loc == SymbolTable.end()) 4753e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return; 4763e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 4773e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth RelocationList &Relocs = UnresolvedRelocations[Name]; 4783e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth DEBUG(dbgs() << "Resolving symbol '" << Name << "'\n"); 4793e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth for (int i = 0, e = Relocs.size(); i != e; ++i) { 4803e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Change the relocation to be section relative rather than symbol 4813e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // relative and move it to the resolved relocation list. 4823e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth RelocationEntry Entry = Relocs[i]; 4833e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Entry.Addend += Loc->second.second; 4843e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint32_t RelocationIndex = Relocations[Loc->second.first].size(); 4853e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Relocations[Loc->second.first].push_back(Entry); 4863e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Referrers[Entry.SectionID].push_back(Referrer(Loc->second.first, RelocationIndex)); 4873e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth } 4883e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // FIXME: Keep a worklist of the relocations we've added so that we can 4893e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // resolve more selectively later. 4903e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Relocs.clear(); 4913e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth} 4923e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 4933e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruthbool RuntimeDyldMachO::loadObject(MemoryBuffer *InputBuffer) { 4943e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // If the linker is in an error state, don't do anything. 4953e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (hasError()) 4963e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return true; 4973e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Load the Mach-O wrapper object. 4983e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth std::string ErrorStr; 4993e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth OwningPtr<MachOObject> Obj( 5003e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth MachOObject::LoadFromBuffer(InputBuffer, &ErrorStr)); 5013e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (!Obj) 5023e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return Error("unable to load object: '" + ErrorStr + "'"); 5033e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 5043e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Get the CPU type information from the header. 5053e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth const macho::Header &Header = Obj->getHeader(); 5063e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 5073e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // FIXME: Error checking that the loaded object is compatible with 5083e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // the system we're running on. 5093e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth CPUType = Header.CPUType; 5103e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth CPUSubtype = Header.CPUSubtype; 5113e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 5123e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Validate that the load commands match what we expect. 5133e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth const MachOObject::LoadCommandInfo *SegmentLCI = 0, *SymtabLCI = 0, 5143e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth *DysymtabLCI = 0; 5153e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth for (unsigned i = 0; i != Header.NumLoadCommands; ++i) { 5163e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth const MachOObject::LoadCommandInfo &LCI = Obj->getLoadCommandInfo(i); 5173e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth switch (LCI.Command.Type) { 5183e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth case macho::LCT_Segment: 5193e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth case macho::LCT_Segment64: 5203e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (SegmentLCI) 5213e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return Error("unexpected input object (multiple segments)"); 5223e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SegmentLCI = &LCI; 5233e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth break; 5243e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth case macho::LCT_Symtab: 5253e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (SymtabLCI) 5263e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return Error("unexpected input object (multiple symbol tables)"); 5273e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SymtabLCI = &LCI; 5283e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth break; 5293e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth case macho::LCT_Dysymtab: 5303e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (DysymtabLCI) 5313e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return Error("unexpected input object (multiple symbol tables)"); 5323e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth DysymtabLCI = &LCI; 5333e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth break; 5343e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth default: 5353e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return Error("unexpected input object (unexpected load command"); 536799184d8eb140d02385501223cea0a087148b67bDanil Malyshev } 5373e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth } 5383e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 5393e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (!SymtabLCI) 5403e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return Error("no symbol table found in object"); 5413e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (!SegmentLCI) 5423e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return Error("no segments found in object"); 5433e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 5443e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Read and register the symbol table data. 5453e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth InMemoryStruct<macho::SymtabLoadCommand> SymtabLC; 5463e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Obj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC); 5473e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (!SymtabLC) 5483e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return Error("unable to load symbol table load command"); 5493e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Obj->RegisterStringTable(*SymtabLC); 5503e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 5513e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Read the dynamic link-edit information, if present (not present in static 5523e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // objects). 5533e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (DysymtabLCI) { 5543e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth InMemoryStruct<macho::DysymtabLoadCommand> DysymtabLC; 5553e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Obj->ReadDysymtabLoadCommand(*DysymtabLCI, DysymtabLC); 5563e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (!DysymtabLC) 5573e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return Error("unable to load dynamic link-exit load command"); 5583e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 5593e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // FIXME: We don't support anything interesting yet. 5603e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth// if (DysymtabLC->LocalSymbolsIndex != 0) 5613e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth// return Error("NOT YET IMPLEMENTED: local symbol entries"); 5623e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth// if (DysymtabLC->ExternalSymbolsIndex != 0) 5633e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth// return Error("NOT YET IMPLEMENTED: non-external symbol entries"); 5643e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth// if (DysymtabLC->UndefinedSymbolsIndex != SymtabLC->NumSymbolTableEntries) 5653e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth// return Error("NOT YET IMPLEMENTED: undefined symbol entries"); 5663e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth } 5673e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 5683e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Load the segment load command. 5693e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (SegmentLCI->Command.Type == macho::LCT_Segment) { 5703e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (loadSegment32(Obj.get(), SegmentLCI, SymtabLC)) 5713e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return true; 5723e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth } else { 5733e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth if (loadSegment64(Obj.get(), SegmentLCI, SymtabLC)) 5743e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return true; 5753e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth } 5763e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 5773e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Assign the addresses of the sections from the object so that any 5783e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // relocations to them get set properly. 5793e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // FIXME: This is done directly from the client at the moment. We should 5803e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // default the values to the local storage, at least when the target arch 5813e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // is the same as the host arch. 5823e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 5833e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth return false; 584cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 585cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 5863e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth// Assign an address to a symbol name and resolve all the relocations 5873e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth// associated with it. 5883e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruthvoid RuntimeDyldMachO::reassignSectionAddress(unsigned SectionID, 5893e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint64_t Addr) { 5903e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // The address to use for relocation resolution is not 5913e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // the address of the local section buffer. We must be doing 5923e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // a remote execution environment of some sort. Re-apply any 5933e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // relocations referencing this section with the given address. 5943e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // 5953e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // Addr is a uint64_t because we can't assume the pointer width 5963e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // of the target is the same as that of the host. Just use a generic 5973e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth // "big enough" type. 5983e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 5993e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth SectionLoadAddress[SectionID] = Addr; 6003e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 6013e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth RelocationList &Relocs = Relocations[SectionID]; 6023e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 6033e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth RelocationEntry &RE = Relocs[i]; 6043e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint8_t *Target = (uint8_t*)Sections[RE.SectionID].base() + RE.Offset; 6053e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint64_t FinalTarget = (uint64_t)SectionLoadAddress[RE.SectionID] + RE.Offset; 6063e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth bool isPCRel = (RE.Data >> 24) & 1; 6073e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth unsigned Type = (RE.Data >> 28) & 0xf; 6083e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth unsigned Size = 1 << ((RE.Data >> 25) & 3); 6093e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 6103e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth DEBUG(dbgs() << "Resolving relocation at Section #" << RE.SectionID 6113e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << " + " << RE.Offset << " (" << format("%p", Target) << ")" 6123e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << " from Section #" << SectionID << " (" << format("%p", Addr) << ")" 6133e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << "(" << (isPCRel ? "pcrel" : "absolute") 6143e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << ", type: " << Type << ", Size: " << Size << ", Addend: " 6153e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << RE.Addend << ").\n"); 6163e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 6173e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth resolveRelocation(Target, 6183e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth FinalTarget, 6193e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Addr, 6203e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth isPCRel, 6213e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Type, 6223e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Size, 6233e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth RE.Addend); 6243e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth } 6253e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth ReferrerList &Refers = Referrers[SectionID]; 6263e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth for (unsigned i = 0, e = Refers.size(); i != e; ++i) { 6273e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Referrer &R = Refers[i]; 6283e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth RelocationEntry &RE = Relocations[R.SectionID][R.Index]; 6293e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint8_t *Target = (uint8_t*)Sections[RE.SectionID].base() + RE.Offset; 6303e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth uint64_t FinalTarget = (uint64_t)SectionLoadAddress[RE.SectionID] + RE.Offset; 6313e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth bool isPCRel = (RE.Data >> 24) & 1; 6323e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth unsigned Type = (RE.Data >> 28) & 0xf; 6333e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth unsigned Size = 1 << ((RE.Data >> 25) & 3); 6343e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 6353e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth DEBUG(dbgs() << "Resolving relocation at Section #" << RE.SectionID 6363e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << " + " << RE.Offset << " (" << format("%p", Target) << ")" 6373e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << " from Section #" << SectionID << " (" << format("%p", Addr) << ")" 6383e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << "(" << (isPCRel ? "pcrel" : "absolute") 6393e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << ", type: " << Type << ", Size: " << Size << ", Addend: " 6403e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth << RE.Addend << ").\n"); 6413e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 6423e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth resolveRelocation(Target, 6433e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth FinalTarget, 6443e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Addr, 6453e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth isPCRel, 6463e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Type, 6473e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth Size, 6483e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth RE.Addend); 6493e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth } 6503e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth} 651cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 6523e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruthbool RuntimeDyldMachO::isKnownFormat(const MemoryBuffer *InputBuffer) { 653cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev StringRef Magic = InputBuffer->getBuffer().slice(0, 4); 654cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xFE\xED\xFA\xCE") return true; 655cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xCE\xFA\xED\xFE") return true; 656cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xFE\xED\xFA\xCF") return true; 657cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xCF\xFA\xED\xFE") return true; 658cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 659cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 660cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 661cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} // end namespace llvm 662