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