RuntimeDyldMachO.cpp revision 858143816d43e58b17bfd11cb1b57afbd7f0f893
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 24cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevbool RuntimeDyldMachO:: 2561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim GrosbachresolveRelocation(uint8_t *Address, uint64_t Value, bool isPCRel, 2661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach unsigned Type, unsigned Size, int64_t Addend) { 27cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // This just dispatches to the proper target specific routine. 28cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch (CPUType) { 29858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper default: llvm_unreachable("Unsupported CPU type!"); 30cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case mach::CTM_x86_64: 31cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return resolveX86_64Relocation((uintptr_t)Address, (uintptr_t)Value, 3261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach isPCRel, Type, Size, Addend); 33cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case mach::CTM_ARM: 34cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return resolveARMRelocation((uintptr_t)Address, (uintptr_t)Value, 3561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach isPCRel, Type, Size, Addend); 36cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 37cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable(""); 38cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 39cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 40cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevbool RuntimeDyldMachO:: 4161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim GrosbachresolveX86_64Relocation(uintptr_t Address, uintptr_t Value, bool isPCRel, 4261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach unsigned Type, unsigned Size, int64_t Addend) { 43cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the relocation is PC-relative, the value to be encoded is the 44cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // pointer difference. 45cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (isPCRel) 46cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: It seems this value needs to be adjusted by 4 for an effective PC 47cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // address. Is that expected? Only for branches, perhaps? 48cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value -= Address + 4; 49cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 50cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch(Type) { 51cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 52cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 53652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed1: 54652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed2: 55652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed4: 56652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed: 57cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Unsigned: 58cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Branch: { 59652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach Value += Addend; 60cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask in the target value a byte at a time (we don't have an alignment 61cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // guarantee for the target address, so this is safest). 62cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint8_t *p = (uint8_t*)Address; 63cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i < Size; ++i) { 64cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p++ = (uint8_t)Value; 65cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 8; 66cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 67cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 68cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 69cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_GOTLoad: 70cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_GOT: 71cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Subtractor: 72cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_TLV: 73cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Relocation type not implemented yet!"); 74cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 75cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 76cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 7761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbachbool RuntimeDyldMachO:: 7861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim GrosbachresolveARMRelocation(uintptr_t Address, uintptr_t Value, bool isPCRel, 7961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach unsigned Type, unsigned Size, int64_t Addend) { 80cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the relocation is PC-relative, the value to be encoded is the 81cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // pointer difference. 82cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (isPCRel) { 83cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value -= Address; 84cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // ARM PCRel relocations have an effective-PC offset of two instructions 85cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // (four bytes in Thumb mode, 8 bytes in ARM mode). 86cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: For now, assume ARM mode. 87cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value -= 8; 88cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 89cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 90cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch(Type) { 91cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 92cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 93cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_Vanilla: { 94cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 95cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask in the target value a byte at a time (we don't have an alignment 96cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // guarantee for the target address, so this is safest). 97cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint8_t *p = (uint8_t*)Address; 98cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i < Size; ++i) { 99cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p++ = (uint8_t)Value; 100cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 8; 101cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 102cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 103cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 104cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_Branch24Bit: { 105cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask the value into the target address. We know instructions are 106cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // 32-bit aligned, so we can do it all at once. 107cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint32_t *p = (uint32_t*)Address; 108cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // The low two bits of the value are not encoded. 109cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 2; 110cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask the value to 24 bits. 111cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value &= 0xffffff; 112cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: If the destination is a Thumb function (and the instruction 113cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // is a non-predicated BL instruction), we need to change it to a BLX 114cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // instruction instead. 115cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 116cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Insert the value into the instruction. 117cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p = (*p & ~0xffffff) | Value; 118cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 119cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 120cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_ThumbBranch22Bit: 121cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_ThumbBranch32Bit: 122cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_Half: 123cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_HalfDifference: 124cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_Pair: 125cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_Difference: 126cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_LocalDifference: 127cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_PreboundLazyPointer: 128cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Relocation type not implemented yet!"); 129cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 130cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 131cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 132cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 133cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevbool RuntimeDyldMachO:: 134cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil MalyshevloadSegment32(const MachOObject *Obj, 135cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev const MachOObject::LoadCommandInfo *SegmentLCI, 136cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC) { 13761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: This should really be combined w/ loadSegment64. Templatized 13861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // function on the 32/64 datatypes maybe? 139cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::SegmentLoadCommand> SegmentLC; 140cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadSegmentLoadCommand(*SegmentLCI, SegmentLC); 141cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!SegmentLC) 142cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to load segment load command"); 143cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 14461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 14561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SmallVector<unsigned, 16> SectionMap; 146cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) { 147cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::Section> Sect; 148cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadSection(*SegmentLCI, SectNum, Sect); 149cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!Sect) 150cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to load section: '" + Twine(SectNum) + "'"); 151cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 15261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Allocate memory via the MM for the section. 15361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint8_t *Buffer; 15461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint32_t SectionID = Sections.size(); 155cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Sect->Flags != 0x80000400) 15661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Buffer = MemMgr->allocateCodeSection(Sect->Size, Sect->Align, SectionID); 15761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach else 15861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Buffer = MemMgr->allocateDataSection(Sect->Size, Sect->Align, SectionID); 15961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 16061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach DEBUG(dbgs() << "Loading " 16161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << ((Sect->Flags == 0x80000400) ? "text" : "data") 16261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " (ID #" << SectionID << ")" 16361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " '" << Sect->SegmentName << "," 16461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << Sect->Name << "' of size " << Sect->Size 16561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " to address " << Buffer << ".\n"); 16661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 16761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Copy the payload from the object file into the allocated buffer. 16861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint8_t *Base = (uint8_t*)Obj->getData(SegmentLC->FileOffset, 16961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SegmentLC->FileSize).data(); 17061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach memcpy(Buffer, Base + Sect->Address, Sect->Size); 171cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 17261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Remember what got allocated for this SectionID. 17361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Sections.push_back(sys::MemoryBlock(Buffer, Sect->Size)); 174020f4e861a9a32059f76377e787703c92ba55a98Jim Grosbach SectionLocalMemToID[Buffer] = SectionID; 175cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 17661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // By default, the load address of a section is its memory buffer. 17761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SectionLoadAddress.push_back((uint64_t)Buffer); 178cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 17961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Keep a map of object file section numbers to corresponding SectionIDs 18061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // while processing the file. 18161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SectionMap.push_back(SectionID); 18261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } 18361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 18461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Process the symbol table. 18561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SmallVector<StringRef, 64> SymbolNames; 18661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach processSymbols32(Obj, SectionMap, SymbolNames, SymtabLC); 18761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 18861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Process the relocations for each section we're loading. 18961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Relocations.grow(Relocations.size() + SegmentLC->NumSections); 19061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) { 19161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach InMemoryStruct<macho::Section> Sect; 19261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Obj->ReadSection(*SegmentLCI, SectNum, Sect); 19361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if (!Sect) 19461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach return Error("unable to load section: '" + Twine(SectNum) + "'"); 195cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned j = 0; j != Sect->NumRelocationTableEntries; ++j) { 196cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::RelocationEntry> RE; 197cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadRelocationEntry(Sect->RelocationTableOffset, j, RE); 198cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (RE->Word0 & macho::RF_Scattered) 199cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("NOT YET IMPLEMENTED: scattered relocations."); 200cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Word0 of the relocation is the offset into the section where the 201cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // relocation should be applied. We need to translate that into an 202cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // offset into a function since that's our atom. 203cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint32_t Offset = RE->Word0; 204cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev bool isExtern = (RE->Word1 >> 27) & 1; 20561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 20661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: Get the relocation addend from the target address. 20761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: VERY imporant for internal relocations. 20861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 209cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Figure out the source symbol of the relocation. If isExtern is true, 210cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // this relocation references the symbol table, otherwise it references 211cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // a section in the same object, numbered from 1 through NumSections 212cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // (SectionBases is [0, NumSections-1]). 213cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint32_t SourceNum = RE->Word1 & 0xffffff; // 24-bit value 21461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if (!isExtern) { 21561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach assert(SourceNum > 0 && "Invalid relocation section number!"); 21661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach unsigned SectionID = SectionMap[SourceNum - 1]; 21761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach unsigned TargetID = SectionMap[SectNum]; 21861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach DEBUG(dbgs() << "Internal relocation at Section #" 21961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << TargetID << " + " << Offset 22061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " from Section #" 22161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << SectionID << " (Word1: " 22261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << format("0x%x", RE->Word1) << ")\n"); 22361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 22461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Store the relocation information. It will get resolved when 22561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // the section addresses are assigned. 22661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Relocations[SectionID].push_back(RelocationEntry(TargetID, 22761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Offset, 22861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach RE->Word1, 22961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 0 /*Addend*/)); 23061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } else { 23161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach StringRef SourceName = SymbolNames[SourceNum]; 23261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 23361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Now store the relocation information. Associate it with the source 23461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // symbol. Just add it to the unresolved list and let the general 23561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // path post-load resolve it if we know where the symbol is. 23661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach UnresolvedRelocations[SourceName].push_back(RelocationEntry(SectNum, 23761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Offset, 23861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach RE->Word1, 23961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 0 /*Addend*/)); 24061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach DEBUG(dbgs() << "Relocation at Section #" << SectNum << " + " << Offset 24161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " from '" << SourceName << "(Word1: " 24261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << format("0x%x", RE->Word1) << ")\n"); 24361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } 244cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 245cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 24661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 24761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Resolve the addresses of any symbols that were defined in this segment. 24861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach for (int i = 0, e = SymbolNames.size(); i != e; ++i) 24961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach resolveSymbol(SymbolNames[i]); 25061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 251cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 252cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 253cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 254cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 255cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevbool RuntimeDyldMachO:: 256cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil MalyshevloadSegment64(const MachOObject *Obj, 257cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev const MachOObject::LoadCommandInfo *SegmentLCI, 258cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC) { 259cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::Segment64LoadCommand> Segment64LC; 260cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadSegment64LoadCommand(*SegmentLCI, Segment64LC); 261cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!Segment64LC) 262cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to load segment load command"); 263cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 26461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 26561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SmallVector<unsigned, 16> SectionMap; 266cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections; ++SectNum) { 267cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::Section64> Sect; 268cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadSection64(*SegmentLCI, SectNum, Sect); 269cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!Sect) 270cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to load section: '" + Twine(SectNum) + "'"); 271cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 27261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Allocate memory via the MM for the section. 27361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint8_t *Buffer; 27461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint32_t SectionID = Sections.size(); 27593391348dc00b4078463515149eeb214796f553dJim Grosbach unsigned Align = 1 << Sect->Align; // .o file has log2 alignment. 276b442d7c6bf920b892b4b098923c1652700ee07e6Jim Grosbach if (Sect->Flags == 0x80000400) 27793391348dc00b4078463515149eeb214796f553dJim Grosbach Buffer = MemMgr->allocateCodeSection(Sect->Size, Align, SectionID); 27861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach else 27993391348dc00b4078463515149eeb214796f553dJim Grosbach Buffer = MemMgr->allocateDataSection(Sect->Size, Align, SectionID); 28061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 28161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach DEBUG(dbgs() << "Loading " 28261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << ((Sect->Flags == 0x80000400) ? "text" : "data") 28361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " (ID #" << SectionID << ")" 28461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " '" << Sect->SegmentName << "," 28561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << Sect->Name << "' of size " << Sect->Size 28693391348dc00b4078463515149eeb214796f553dJim Grosbach << " (align " << Align << ")" 28761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " to address " << Buffer << ".\n"); 28861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 28961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Copy the payload from the object file into the allocated buffer. 29061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint8_t *Base = (uint8_t*)Obj->getData(Segment64LC->FileOffset, 29161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Segment64LC->FileSize).data(); 29261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach memcpy(Buffer, Base + Sect->Address, Sect->Size); 293cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 29461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Remember what got allocated for this SectionID. 29561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Sections.push_back(sys::MemoryBlock(Buffer, Sect->Size)); 296020f4e861a9a32059f76377e787703c92ba55a98Jim Grosbach SectionLocalMemToID[Buffer] = SectionID; 297cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 29861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // By default, the load address of a section is its memory buffer. 29961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SectionLoadAddress.push_back((uint64_t)Buffer); 300cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 30161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Keep a map of object file section numbers to corresponding SectionIDs 30261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // while processing the file. 30361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SectionMap.push_back(SectionID); 30461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } 30561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 30661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Process the symbol table. 30761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SmallVector<StringRef, 64> SymbolNames; 30861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach processSymbols64(Obj, SectionMap, SymbolNames, SymtabLC); 30961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 31061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Process the relocations for each section we're loading. 31161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Relocations.grow(Relocations.size() + Segment64LC->NumSections); 31261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections; ++SectNum) { 31361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach InMemoryStruct<macho::Section64> Sect; 31461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Obj->ReadSection64(*SegmentLCI, SectNum, Sect); 31561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if (!Sect) 31661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach return Error("unable to load section: '" + Twine(SectNum) + "'"); 317cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned j = 0; j != Sect->NumRelocationTableEntries; ++j) { 318cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::RelocationEntry> RE; 319cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadRelocationEntry(Sect->RelocationTableOffset, j, RE); 320cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (RE->Word0 & macho::RF_Scattered) 321cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("NOT YET IMPLEMENTED: scattered relocations."); 322cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Word0 of the relocation is the offset into the section where the 323cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // relocation should be applied. We need to translate that into an 324cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // offset into a function since that's our atom. 325cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint32_t Offset = RE->Word0; 326cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev bool isExtern = (RE->Word1 >> 27) & 1; 32761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 32861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: Get the relocation addend from the target address. 32961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: VERY imporant for internal relocations. 33061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 331cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Figure out the source symbol of the relocation. If isExtern is true, 332cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // this relocation references the symbol table, otherwise it references 333cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // a section in the same object, numbered from 1 through NumSections 334cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // (SectionBases is [0, NumSections-1]). 335cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint32_t SourceNum = RE->Word1 & 0xffffff; // 24-bit value 33661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if (!isExtern) { 33761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach assert(SourceNum > 0 && "Invalid relocation section number!"); 33861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach unsigned SectionID = SectionMap[SourceNum - 1]; 33961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach unsigned TargetID = SectionMap[SectNum]; 34061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach DEBUG(dbgs() << "Internal relocation at Section #" 34161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << TargetID << " + " << Offset 34261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " from Section #" 34361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << SectionID << " (Word1: " 34461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << format("0x%x", RE->Word1) << ")\n"); 34561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 34661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Store the relocation information. It will get resolved when 34761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // the section addresses are assigned. 34861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Relocations[SectionID].push_back(RelocationEntry(TargetID, 34961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Offset, 35061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach RE->Word1, 35161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 0 /*Addend*/)); 35261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } else { 35361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach StringRef SourceName = SymbolNames[SourceNum]; 35461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 35561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Now store the relocation information. Associate it with the source 35661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // symbol. Just add it to the unresolved list and let the general 35761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // path post-load resolve it if we know where the symbol is. 35861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach UnresolvedRelocations[SourceName].push_back(RelocationEntry(SectNum, 35961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Offset, 36061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach RE->Word1, 36161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 0 /*Addend*/)); 36261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach DEBUG(dbgs() << "Relocation at Section #" << SectNum << " + " << Offset 36361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " from '" << SourceName << "(Word1: " 36461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << format("0x%x", RE->Word1) << ")\n"); 36561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } 36661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } 36761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } 368cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 36961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Resolve the addresses of any symbols that were defined in this segment. 37061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach for (int i = 0, e = SymbolNames.size(); i != e; ++i) 37161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach resolveSymbol(SymbolNames[i]); 372cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 37361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach return false; 37461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach} 37561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 37661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbachbool RuntimeDyldMachO:: 37761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim GrosbachprocessSymbols32(const MachOObject *Obj, 37861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SmallVectorImpl<unsigned> &SectionMap, 37961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SmallVectorImpl<StringRef> &SymbolNames, 38061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC) { 38161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: Combine w/ processSymbols64. Factor 64/32 datatype and such. 38261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) { 38361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach InMemoryStruct<macho::SymbolTableEntry> STE; 38461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Obj->ReadSymbolTableEntry(SymtabLC->SymbolTableOffset, i, STE); 38561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if (!STE) 38661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach return Error("unable to read symbol: '" + Twine(i) + "'"); 38761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Get the symbol name. 38861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach StringRef Name = Obj->getStringAtIndex(STE->StringIndex); 38961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SymbolNames.push_back(Name); 39061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 39161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: Check the symbol type and flags. 39261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if (STE->Type != 0xF) // external, defined in this segment. 39361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach continue; 39461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Flags in the upper nibble we don't care about. 39561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if ((STE->Flags & 0xf) != 0x0) 39661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach continue; 39761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 39861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Remember the symbol. 39961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint32_t SectionID = SectionMap[STE->SectionIndex - 1]; 40061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SymbolTable[Name] = SymbolLoc(SectionID, STE->Value); 40161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 40261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach DEBUG(dbgs() << "Symbol: '" << Name << "' @ " 40361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << (getSectionAddress(SectionID) + STE->Value) 40461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << "\n"); 40561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } 40661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach return false; 40761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach} 40861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 40961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbachbool RuntimeDyldMachO:: 41061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim GrosbachprocessSymbols64(const MachOObject *Obj, 41161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SmallVectorImpl<unsigned> &SectionMap, 41261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SmallVectorImpl<StringRef> &SymbolNames, 41361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC) { 41461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) { 41561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach InMemoryStruct<macho::Symbol64TableEntry> STE; 41661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Obj->ReadSymbol64TableEntry(SymtabLC->SymbolTableOffset, i, STE); 41761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if (!STE) 41861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach return Error("unable to read symbol: '" + Twine(i) + "'"); 41961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Get the symbol name. 42061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach StringRef Name = Obj->getStringAtIndex(STE->StringIndex); 42161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SymbolNames.push_back(Name); 42261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 42361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: Check the symbol type and flags. 42461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if (STE->Type != 0xF) // external, defined in this segment. 42561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach continue; 42661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Flags in the upper nibble we don't care about. 42761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if ((STE->Flags & 0xf) != 0x0) 42861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach continue; 42961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 43061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Remember the symbol. 43161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint32_t SectionID = SectionMap[STE->SectionIndex - 1]; 43261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SymbolTable[Name] = SymbolLoc(SectionID, STE->Value); 43361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 43461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach DEBUG(dbgs() << "Symbol: '" << Name << "' @ " 43561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << (getSectionAddress(SectionID) + STE->Value) 43661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << "\n"); 437cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 438cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 439cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 440cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 44161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach// resolveSymbol - Resolve any relocations to the specified symbol if 44261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach// we know where it lives. 44361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbachvoid RuntimeDyldMachO::resolveSymbol(StringRef Name) { 44461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach StringMap<SymbolLoc>::const_iterator Loc = SymbolTable.find(Name); 44561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if (Loc == SymbolTable.end()) 44661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach return; 44761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 44861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach RelocationList &Relocs = UnresolvedRelocations[Name]; 44961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach DEBUG(dbgs() << "Resolving symbol '" << Name << "'\n"); 45061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach for (int i = 0, e = Relocs.size(); i != e; ++i) { 45161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Change the relocation to be section relative rather than symbol 45261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // relative and move it to the resolved relocation list. 45361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach RelocationEntry Entry = Relocs[i]; 45461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Entry.Addend += Loc->second.second; 45561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Relocations[Loc->second.first].push_back(Entry); 45661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } 45761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: Keep a worklist of the relocations we've added so that we can 45861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // resolve more selectively later. 45961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Relocs.clear(); 46061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach} 46161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 462cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevbool RuntimeDyldMachO::loadObject(MemoryBuffer *InputBuffer) { 463cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the linker is in an error state, don't do anything. 464cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (hasError()) 465cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return true; 466cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Load the Mach-O wrapper object. 467cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev std::string ErrorStr; 468cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev OwningPtr<MachOObject> Obj( 469cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev MachOObject::LoadFromBuffer(InputBuffer, &ErrorStr)); 470cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!Obj) 471cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to load object: '" + ErrorStr + "'"); 472cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 473cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Get the CPU type information from the header. 474cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev const macho::Header &Header = Obj->getHeader(); 475cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 476cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: Error checking that the loaded object is compatible with 477cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // the system we're running on. 478cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev CPUType = Header.CPUType; 479cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev CPUSubtype = Header.CPUSubtype; 480cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 481cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Validate that the load commands match what we expect. 482cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev const MachOObject::LoadCommandInfo *SegmentLCI = 0, *SymtabLCI = 0, 483cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *DysymtabLCI = 0; 484cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i != Header.NumLoadCommands; ++i) { 485cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev const MachOObject::LoadCommandInfo &LCI = Obj->getLoadCommandInfo(i); 486cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch (LCI.Command.Type) { 487cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::LCT_Segment: 488cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::LCT_Segment64: 489cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (SegmentLCI) 490cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unexpected input object (multiple segments)"); 491cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev SegmentLCI = &LCI; 492cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 493cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::LCT_Symtab: 494cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (SymtabLCI) 495cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unexpected input object (multiple symbol tables)"); 496cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev SymtabLCI = &LCI; 497cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 498cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::LCT_Dysymtab: 499cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (DysymtabLCI) 500cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unexpected input object (multiple symbol tables)"); 501cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev DysymtabLCI = &LCI; 502cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 503cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 504cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unexpected input object (unexpected load command"); 505cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 506cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 507cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 508cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!SymtabLCI) 509cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("no symbol table found in object"); 510cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!SegmentLCI) 5111eb189b4b2a99fc0b03f4d8df9f469c3ef7ad4f5Eli Bendersky return Error("no segments found in object"); 512cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 513cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Read and register the symbol table data. 514cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::SymtabLoadCommand> SymtabLC; 515cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC); 516cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!SymtabLC) 517cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to load symbol table load command"); 518cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->RegisterStringTable(*SymtabLC); 519cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 520cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Read the dynamic link-edit information, if present (not present in static 521cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // objects). 522cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (DysymtabLCI) { 523cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::DysymtabLoadCommand> DysymtabLC; 524cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadDysymtabLoadCommand(*DysymtabLCI, DysymtabLC); 525cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!DysymtabLC) 526cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to load dynamic link-exit load command"); 527cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 528cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: We don't support anything interesting yet. 529cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// if (DysymtabLC->LocalSymbolsIndex != 0) 530cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// return Error("NOT YET IMPLEMENTED: local symbol entries"); 531cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// if (DysymtabLC->ExternalSymbolsIndex != 0) 532cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// return Error("NOT YET IMPLEMENTED: non-external symbol entries"); 533cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// if (DysymtabLC->UndefinedSymbolsIndex != SymtabLC->NumSymbolTableEntries) 534cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// return Error("NOT YET IMPLEMENTED: undefined symbol entries"); 535cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 536cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 537cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Load the segment load command. 538cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (SegmentLCI->Command.Type == macho::LCT_Segment) { 539cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (loadSegment32(Obj.get(), SegmentLCI, SymtabLC)) 540cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return true; 541cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } else { 542cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (loadSegment64(Obj.get(), SegmentLCI, SymtabLC)) 543cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return true; 544cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 545cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 54661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Assign the addresses of the sections from the object so that any 54761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // relocations to them get set properly. 54861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: This is done directly from the client at the moment. We should 54961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // default the values to the local storage, at least when the target arch 55061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // is the same as the host arch. 55161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 552cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 553cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 554cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 555cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// Assign an address to a symbol name and resolve all the relocations 556cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// associated with it. 55761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbachvoid RuntimeDyldMachO::reassignSectionAddress(unsigned SectionID, 55861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint64_t Addr) { 55961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // The address to use for relocation resolution is not 56061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // the address of the local section buffer. We must be doing 56161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // a remote execution environment of some sort. Re-apply any 56261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // relocations referencing this section with the given address. 56361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // 56461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Addr is a uint64_t because we can't assume the pointer width 56561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // of the target is the same as that of the host. Just use a generic 56661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // "big enough" type. 56761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 56861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SectionLoadAddress[SectionID] = Addr; 56961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 57061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach RelocationList &Relocs = Relocations[SectionID]; 571cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 572cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev RelocationEntry &RE = Relocs[i]; 57361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint8_t *Target = (uint8_t*)Sections[RE.SectionID].base() + RE.Offset; 574cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev bool isPCRel = (RE.Data >> 24) & 1; 575cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev unsigned Type = (RE.Data >> 28) & 0xf; 576cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev unsigned Size = 1 << ((RE.Data >> 25) & 3); 577cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 57861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach DEBUG(dbgs() << "Resolving relocation at Section #" << RE.SectionID 57961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " + " << RE.Offset << " (" << format("%p", Target) << ")" 58061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " from Section #" << SectionID << " (" << format("%p", Addr) << ")" 581cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev << "(" << (isPCRel ? "pcrel" : "absolute") 58261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << ", type: " << Type << ", Size: " << Size << ", Addend: " 58361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << RE.Addend << ").\n"); 584cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 58561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach resolveRelocation(Target, Addr, isPCRel, Type, Size, RE.Addend); 586cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 587cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 588cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 589cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevbool RuntimeDyldMachO::isKnownFormat(const MemoryBuffer *InputBuffer) { 590cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev StringRef Magic = InputBuffer->getBuffer().slice(0, 4); 591cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xFE\xED\xFA\xCE") return true; 592cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xCE\xFA\xED\xFE") return true; 593cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xFE\xED\xFA\xCF") return true; 594cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xCF\xFA\xED\xFE") return true; 595cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 596cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 597cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 598cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} // end namespace llvm 599