RuntimeDyldMachO.cpp revision 61dfa77fce2b6b6261e43334aec060129eac5c6c
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:: 2561dfa77fce2b6b6261e43334aec060129eac5c6cSean CallananresolveRelocation(uint8_t *LocalAddress, 2661dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint64_t FinalAddress, 2761dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint64_t Value, 2861dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan bool isPCRel, 2961dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan unsigned Type, 3061dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan unsigned Size, 3161dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan int64_t Addend) { 32cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // This just dispatches to the proper target specific routine. 33cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch (CPUType) { 34858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper default: llvm_unreachable("Unsupported CPU type!"); 35cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case mach::CTM_x86_64: 3661dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan return resolveX86_64Relocation(LocalAddress, 3761dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan FinalAddress, 3861dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan (uintptr_t)Value, 3961dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan isPCRel, 4061dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Type, 4161dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Size, 4261dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Addend); 43cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case mach::CTM_ARM: 4461dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan return resolveARMRelocation(LocalAddress, 4561dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan FinalAddress, 4661dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan (uintptr_t)Value, 4761dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan isPCRel, 4861dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Type, 4961dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Size, 5061dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Addend); 51cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 52cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 53cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 54cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevbool RuntimeDyldMachO:: 5561dfa77fce2b6b6261e43334aec060129eac5c6cSean CallananresolveX86_64Relocation(uint8_t *LocalAddress, 5661dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint64_t FinalAddress, 5761dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint64_t Value, 5861dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan bool isPCRel, 5961dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan unsigned Type, 6061dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan unsigned Size, 6161dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan int64_t Addend) { 62cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the relocation is PC-relative, the value to be encoded is the 63cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // pointer difference. 64cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (isPCRel) 65cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: It seems this value needs to be adjusted by 4 for an effective PC 66cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // address. Is that expected? Only for branches, perhaps? 6761dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Value -= FinalAddress + 4; 68cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 69cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch(Type) { 70cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 71cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 72652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed1: 73652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed2: 74652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed4: 75652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed: 76cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Unsigned: 77cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Branch: { 78652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach Value += Addend; 79cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask in the target value a byte at a time (we don't have an alignment 80cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // guarantee for the target address, so this is safest). 8161dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint8_t *p = (uint8_t*)LocalAddress; 82cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i < Size; ++i) { 83cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p++ = (uint8_t)Value; 84cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 8; 85cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 86cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 87cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 88cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_GOTLoad: 89cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_GOT: 90cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Subtractor: 91cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_TLV: 92cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Relocation type not implemented yet!"); 93cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 94cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 95cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 9661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbachbool RuntimeDyldMachO:: 9761dfa77fce2b6b6261e43334aec060129eac5c6cSean CallananresolveARMRelocation(uint8_t *LocalAddress, 9861dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint64_t FinalAddress, 9961dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint64_t Value, 10061dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan bool isPCRel, 10161dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan unsigned Type, 10261dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan unsigned Size, 10361dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan int64_t Addend) { 104cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the relocation is PC-relative, the value to be encoded is the 105cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // pointer difference. 106cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (isPCRel) { 10761dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Value -= FinalAddress; 108cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // ARM PCRel relocations have an effective-PC offset of two instructions 109cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // (four bytes in Thumb mode, 8 bytes in ARM mode). 110cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: For now, assume ARM mode. 111cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value -= 8; 112cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 113cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 114cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch(Type) { 115cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 116cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 117cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_Vanilla: { 118cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask in the target value a byte at a time (we don't have an alignment 119cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // guarantee for the target address, so this is safest). 12061dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint8_t *p = (uint8_t*)LocalAddress; 121cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i < Size; ++i) { 122cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p++ = (uint8_t)Value; 123cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 8; 124cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 125cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 126cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 127cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_Branch24Bit: { 128cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask the value into the target address. We know instructions are 129cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // 32-bit aligned, so we can do it all at once. 13061dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint32_t *p = (uint32_t*)LocalAddress; 131cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // The low two bits of the value are not encoded. 132cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 2; 133cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask the value to 24 bits. 134cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value &= 0xffffff; 135cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: If the destination is a Thumb function (and the instruction 136cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // is a non-predicated BL instruction), we need to change it to a BLX 137cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // instruction instead. 138cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 139cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Insert the value into the instruction. 140cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p = (*p & ~0xffffff) | Value; 141cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 142cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 143cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_ThumbBranch22Bit: 144cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_ThumbBranch32Bit: 145cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_Half: 146cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_HalfDifference: 147cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_Pair: 148cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_Difference: 149cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_LocalDifference: 150cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_PreboundLazyPointer: 151cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Relocation type not implemented yet!"); 152cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 153cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 154cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 155cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 156cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevbool RuntimeDyldMachO:: 157cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil MalyshevloadSegment32(const MachOObject *Obj, 158cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev const MachOObject::LoadCommandInfo *SegmentLCI, 159cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC) { 16061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: This should really be combined w/ loadSegment64. Templatized 16161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // function on the 32/64 datatypes maybe? 162cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::SegmentLoadCommand> SegmentLC; 163cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadSegmentLoadCommand(*SegmentLCI, SegmentLC); 164cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!SegmentLC) 165cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to load segment load command"); 166cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 16761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 16861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SmallVector<unsigned, 16> SectionMap; 169cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) { 170cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::Section> Sect; 171cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadSection(*SegmentLCI, SectNum, Sect); 172cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!Sect) 173cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to load section: '" + Twine(SectNum) + "'"); 174cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 17561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Allocate memory via the MM for the section. 17661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint8_t *Buffer; 17761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint32_t SectionID = Sections.size(); 178996d6fdfb4242f935a8c97cbfa0af5ba6db4a743Sean Callanan if (Sect->Flags == 0x80000400) 17961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Buffer = MemMgr->allocateCodeSection(Sect->Size, Sect->Align, SectionID); 18061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach else 18161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Buffer = MemMgr->allocateDataSection(Sect->Size, Sect->Align, SectionID); 18261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 18361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach DEBUG(dbgs() << "Loading " 18461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << ((Sect->Flags == 0x80000400) ? "text" : "data") 18561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " (ID #" << SectionID << ")" 18661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " '" << Sect->SegmentName << "," 18761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << Sect->Name << "' of size " << Sect->Size 18861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " to address " << Buffer << ".\n"); 18961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 19061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Copy the payload from the object file into the allocated buffer. 19161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint8_t *Base = (uint8_t*)Obj->getData(SegmentLC->FileOffset, 19261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SegmentLC->FileSize).data(); 19361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach memcpy(Buffer, Base + Sect->Address, Sect->Size); 194cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 19561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Remember what got allocated for this SectionID. 19661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Sections.push_back(sys::MemoryBlock(Buffer, Sect->Size)); 197020f4e861a9a32059f76377e787703c92ba55a98Jim Grosbach SectionLocalMemToID[Buffer] = SectionID; 198cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 19961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // By default, the load address of a section is its memory buffer. 20061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SectionLoadAddress.push_back((uint64_t)Buffer); 201cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 20261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Keep a map of object file section numbers to corresponding SectionIDs 20361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // while processing the file. 20461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SectionMap.push_back(SectionID); 20561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } 20661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 20761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Process the symbol table. 20861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SmallVector<StringRef, 64> SymbolNames; 20961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach processSymbols32(Obj, SectionMap, SymbolNames, SymtabLC); 21061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 21161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Process the relocations for each section we're loading. 21261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Relocations.grow(Relocations.size() + SegmentLC->NumSections); 21361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) { 21461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach InMemoryStruct<macho::Section> Sect; 21561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Obj->ReadSection(*SegmentLCI, SectNum, Sect); 21661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if (!Sect) 21761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach return Error("unable to load section: '" + Twine(SectNum) + "'"); 218cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned j = 0; j != Sect->NumRelocationTableEntries; ++j) { 219cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::RelocationEntry> RE; 220cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadRelocationEntry(Sect->RelocationTableOffset, j, RE); 221cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (RE->Word0 & macho::RF_Scattered) 222cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("NOT YET IMPLEMENTED: scattered relocations."); 223cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Word0 of the relocation is the offset into the section where the 224cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // relocation should be applied. We need to translate that into an 225cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // offset into a function since that's our atom. 226cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint32_t Offset = RE->Word0; 227cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev bool isExtern = (RE->Word1 >> 27) & 1; 22861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 22961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: Get the relocation addend from the target address. 23061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: VERY imporant for internal relocations. 23161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 232cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Figure out the source symbol of the relocation. If isExtern is true, 233cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // this relocation references the symbol table, otherwise it references 234cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // a section in the same object, numbered from 1 through NumSections 235cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // (SectionBases is [0, NumSections-1]). 236cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint32_t SourceNum = RE->Word1 & 0xffffff; // 24-bit value 23761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if (!isExtern) { 23861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach assert(SourceNum > 0 && "Invalid relocation section number!"); 23961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach unsigned SectionID = SectionMap[SourceNum - 1]; 24061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach unsigned TargetID = SectionMap[SectNum]; 24161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach DEBUG(dbgs() << "Internal relocation at Section #" 24261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << TargetID << " + " << Offset 24361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " from Section #" 24461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << SectionID << " (Word1: " 24561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << format("0x%x", RE->Word1) << ")\n"); 24661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 24761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Store the relocation information. It will get resolved when 24861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // the section addresses are assigned. 24961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Relocations[SectionID].push_back(RelocationEntry(TargetID, 25061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Offset, 25161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach RE->Word1, 25261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 0 /*Addend*/)); 25361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } else { 25461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach StringRef SourceName = SymbolNames[SourceNum]; 25561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 25661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Now store the relocation information. Associate it with the source 25761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // symbol. Just add it to the unresolved list and let the general 25861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // path post-load resolve it if we know where the symbol is. 25961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach UnresolvedRelocations[SourceName].push_back(RelocationEntry(SectNum, 26061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Offset, 26161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach RE->Word1, 26261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 0 /*Addend*/)); 26361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach DEBUG(dbgs() << "Relocation at Section #" << SectNum << " + " << Offset 26461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " from '" << SourceName << "(Word1: " 26561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << format("0x%x", RE->Word1) << ")\n"); 26661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } 267cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 268cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 26961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 27061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Resolve the addresses of any symbols that were defined in this segment. 27161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach for (int i = 0, e = SymbolNames.size(); i != e; ++i) 27261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach resolveSymbol(SymbolNames[i]); 27361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 274cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 275cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 276cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 277cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 278cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevbool RuntimeDyldMachO:: 279cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil MalyshevloadSegment64(const MachOObject *Obj, 280cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev const MachOObject::LoadCommandInfo *SegmentLCI, 281cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC) { 282cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::Segment64LoadCommand> Segment64LC; 283cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadSegment64LoadCommand(*SegmentLCI, Segment64LC); 284cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!Segment64LC) 285cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to load segment load command"); 286cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 28761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 28861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SmallVector<unsigned, 16> SectionMap; 289cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections; ++SectNum) { 290cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::Section64> Sect; 291cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadSection64(*SegmentLCI, SectNum, Sect); 292cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!Sect) 293cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to load section: '" + Twine(SectNum) + "'"); 294cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 29561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Allocate memory via the MM for the section. 29661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint8_t *Buffer; 29761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint32_t SectionID = Sections.size(); 29893391348dc00b4078463515149eeb214796f553dJim Grosbach unsigned Align = 1 << Sect->Align; // .o file has log2 alignment. 299b442d7c6bf920b892b4b098923c1652700ee07e6Jim Grosbach if (Sect->Flags == 0x80000400) 30093391348dc00b4078463515149eeb214796f553dJim Grosbach Buffer = MemMgr->allocateCodeSection(Sect->Size, Align, SectionID); 30161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach else 30293391348dc00b4078463515149eeb214796f553dJim Grosbach Buffer = MemMgr->allocateDataSection(Sect->Size, Align, SectionID); 30361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 30461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach DEBUG(dbgs() << "Loading " 30561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << ((Sect->Flags == 0x80000400) ? "text" : "data") 30661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " (ID #" << SectionID << ")" 30761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " '" << Sect->SegmentName << "," 30861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << Sect->Name << "' of size " << Sect->Size 30993391348dc00b4078463515149eeb214796f553dJim Grosbach << " (align " << Align << ")" 31061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " to address " << Buffer << ".\n"); 31161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 31261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Copy the payload from the object file into the allocated buffer. 31361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint8_t *Base = (uint8_t*)Obj->getData(Segment64LC->FileOffset, 31461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Segment64LC->FileSize).data(); 31561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach memcpy(Buffer, Base + Sect->Address, Sect->Size); 316cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 31761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Remember what got allocated for this SectionID. 31861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Sections.push_back(sys::MemoryBlock(Buffer, Sect->Size)); 319020f4e861a9a32059f76377e787703c92ba55a98Jim Grosbach SectionLocalMemToID[Buffer] = SectionID; 320cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 32161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // By default, the load address of a section is its memory buffer. 32261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SectionLoadAddress.push_back((uint64_t)Buffer); 323cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 32461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Keep a map of object file section numbers to corresponding SectionIDs 32561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // while processing the file. 32661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SectionMap.push_back(SectionID); 32761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } 32861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 32961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Process the symbol table. 33061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SmallVector<StringRef, 64> SymbolNames; 33161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach processSymbols64(Obj, SectionMap, SymbolNames, SymtabLC); 33261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 33361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Process the relocations for each section we're loading. 33461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Relocations.grow(Relocations.size() + Segment64LC->NumSections); 33561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections; ++SectNum) { 33661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach InMemoryStruct<macho::Section64> Sect; 33761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Obj->ReadSection64(*SegmentLCI, SectNum, Sect); 33861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if (!Sect) 33961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach return Error("unable to load section: '" + Twine(SectNum) + "'"); 340cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned j = 0; j != Sect->NumRelocationTableEntries; ++j) { 341cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::RelocationEntry> RE; 342cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadRelocationEntry(Sect->RelocationTableOffset, j, RE); 343cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (RE->Word0 & macho::RF_Scattered) 344cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("NOT YET IMPLEMENTED: scattered relocations."); 345cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Word0 of the relocation is the offset into the section where the 346cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // relocation should be applied. We need to translate that into an 347cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // offset into a function since that's our atom. 348cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint32_t Offset = RE->Word0; 349cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev bool isExtern = (RE->Word1 >> 27) & 1; 35061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 35161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: Get the relocation addend from the target address. 35261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: VERY imporant for internal relocations. 35361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 354cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Figure out the source symbol of the relocation. If isExtern is true, 355cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // this relocation references the symbol table, otherwise it references 356cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // a section in the same object, numbered from 1 through NumSections 357cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // (SectionBases is [0, NumSections-1]). 358cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint32_t SourceNum = RE->Word1 & 0xffffff; // 24-bit value 35961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if (!isExtern) { 36061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach assert(SourceNum > 0 && "Invalid relocation section number!"); 36161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach unsigned SectionID = SectionMap[SourceNum - 1]; 36261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach unsigned TargetID = SectionMap[SectNum]; 36361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach DEBUG(dbgs() << "Internal relocation at Section #" 36461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << TargetID << " + " << Offset 36561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " from Section #" 36661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << SectionID << " (Word1: " 36761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << format("0x%x", RE->Word1) << ")\n"); 36861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 36961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Store the relocation information. It will get resolved when 37061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // the section addresses are assigned. 37161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Relocations[SectionID].push_back(RelocationEntry(TargetID, 37261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Offset, 37361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach RE->Word1, 37461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 0 /*Addend*/)); 37561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } else { 37661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach StringRef SourceName = SymbolNames[SourceNum]; 37761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 37861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Now store the relocation information. Associate it with the source 37961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // symbol. Just add it to the unresolved list and let the general 38061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // path post-load resolve it if we know where the symbol is. 38161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach UnresolvedRelocations[SourceName].push_back(RelocationEntry(SectNum, 38261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Offset, 38361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach RE->Word1, 38461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 0 /*Addend*/)); 38561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach DEBUG(dbgs() << "Relocation at Section #" << SectNum << " + " << Offset 38661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " from '" << SourceName << "(Word1: " 38761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << format("0x%x", RE->Word1) << ")\n"); 38861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } 38961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } 39061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } 391cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 39261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Resolve the addresses of any symbols that were defined in this segment. 39361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach for (int i = 0, e = SymbolNames.size(); i != e; ++i) 39461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach resolveSymbol(SymbolNames[i]); 395cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 39661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach return false; 39761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach} 39861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 39961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbachbool RuntimeDyldMachO:: 40061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim GrosbachprocessSymbols32(const MachOObject *Obj, 40161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SmallVectorImpl<unsigned> &SectionMap, 40261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SmallVectorImpl<StringRef> &SymbolNames, 40361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC) { 40461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: Combine w/ processSymbols64. Factor 64/32 datatype and such. 40561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) { 40661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach InMemoryStruct<macho::SymbolTableEntry> STE; 40761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Obj->ReadSymbolTableEntry(SymtabLC->SymbolTableOffset, i, STE); 40861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if (!STE) 40961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach return Error("unable to read symbol: '" + Twine(i) + "'"); 41061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Get the symbol name. 41161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach StringRef Name = Obj->getStringAtIndex(STE->StringIndex); 41261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SymbolNames.push_back(Name); 41361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 41461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: Check the symbol type and flags. 41561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if (STE->Type != 0xF) // external, defined in this segment. 41661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach continue; 41761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Flags in the upper nibble we don't care about. 41861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if ((STE->Flags & 0xf) != 0x0) 41961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach continue; 42061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 42161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Remember the symbol. 42261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint32_t SectionID = SectionMap[STE->SectionIndex - 1]; 42361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SymbolTable[Name] = SymbolLoc(SectionID, STE->Value); 42461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 42561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach DEBUG(dbgs() << "Symbol: '" << Name << "' @ " 42661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << (getSectionAddress(SectionID) + STE->Value) 42761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << "\n"); 42861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } 42961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach return false; 43061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach} 43161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 43261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbachbool RuntimeDyldMachO:: 43361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim GrosbachprocessSymbols64(const MachOObject *Obj, 43461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SmallVectorImpl<unsigned> &SectionMap, 43561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SmallVectorImpl<StringRef> &SymbolNames, 43661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC) { 43761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) { 43861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach InMemoryStruct<macho::Symbol64TableEntry> STE; 43961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Obj->ReadSymbol64TableEntry(SymtabLC->SymbolTableOffset, i, STE); 44061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if (!STE) 44161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach return Error("unable to read symbol: '" + Twine(i) + "'"); 44261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Get the symbol name. 44361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach StringRef Name = Obj->getStringAtIndex(STE->StringIndex); 44461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SymbolNames.push_back(Name); 44561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 44661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: Check the symbol type and flags. 44761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if (STE->Type != 0xF) // external, defined in this segment. 44861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach continue; 44961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Flags in the upper nibble we don't care about. 45061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if ((STE->Flags & 0xf) != 0x0) 45161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach continue; 45261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 45361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Remember the symbol. 45461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint32_t SectionID = SectionMap[STE->SectionIndex - 1]; 45561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SymbolTable[Name] = SymbolLoc(SectionID, STE->Value); 45661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 45761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach DEBUG(dbgs() << "Symbol: '" << Name << "' @ " 45861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << (getSectionAddress(SectionID) + STE->Value) 45961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << "\n"); 460cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 461cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 462cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 463cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 46461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach// resolveSymbol - Resolve any relocations to the specified symbol if 46561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach// we know where it lives. 46661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbachvoid RuntimeDyldMachO::resolveSymbol(StringRef Name) { 46761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach StringMap<SymbolLoc>::const_iterator Loc = SymbolTable.find(Name); 46861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach if (Loc == SymbolTable.end()) 46961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach return; 47061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 47161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach RelocationList &Relocs = UnresolvedRelocations[Name]; 47261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach DEBUG(dbgs() << "Resolving symbol '" << Name << "'\n"); 47361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach for (int i = 0, e = Relocs.size(); i != e; ++i) { 47461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Change the relocation to be section relative rather than symbol 47561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // relative and move it to the resolved relocation list. 47661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach RelocationEntry Entry = Relocs[i]; 47761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Entry.Addend += Loc->second.second; 47861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Relocations[Loc->second.first].push_back(Entry); 47961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } 48061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: Keep a worklist of the relocations we've added so that we can 48161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // resolve more selectively later. 48261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Relocs.clear(); 48361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach} 48461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 485cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevbool RuntimeDyldMachO::loadObject(MemoryBuffer *InputBuffer) { 486cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the linker is in an error state, don't do anything. 487cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (hasError()) 488cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return true; 489cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Load the Mach-O wrapper object. 490cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev std::string ErrorStr; 491cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev OwningPtr<MachOObject> Obj( 492cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev MachOObject::LoadFromBuffer(InputBuffer, &ErrorStr)); 493cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!Obj) 494cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to load object: '" + ErrorStr + "'"); 495cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 496cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Get the CPU type information from the header. 497cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev const macho::Header &Header = Obj->getHeader(); 498cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 499cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: Error checking that the loaded object is compatible with 500cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // the system we're running on. 501cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev CPUType = Header.CPUType; 502cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev CPUSubtype = Header.CPUSubtype; 503cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 504cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Validate that the load commands match what we expect. 505cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev const MachOObject::LoadCommandInfo *SegmentLCI = 0, *SymtabLCI = 0, 506cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *DysymtabLCI = 0; 507cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i != Header.NumLoadCommands; ++i) { 508cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev const MachOObject::LoadCommandInfo &LCI = Obj->getLoadCommandInfo(i); 509cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch (LCI.Command.Type) { 510cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::LCT_Segment: 511cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::LCT_Segment64: 512cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (SegmentLCI) 513cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unexpected input object (multiple segments)"); 514cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev SegmentLCI = &LCI; 515cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 516cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::LCT_Symtab: 517cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (SymtabLCI) 518cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unexpected input object (multiple symbol tables)"); 519cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev SymtabLCI = &LCI; 520cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 521cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::LCT_Dysymtab: 522cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (DysymtabLCI) 523cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unexpected input object (multiple symbol tables)"); 524cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev DysymtabLCI = &LCI; 525cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 526cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 527cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unexpected input object (unexpected load command"); 528cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 529cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 530cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 531cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!SymtabLCI) 532cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("no symbol table found in object"); 533cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!SegmentLCI) 5341eb189b4b2a99fc0b03f4d8df9f469c3ef7ad4f5Eli Bendersky return Error("no segments found in object"); 535cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 536cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Read and register the symbol table data. 537cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::SymtabLoadCommand> SymtabLC; 538cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC); 539cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!SymtabLC) 540cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to load symbol table load command"); 541cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->RegisterStringTable(*SymtabLC); 542cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 543cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Read the dynamic link-edit information, if present (not present in static 544cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // objects). 545cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (DysymtabLCI) { 546cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::DysymtabLoadCommand> DysymtabLC; 547cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadDysymtabLoadCommand(*DysymtabLCI, DysymtabLC); 548cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!DysymtabLC) 549cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to load dynamic link-exit load command"); 550cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 551cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: We don't support anything interesting yet. 552cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// if (DysymtabLC->LocalSymbolsIndex != 0) 553cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// return Error("NOT YET IMPLEMENTED: local symbol entries"); 554cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// if (DysymtabLC->ExternalSymbolsIndex != 0) 555cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// return Error("NOT YET IMPLEMENTED: non-external symbol entries"); 556cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// if (DysymtabLC->UndefinedSymbolsIndex != SymtabLC->NumSymbolTableEntries) 557cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// return Error("NOT YET IMPLEMENTED: undefined symbol entries"); 558cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 559cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 560cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Load the segment load command. 561cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (SegmentLCI->Command.Type == macho::LCT_Segment) { 562cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (loadSegment32(Obj.get(), SegmentLCI, SymtabLC)) 563cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return true; 564cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } else { 565cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (loadSegment64(Obj.get(), SegmentLCI, SymtabLC)) 566cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return true; 567cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 568cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 56961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Assign the addresses of the sections from the object so that any 57061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // relocations to them get set properly. 57161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // FIXME: This is done directly from the client at the moment. We should 57261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // default the values to the local storage, at least when the target arch 57361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // is the same as the host arch. 57461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 575cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 576cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 577cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 578cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// Assign an address to a symbol name and resolve all the relocations 579cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// associated with it. 58061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbachvoid RuntimeDyldMachO::reassignSectionAddress(unsigned SectionID, 58161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint64_t Addr) { 58261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // The address to use for relocation resolution is not 58361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // the address of the local section buffer. We must be doing 58461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // a remote execution environment of some sort. Re-apply any 58561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // relocations referencing this section with the given address. 58661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // 58761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Addr is a uint64_t because we can't assume the pointer width 58861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // of the target is the same as that of the host. Just use a generic 58961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // "big enough" type. 59061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 59161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach SectionLoadAddress[SectionID] = Addr; 59261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach 59361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach RelocationList &Relocs = Relocations[SectionID]; 594cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 595cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev RelocationEntry &RE = Relocs[i]; 59661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach uint8_t *Target = (uint8_t*)Sections[RE.SectionID].base() + RE.Offset; 59761dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint64_t FinalTarget = (uint64_t)SectionLoadAddress[RE.SectionID] + RE.Offset; 598cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev bool isPCRel = (RE.Data >> 24) & 1; 599cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev unsigned Type = (RE.Data >> 28) & 0xf; 600cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev unsigned Size = 1 << ((RE.Data >> 25) & 3); 601cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 60261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach DEBUG(dbgs() << "Resolving relocation at Section #" << RE.SectionID 60361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " + " << RE.Offset << " (" << format("%p", Target) << ")" 60461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << " from Section #" << SectionID << " (" << format("%p", Addr) << ")" 605cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev << "(" << (isPCRel ? "pcrel" : "absolute") 60661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << ", type: " << Type << ", Size: " << Size << ", Addend: " 60761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach << RE.Addend << ").\n"); 608cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 60961dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan resolveRelocation(Target, 61061dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan FinalTarget, 61161dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Addr, 61261dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan isPCRel, 61361dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Type, 61461dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Size, 61561dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan RE.Addend); 616cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 617cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 618cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 619cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevbool RuntimeDyldMachO::isKnownFormat(const MemoryBuffer *InputBuffer) { 620cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev StringRef Magic = InputBuffer->getBuffer().slice(0, 4); 621cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xFE\xED\xFA\xCE") return true; 622cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xCE\xFA\xED\xFE") return true; 623cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xFE\xED\xFA\xCF") return true; 624cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xCF\xFA\xED\xFE") return true; 625cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 626cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 627cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 628cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} // end namespace llvm 629