RuntimeDyldMachO.cpp revision c201e6eaf165c83f0092c43b371e509fa8eaf4cc
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 336d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky DEBUG(dbgs() << "resolveRelocation LocalAddress: " 346d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky << format("%p", LocalAddress) 350e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " FinalAddress: " << format("%p", FinalAddress) 360e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " Value: " << format("%p", Value) 370e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " Addend: " << Addend 380e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " isPCRel: " << isPCRel 390e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " MachoType: " << MachoType 400e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " Size: " << Size 410e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << "\n"); 420e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 43cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // This just dispatches to the proper target specific routine. 440e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev switch (Arch) { 45858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper default: llvm_unreachable("Unsupported CPU type!"); 460e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::x86_64: 470e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev resolveX86_64Relocation(LocalAddress, 480e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev FinalAddress, 490e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uintptr_t)Value, 500e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev isPCRel, 510e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev MachoType, 520e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Size, 530e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Addend); 540e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 550e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::x86: 560e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev resolveI386Relocation(LocalAddress, 576d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky FinalAddress, 586d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky (uintptr_t)Value, 596d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky isPCRel, 606d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky Type, 616d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky Size, 626d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky Addend); 630e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 640e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::arm: // Fall through. 650e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::thumb: 660e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev resolveARMRelocation(LocalAddress, 670e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev FinalAddress, 680e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uintptr_t)Value, 690e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev isPCRel, 700e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev MachoType, 710e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Size, 720e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Addend); 730e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 74cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 75cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 76cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 776d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::resolveI386Relocation(uint8_t *LocalAddress, 786d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t FinalAddress, 796d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t Value, 806d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky bool isPCRel, 816d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Type, 826d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Size, 836d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky 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 1056d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::resolveX86_64Relocation(uint8_t *LocalAddress, 1066d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t FinalAddress, 1076d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t Value, 1086d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky bool isPCRel, 1096d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Type, 1106d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Size, 1116d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky int64_t Addend) { 112cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the relocation is PC-relative, the value to be encoded is the 113cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // pointer difference. 114cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (isPCRel) 115cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: It seems this value needs to be adjusted by 4 for an effective PC 116cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // address. Is that expected? Only for branches, perhaps? 11761dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Value -= FinalAddress + 4; 118cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 119cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch(Type) { 120cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 121cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 122652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed1: 123652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed2: 124652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed4: 125652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed: 126cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Unsigned: 127cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Branch: { 128652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach Value += Addend; 129cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask in the target value a byte at a time (we don't have an alignment 130cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // guarantee for the target address, so this is safest). 13161dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint8_t *p = (uint8_t*)LocalAddress; 132cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i < Size; ++i) { 133cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p++ = (uint8_t)Value; 134cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 8; 135cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 136cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 137cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 138cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_GOTLoad: 139cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_GOT: 140cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Subtractor: 141cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_TLV: 142cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Relocation type not implemented yet!"); 143cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 144cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 145cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 1466d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::resolveARMRelocation(uint8_t *LocalAddress, 1476d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t FinalAddress, 1486d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t Value, 1496d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky bool isPCRel, 1506d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Type, 1516d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Size, 1526d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky int64_t Addend) { 153cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the relocation is PC-relative, the value to be encoded is the 154cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // pointer difference. 155cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (isPCRel) { 15661dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Value -= FinalAddress; 157cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // ARM PCRel relocations have an effective-PC offset of two instructions 158cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // (four bytes in Thumb mode, 8 bytes in ARM mode). 159cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: For now, assume ARM mode. 160cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value -= 8; 161cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 162cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 163cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch(Type) { 164cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 165cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 166cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_Vanilla: { 167cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask in the target value a byte at a time (we don't have an alignment 168cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // guarantee for the target address, so this is safest). 16961dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint8_t *p = (uint8_t*)LocalAddress; 170cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i < Size; ++i) { 171cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p++ = (uint8_t)Value; 172cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 8; 173cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 174cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 175cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 176cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_Branch24Bit: { 177cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask the value into the target address. We know instructions are 178cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // 32-bit aligned, so we can do it all at once. 17961dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint32_t *p = (uint32_t*)LocalAddress; 180cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // The low two bits of the value are not encoded. 181cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 2; 182cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask the value to 24 bits. 183cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value &= 0xffffff; 184cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: If the destination is a Thumb function (and the instruction 185cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // is a non-predicated BL instruction), we need to change it to a BLX 186cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // instruction instead. 187cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 188cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Insert the value into the instruction. 189cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p = (*p & ~0xffffff) | Value; 190cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 191cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 192cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_ThumbBranch22Bit: 193cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_ThumbBranch32Bit: 194cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_Half: 195cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_HalfDifference: 196cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_Pair: 197cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_Difference: 198cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_LocalDifference: 199cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_PreboundLazyPointer: 200cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Relocation type not implemented yet!"); 201cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 202cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 203cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 204cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 2050e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshevvoid RuntimeDyldMachO::processRelocationRef(const ObjRelocationInfo &Rel, 206689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd ObjectImage &Obj, 2070e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev ObjSectionToIDMap &ObjSectionToID, 208d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky const SymbolTableMap &Symbols, 2090e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StubMap &Stubs) { 2100e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 2110e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint32_t RelType = (uint32_t) (Rel.Type & 0xffffffffL); 2120e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev RelocationValueRef Value; 2130e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev SectionEntry &Section = Sections[Rel.SectionID]; 2140e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint8_t *Target = Section.Address + Rel.Offset; 2150e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 2160e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev bool isExtern = (RelType >> 27) & 1; 2170e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (isExtern) { 218c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // Obtain the symbol name which is referenced in the relocation 2190e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StringRef TargetName; 2200e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev const SymbolRef &Symbol = Rel.Symbol; 2210e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Symbol.getName(TargetName); 222c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // First search for the symbol in the local symbol table 223d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky SymbolTableMap::const_iterator lsi = Symbols.find(TargetName.data()); 2240e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (lsi != Symbols.end()) { 2250e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.SectionID = lsi->second.first; 2260e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.Addend = lsi->second.second; 2270e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } else { 228c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // Search for the symbol in the global symbol table 229d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky SymbolTableMap::const_iterator gsi = GlobalSymbolTable.find(TargetName.data()); 230d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky if (gsi != GlobalSymbolTable.end()) { 2310e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.SectionID = gsi->second.first; 2320e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.Addend = gsi->second.second; 2330e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } else 2340e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.SymbolName = TargetName.data(); 235cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 2360e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } else { 2370e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev error_code err; 2380e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint8_t sectionIndex = static_cast<uint8_t>(RelType & 0xFF); 2390e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev section_iterator si = Obj.begin_sections(), 2400e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev se = Obj.end_sections(); 2410e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev for (uint8_t i = 1; i < sectionIndex; i++) { 2420e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev error_code err; 2430e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev si.increment(err); 2440e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (si == se) 2450e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 246799184d8eb140d02385501223cea0a087148b67bDanil Malyshev } 2470e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev assert(si != se && "No section containing relocation!"); 248689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd Value.SectionID = findOrEmitSection(Obj, *si, true, ObjSectionToID); 2490e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.Addend = *(const intptr_t *)Target; 2500e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (Value.Addend) { 251c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // The MachO addend is an offset from the current section. We need it 252c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // to be an offset from the destination section 2530e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.Addend += Section.ObjAddress - Sections[Value.SectionID].ObjAddress; 2544b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev } 255288967dfac246c8e35dc4f85afb667e74d1d26a8Bill Wendling } 256288967dfac246c8e35dc4f85afb667e74d1d26a8Bill Wendling 2570e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (Arch == Triple::arm && RelType == macho::RIT_ARM_Branch24Bit) { 2580e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // This is an ARM branch relocation, need to use a stub function. 2590e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 2600e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Look up for existing stub. 2610e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StubMap::const_iterator i = Stubs.find(Value); 2620e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (i != Stubs.end()) 2630e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev resolveRelocation(Target, (uint64_t)Target, 2640e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uint64_t)Section.Address + i->second, 2650e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev RelType, 0); 2660e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev else { 2670e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Create a new stub function. 2680e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Stubs[Value] = Section.StubOffset; 2690e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint8_t *StubTargetAddr = createStubFunction(Section.Address + 2700e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Section.StubOffset); 271c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky RelocationEntry RE(Rel.SectionID, StubTargetAddr - Section.Address, 272c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky macho::RIT_Vanilla, Value.Addend); 273c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky if (Value.SymbolName) 274c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSymbol(RE, Value.SymbolName); 275c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky else 276c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSection(RE, Value.SectionID); 2770e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev resolveRelocation(Target, (uint64_t)Target, 2780e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uint64_t)Section.Address + Section.StubOffset, 2790e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev RelType, 0); 2800e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Section.StubOffset += getMaxStubSize(); 2810e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } 282c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky } else { 283c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky RelocationEntry RE(Rel.SectionID, Rel.Offset, RelType, Value.Addend); 284c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky if (Value.SymbolName) 285c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSymbol(RE, Value.SymbolName); 286c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky else 287c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSection(RE, Value.SectionID); 288c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky } 289cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 290cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 291cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 2926d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::isCompatibleFormat( 2936d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky const MemoryBuffer *InputBuffer) const { 294cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev StringRef Magic = InputBuffer->getBuffer().slice(0, 4); 295cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xFE\xED\xFA\xCE") return true; 296cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xCE\xFA\xED\xFE") return true; 297cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xFE\xED\xFA\xCF") return true; 298cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xCF\xFA\xED\xFE") return true; 299cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 300cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 301cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 302cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} // end namespace llvm 303