RuntimeDyldMachO.cpp revision 689ff9c00f4f3dcf3491778bcdbda79e19e2285d
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 240e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshevvoid RuntimeDyldMachO::resolveRelocation(uint8_t *LocalAddress, 250e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint64_t FinalAddress, 260e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint64_t Value, 270e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint32_t Type, 280e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev int64_t Addend) { 290e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev bool isPCRel = (Type >> 24) & 1; 300e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev unsigned MachoType = (Type >> 28) & 0xf; 310e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev unsigned Size = 1 << ((Type >> 25) & 3); 320e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 330e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev DEBUG(dbgs() << "resolveRelocation LocalAddress: " << format("%p", LocalAddress) 340e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " FinalAddress: " << format("%p", FinalAddress) 350e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " Value: " << format("%p", Value) 360e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " Addend: " << Addend 370e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " isPCRel: " << isPCRel 380e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " MachoType: " << MachoType 390e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " Size: " << Size 400e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << "\n"); 410e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 42cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // This just dispatches to the proper target specific routine. 430e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev switch (Arch) { 44858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper default: llvm_unreachable("Unsupported CPU type!"); 450e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::x86_64: 460e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev resolveX86_64Relocation(LocalAddress, 470e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev FinalAddress, 480e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uintptr_t)Value, 490e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev isPCRel, 500e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev MachoType, 510e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Size, 520e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Addend); 530e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 540e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::x86: 550e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev resolveI386Relocation(LocalAddress, 56b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan FinalAddress, 57b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan (uintptr_t)Value, 58b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan isPCRel, 59b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan Type, 60b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan Size, 61b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan Addend); 620e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 630e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::arm: // Fall through. 640e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::thumb: 650e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev resolveARMRelocation(LocalAddress, 660e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev FinalAddress, 670e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uintptr_t)Value, 680e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev isPCRel, 690e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev MachoType, 700e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Size, 710e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Addend); 720e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil 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 2070e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshevvoid RuntimeDyldMachO::processRelocationRef(const ObjRelocationInfo &Rel, 208689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd ObjectImage &Obj, 2090e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev ObjSectionToIDMap &ObjSectionToID, 2100e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev LocalSymbolMap &Symbols, 2110e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StubMap &Stubs) { 2120e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 2130e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint32_t RelType = (uint32_t) (Rel.Type & 0xffffffffL); 2140e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev RelocationValueRef Value; 2150e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev SectionEntry &Section = Sections[Rel.SectionID]; 2160e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint8_t *Target = Section.Address + Rel.Offset; 2170e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 2180e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev bool isExtern = (RelType >> 27) & 1; 2190e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (isExtern) { 2200e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StringRef TargetName; 2210e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev const SymbolRef &Symbol = Rel.Symbol; 2220e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Symbol.getName(TargetName); 2230e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // First look the symbol in object file symbols. 2240e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev LocalSymbolMap::iterator lsi = Symbols.find(TargetName.data()); 2250e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (lsi != Symbols.end()) { 2260e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.SectionID = lsi->second.first; 2270e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.Addend = lsi->second.second; 2280e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } else { 2290e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Second look the symbol in global symbol table. 2300e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StringMap<SymbolLoc>::iterator gsi = SymbolTable.find(TargetName.data()); 2310e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (gsi != SymbolTable.end()) { 2320e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.SectionID = gsi->second.first; 2330e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.Addend = gsi->second.second; 2340e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } else 2350e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.SymbolName = TargetName.data(); 236cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 2370e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } else { 2380e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev error_code err; 2390e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint8_t sectionIndex = static_cast<uint8_t>(RelType & 0xFF); 2400e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev section_iterator si = Obj.begin_sections(), 2410e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev se = Obj.end_sections(); 2420e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev for (uint8_t i = 1; i < sectionIndex; i++) { 2430e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev error_code err; 2440e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev si.increment(err); 2450e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (si == se) 2460e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 247799184d8eb140d02385501223cea0a087148b67bDanil Malyshev } 2480e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev assert(si != se && "No section containing relocation!"); 249689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd Value.SectionID = findOrEmitSection(Obj, *si, true, ObjSectionToID); 2500e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.Addend = *(const intptr_t *)Target; 2510e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (Value.Addend) { 2520e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // The MachO addend is offset from the current section, we need set it 2530e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // as offset from destination section 2540e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.Addend += Section.ObjAddress - Sections[Value.SectionID].ObjAddress; 2554b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev } 256288967dfac246c8e35dc4f85afb667e74d1d26a8Bill Wendling } 257288967dfac246c8e35dc4f85afb667e74d1d26a8Bill Wendling 2580e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (Arch == Triple::arm && RelType == macho::RIT_ARM_Branch24Bit) { 2590e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // This is an ARM branch relocation, need to use a stub function. 2600e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 2610e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Look up for existing stub. 2620e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StubMap::const_iterator i = Stubs.find(Value); 2630e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (i != Stubs.end()) 2640e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev resolveRelocation(Target, (uint64_t)Target, 2650e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uint64_t)Section.Address + i->second, 2660e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev RelType, 0); 2670e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev else { 2680e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Create a new stub function. 2690e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Stubs[Value] = Section.StubOffset; 2700e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint8_t *StubTargetAddr = createStubFunction(Section.Address + 2710e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Section.StubOffset); 2720e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev AddRelocation(Value, Rel.SectionID, StubTargetAddr - Section.Address, 2730e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev macho::RIT_Vanilla); 2740e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev resolveRelocation(Target, (uint64_t)Target, 2750e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uint64_t)Section.Address + Section.StubOffset, 2760e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev RelType, 0); 2770e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Section.StubOffset += getMaxStubSize(); 2780e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } 2790e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } else 2800e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev AddRelocation(Value, Rel.SectionID, Rel.Offset, RelType); 281cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 282cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 283cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 2840e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil 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