RuntimeDyldMachO.cpp revision d04a8d4b33ff316ca4cf961e06c9e312eff8e64f
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" 15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "RuntimeDyldMachO.h" 16cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev#include "llvm/ADT/OwningPtr.h" 17cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev#include "llvm/ADT/STLExtras.h" 18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/StringRef.h" 19cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevusing namespace llvm; 20cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevusing namespace llvm::object; 21cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 22cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevnamespace llvm { 23cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 24a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylorvoid RuntimeDyldMachO::resolveRelocation(const SectionEntry &Section, 25a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor uint64_t Offset, 260e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint64_t Value, 270e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint32_t Type, 280e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev int64_t Addend) { 29a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor uint8_t *LocalAddress = Section.Address + Offset; 30a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor uint64_t FinalAddress = Section.LoadAddress + Offset; 310e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev bool isPCRel = (Type >> 24) & 1; 320e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev unsigned MachoType = (Type >> 28) & 0xf; 330e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev unsigned Size = 1 << ((Type >> 25) & 3); 340e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 356d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky DEBUG(dbgs() << "resolveRelocation LocalAddress: " 366d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky << format("%p", LocalAddress) 370e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " FinalAddress: " << format("%p", FinalAddress) 380e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " Value: " << format("%p", Value) 390e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " Addend: " << Addend 400e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " isPCRel: " << isPCRel 410e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " MachoType: " << MachoType 420e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " Size: " << Size 430e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << "\n"); 440e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 45cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // This just dispatches to the proper target specific routine. 460e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev switch (Arch) { 47858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper default: llvm_unreachable("Unsupported CPU type!"); 480e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::x86_64: 490e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev resolveX86_64Relocation(LocalAddress, 500e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev FinalAddress, 510e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uintptr_t)Value, 520e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev isPCRel, 530e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev MachoType, 540e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Size, 550e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Addend); 560e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 570e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::x86: 580e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev resolveI386Relocation(LocalAddress, 596d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky FinalAddress, 606d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky (uintptr_t)Value, 616d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky isPCRel, 62ba9ba9f9bcb8e627ff9cc4bd11904db21762e5a2Jim Grosbach MachoType, 636d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky Size, 646d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky Addend); 650e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 660e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::arm: // Fall through. 670e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::thumb: 680e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev resolveARMRelocation(LocalAddress, 690e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev FinalAddress, 700e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uintptr_t)Value, 710e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev isPCRel, 720e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev MachoType, 730e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Size, 740e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Addend); 750e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 76cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 77cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 78cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 796d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::resolveI386Relocation(uint8_t *LocalAddress, 806d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t FinalAddress, 816d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t Value, 826d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky bool isPCRel, 836d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Type, 846d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Size, 856d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky int64_t Addend) { 86b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan if (isPCRel) 87b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan Value -= FinalAddress + 4; // see resolveX86_64Relocation 88b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan 89b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan switch (Type) { 90b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan default: 91b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan llvm_unreachable("Invalid relocation type!"); 92b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan case macho::RIT_Vanilla: { 93b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan uint8_t *p = LocalAddress; 94b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan uint64_t ValueToWrite = Value + Addend; 95b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan for (unsigned i = 0; i < Size; ++i) { 96b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan *p++ = (uint8_t)(ValueToWrite & 0xff); 97b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan ValueToWrite >>= 8; 98b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan } 99b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan } 100b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan case macho::RIT_Difference: 101b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan case macho::RIT_Generic_LocalDifference: 102b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan case macho::RIT_Generic_PreboundLazyPointer: 103b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan return Error("Relocation type not implemented yet!"); 104b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan } 105b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan} 106b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan 1076d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::resolveX86_64Relocation(uint8_t *LocalAddress, 1086d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t FinalAddress, 1096d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t Value, 1106d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky bool isPCRel, 1116d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Type, 1126d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Size, 1136d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky int64_t Addend) { 114cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the relocation is PC-relative, the value to be encoded is the 115cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // pointer difference. 116cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (isPCRel) 117cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: It seems this value needs to be adjusted by 4 for an effective PC 118cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // address. Is that expected? Only for branches, perhaps? 11961dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Value -= FinalAddress + 4; 120cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 121cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch(Type) { 122cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 123cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 124652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed1: 125652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed2: 126652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed4: 127652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed: 128cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Unsigned: 129cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Branch: { 130652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach Value += Addend; 131cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask in the target value a byte at a time (we don't have an alignment 132cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // guarantee for the target address, so this is safest). 13361dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint8_t *p = (uint8_t*)LocalAddress; 134cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i < Size; ++i) { 135cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p++ = (uint8_t)Value; 136cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 8; 137cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 138cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 139cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 140cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_GOTLoad: 141cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_GOT: 142cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Subtractor: 143cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_TLV: 144cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Relocation type not implemented yet!"); 145cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 146cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 147cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 1486d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::resolveARMRelocation(uint8_t *LocalAddress, 1496d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t FinalAddress, 1506d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t Value, 1516d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky bool isPCRel, 1526d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Type, 1536d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Size, 1546d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky 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, 210d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky const SymbolTableMap &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 2170e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev bool isExtern = (RelType >> 27) & 1; 2180e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (isExtern) { 219c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // Obtain the symbol name which is referenced in the relocation 2200e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StringRef TargetName; 2210e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev const SymbolRef &Symbol = Rel.Symbol; 2220e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Symbol.getName(TargetName); 223c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // First search for the symbol in the local symbol table 224d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky SymbolTableMap::const_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 { 229c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // Search for the symbol in the global symbol table 230d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky SymbolTableMap::const_iterator gsi = GlobalSymbolTable.find(TargetName.data()); 231d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky if (gsi != GlobalSymbolTable.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); 2507639f98c5fc903339bf50e574aee999d54340cdfJim Grosbach Value.Addend = 0; 2517639f98c5fc903339bf50e574aee999d54340cdfJim Grosbach // FIXME: The size and type of the relocation determines if we can 2527639f98c5fc903339bf50e574aee999d54340cdfJim Grosbach // encode an Addend in the target location itself, and if so, how many 2537639f98c5fc903339bf50e574aee999d54340cdfJim Grosbach // bytes we should read in order to get it. We don't yet support doing 2547639f98c5fc903339bf50e574aee999d54340cdfJim Grosbach // that, and just assuming it's sizeof(intptr_t) is blatantly wrong. 2557639f98c5fc903339bf50e574aee999d54340cdfJim Grosbach //Value.Addend = *(const intptr_t *)Target; 2560e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (Value.Addend) { 257c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // The MachO addend is an offset from the current section. We need it 258c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // to be an offset from the destination section 2590e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.Addend += Section.ObjAddress - Sections[Value.SectionID].ObjAddress; 2604b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev } 261288967dfac246c8e35dc4f85afb667e74d1d26a8Bill Wendling } 262288967dfac246c8e35dc4f85afb667e74d1d26a8Bill Wendling 26301e1a97021da37588ebaf94352984cd566729c4eJim Grosbach if (Arch == Triple::arm && (RelType & 0xf) == macho::RIT_ARM_Branch24Bit) { 2640e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // This is an ARM branch relocation, need to use a stub function. 2650e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 2660e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Look up for existing stub. 2670e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StubMap::const_iterator i = Stubs.find(Value); 2680e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (i != Stubs.end()) 269a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor resolveRelocation(Section, Rel.Offset, 2700e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uint64_t)Section.Address + i->second, 2710e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev RelType, 0); 2720e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev else { 2730e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Create a new stub function. 2740e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Stubs[Value] = Section.StubOffset; 2750e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint8_t *StubTargetAddr = createStubFunction(Section.Address + 2760e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Section.StubOffset); 277c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky RelocationEntry RE(Rel.SectionID, StubTargetAddr - Section.Address, 278c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky macho::RIT_Vanilla, Value.Addend); 279c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky if (Value.SymbolName) 280c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSymbol(RE, Value.SymbolName); 281c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky else 282c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSection(RE, Value.SectionID); 283a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor resolveRelocation(Section, Rel.Offset, 2840e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uint64_t)Section.Address + Section.StubOffset, 2850e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev RelType, 0); 2860e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Section.StubOffset += getMaxStubSize(); 2870e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } 288c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky } else { 289c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky RelocationEntry RE(Rel.SectionID, Rel.Offset, RelType, Value.Addend); 290c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky if (Value.SymbolName) 291c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSymbol(RE, Value.SymbolName); 292c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky else 293c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSection(RE, Value.SectionID); 294c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky } 295cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 296cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 297cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 2986d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::isCompatibleFormat( 2993f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor const ObjectBuffer *InputBuffer) const { 3003f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor if (InputBuffer->getBufferSize() < 4) 3013f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor return false; 3023f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor StringRef Magic(InputBuffer->getBufferStart(), 4); 303cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xFE\xED\xFA\xCE") return true; 304cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xCE\xFA\xED\xFE") return true; 305cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xFE\xED\xFA\xCF") return true; 306cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xCF\xFA\xED\xFE") return true; 307cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 308cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 309cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 310cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} // end namespace llvm 311