RuntimeDyldMachO.cpp revision 4b0b8ef1b0edc2c343145f6b029c43b00a6f5c13
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 244b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshevvoid RuntimeDyldMachO::resolveRelocation(uint8_t *LocalAddress, 254b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev uint64_t FinalAddress, 264b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev uint64_t Value, 274b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev uint32_t Type, 284b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev int64_t Addend) { 294b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev bool isPCRel = (Type >> 24) & 1; 304b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev unsigned MachoType = (Type >> 28) & 0xf; 314b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev unsigned Size = 1 << ((Type >> 25) & 3); 324b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev 334b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev DEBUG(dbgs() << "resolveRelocation LocalAddress: " << format("%p", LocalAddress) 344b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev << " FinalAddress: " << format("%p", FinalAddress) 354b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev << " Value: " << format("%p", Value) 364b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev << " Addend: " << Addend 374b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev << " isPCRel: " << isPCRel 384b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev << " MachoType: " << MachoType 394b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev << " Size: " << Size 404b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev << "\n"); 414b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev 42cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // This just dispatches to the proper target specific routine. 434b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev switch (Arch) { 44858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper default: llvm_unreachable("Unsupported CPU type!"); 454b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev case Triple::x86_64: 464b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev resolveX86_64Relocation(LocalAddress, 474b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev FinalAddress, 484b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev (uintptr_t)Value, 494b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev isPCRel, 504b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev MachoType, 514b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev Size, 524b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev Addend); 534b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev break; 544b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev case Triple::x86: 554b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev resolveI386Relocation(LocalAddress, 56b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan FinalAddress, 57b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan (uintptr_t)Value, 58b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan isPCRel, 59b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan Type, 60b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan Size, 61b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan Addend); 624b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev break; 634b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev case Triple::arm: // Fall through. 644b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev case Triple::thumb: 654b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev resolveARMRelocation(LocalAddress, 664b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev FinalAddress, 674b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev (uintptr_t)Value, 684b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev isPCRel, 694b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev MachoType, 704b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev Size, 714b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev Addend); 724b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev break; 73cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 74cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 75cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 76cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevbool RuntimeDyldMachO:: 77b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean CallananresolveI386Relocation(uint8_t *LocalAddress, 78b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan uint64_t FinalAddress, 79b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan uint64_t Value, 80b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan bool isPCRel, 81b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan unsigned Type, 82b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan unsigned Size, 83b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan int64_t Addend) { 84b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan if (isPCRel) 85b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan Value -= FinalAddress + 4; // see resolveX86_64Relocation 86b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan 87b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan switch (Type) { 88b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan default: 89b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan llvm_unreachable("Invalid relocation type!"); 90b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan case macho::RIT_Vanilla: { 91b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan uint8_t *p = LocalAddress; 92b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan uint64_t ValueToWrite = Value + Addend; 93b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan for (unsigned i = 0; i < Size; ++i) { 94b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan *p++ = (uint8_t)(ValueToWrite & 0xff); 95b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan ValueToWrite >>= 8; 96b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan } 97b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan } 98b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan case macho::RIT_Difference: 99b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan case macho::RIT_Generic_LocalDifference: 100b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan case macho::RIT_Generic_PreboundLazyPointer: 101b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan return Error("Relocation type not implemented yet!"); 102b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan } 103b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan} 104b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan 105b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callananbool RuntimeDyldMachO:: 10661dfa77fce2b6b6261e43334aec060129eac5c6cSean CallananresolveX86_64Relocation(uint8_t *LocalAddress, 10761dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint64_t FinalAddress, 10861dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint64_t Value, 10961dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan bool isPCRel, 11061dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan unsigned Type, 11161dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan unsigned Size, 11261dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan int64_t Addend) { 113cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the relocation is PC-relative, the value to be encoded is the 114cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // pointer difference. 115cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (isPCRel) 116cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: It seems this value needs to be adjusted by 4 for an effective PC 117cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // address. Is that expected? Only for branches, perhaps? 11861dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Value -= FinalAddress + 4; 119cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 120cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch(Type) { 121cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 122cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 123652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed1: 124652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed2: 125652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed4: 126652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed: 127cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Unsigned: 128cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Branch: { 129652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach Value += Addend; 130cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask in the target value a byte at a time (we don't have an alignment 131cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // guarantee for the target address, so this is safest). 13261dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint8_t *p = (uint8_t*)LocalAddress; 133cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i < Size; ++i) { 134cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p++ = (uint8_t)Value; 135cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 8; 136cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 137cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 138cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 139cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_GOTLoad: 140cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_GOT: 141cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Subtractor: 142cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_TLV: 143cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Relocation type not implemented yet!"); 144cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 145cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 146cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 14761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbachbool RuntimeDyldMachO:: 14861dfa77fce2b6b6261e43334aec060129eac5c6cSean CallananresolveARMRelocation(uint8_t *LocalAddress, 14961dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint64_t FinalAddress, 15061dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint64_t Value, 15161dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan bool isPCRel, 15261dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan unsigned Type, 15361dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan unsigned Size, 15461dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan int64_t Addend) { 155cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the relocation is PC-relative, the value to be encoded is the 156cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // pointer difference. 157cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (isPCRel) { 15861dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Value -= FinalAddress; 159cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // ARM PCRel relocations have an effective-PC offset of two instructions 160cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // (four bytes in Thumb mode, 8 bytes in ARM mode). 161cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: For now, assume ARM mode. 162cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value -= 8; 163cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 164cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 165cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch(Type) { 166cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 167cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 168cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_Vanilla: { 169cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask in the target value a byte at a time (we don't have an alignment 170cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // guarantee for the target address, so this is safest). 17161dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint8_t *p = (uint8_t*)LocalAddress; 172cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i < Size; ++i) { 173cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p++ = (uint8_t)Value; 174cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 8; 175cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 176cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 177cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 178cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_Branch24Bit: { 179cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask the value into the target address. We know instructions are 180cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // 32-bit aligned, so we can do it all at once. 18161dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint32_t *p = (uint32_t*)LocalAddress; 182cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // The low two bits of the value are not encoded. 183cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 2; 184cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask the value to 24 bits. 185cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value &= 0xffffff; 186cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: If the destination is a Thumb function (and the instruction 187cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // is a non-predicated BL instruction), we need to change it to a BLX 188cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // instruction instead. 189cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 190cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Insert the value into the instruction. 191cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p = (*p & ~0xffffff) | Value; 192cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 193cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 194cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_ThumbBranch22Bit: 195cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_ThumbBranch32Bit: 196cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_Half: 197cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_HalfDifference: 198cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_Pair: 199cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_Difference: 200cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_LocalDifference: 201cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_PreboundLazyPointer: 202cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Relocation type not implemented yet!"); 203cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 204cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 205cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 206cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 2074b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshevvoid RuntimeDyldMachO::processRelocationRef(const ObjRelocationInfo &Rel, 2084b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev const ObjectFile &Obj, 2094b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev ObjSectionToIDMap &ObjSectionToID, 2104b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev LocalSymbolMap &Symbols, 2114b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev StubMap &Stubs) { 2124b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev 2134b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev uint32_t RelType = (uint32_t) (Rel.Type & 0xffffffffL); 2144b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev RelocationValueRef Value; 2154b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev SectionEntry &Section = Sections[Rel.SectionID]; 2164b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev uint8_t *Target = Section.Address + Rel.Offset; 2174b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev 2184b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev bool isExtern = (RelType >> 27) & 1; 2194b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev if (isExtern) { 2204b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev StringRef TargetName; 2214b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev const SymbolRef &Symbol = Rel.Symbol; 2224b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev Symbol.getName(TargetName); 2234b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev // First look the symbol in object file symbols. 2244b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev LocalSymbolMap::iterator lsi = Symbols.find(TargetName.data()); 2254b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev if (lsi != Symbols.end()) { 2264b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev Value.SectionID = lsi->second.first; 2274b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev Value.Addend = lsi->second.second; 2284b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev } else { 2294b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev // Second look the symbol in global symbol table. 2304b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev StringMap<SymbolLoc>::iterator gsi = SymbolTable.find(TargetName.data()); 2314b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev if (gsi != SymbolTable.end()) { 2324b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev Value.SectionID = gsi->second.first; 2334b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev Value.Addend = gsi->second.second; 2344b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev } else 2354b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev Value.SymbolName = TargetName.data(); 23661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } 2374b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev } else { 2384b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev error_code err; 2394b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev uint8_t sectionIndex = static_cast<uint8_t>(RelType & 0xFF); 2404b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev section_iterator si = Obj.begin_sections(), 2414b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev se = Obj.end_sections(); 2424b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev for (uint8_t i = 1; i < sectionIndex; i++) { 2434b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev error_code err; 2444b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev si.increment(err); 2454b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev if (si == se) 2464b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev break; 247cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 2484b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev assert(si != se && "No section containing relocation!"); 2494b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev Value.SectionID = findOrEmitSection(*si, true, ObjSectionToID); 2504b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev Value.Addend = *(const intptr_t *)Target; 2514b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev if (Value.Addend) { 2524b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev // The MachO addend is offset from the current section, we need set it 2534b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev // as offset from destination section 2544b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev Value.Addend += Section.ObjAddress - Sections[Value.SectionID].ObjAddress; 255799184d8eb140d02385501223cea0a087148b67bDanil Malyshev } 2563e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth } 2573e29671cca14f8fce1ea6b602175880cb3df7199Chandler Carruth 2584b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev if (Arch == Triple::arm && RelType == macho::RIT_ARM_Branch24Bit) { 2594b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev // This is an ARM branch relocation, need to use a stub function. 2604b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev 2614b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev // Look up for existing stub. 2624b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev StubMap::const_iterator i = Stubs.find(Value); 2634b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev if (i != Stubs.end()) 2644b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev resolveRelocation(Target, (uint64_t)Target, 2654b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev (uint64_t)Section.Address + i->second, 2664b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev RelType, 0); 2674b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev else { 2684b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev // Create a new stub function. 2694b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev Stubs[Value] = Section.StubOffset; 2704b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev uint8_t *StubTargetAddr = createStubFunction(Section.Address + 2714b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev Section.StubOffset); 2724b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev AddRelocation(Value, Rel.SectionID, StubTargetAddr - Section.Address, 2734b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev macho::RIT_Vanilla); 2744b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev resolveRelocation(Target, (uint64_t)Target, 2754b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev (uint64_t)Section.Address + Section.StubOffset, 2764b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev RelType, 0); 2774b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev Section.StubOffset += getMaxStubSize(); 2784b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev } 2794b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev } else 2804b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev AddRelocation(Value, Rel.SectionID, Rel.Offset, RelType); 281cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 282cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 283cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 2844b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshevbool RuntimeDyldMachO::isCompatibleFormat(const MemoryBuffer *InputBuffer) const { 285cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev StringRef Magic = InputBuffer->getBuffer().slice(0, 4); 286cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xFE\xED\xFA\xCE") return true; 287cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xCE\xFA\xED\xFE") return true; 288cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xFE\xED\xFA\xCF") return true; 289cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xCF\xFA\xED\xFE") return true; 290cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 291cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 292cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 293cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} // end namespace llvm 294