RuntimeDyldMachO.cpp revision ca0e73610056110e9a175c14dd82d6d616fd830f
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 2487b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindolavoid RuntimeDyldMachO::resolveRelocation(const RelocationEntry &RE, 2587b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola uint64_t Value) { 2687b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola const SectionEntry &Section = Sections[RE.SectionID]; 2787b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola return resolveRelocation(Section, RE.Offset, Value, RE.RelType, RE.Addend, 2887b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola RE.IsPCRel, RE.Size); 2987b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola} 3087b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola 31a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylorvoid RuntimeDyldMachO::resolveRelocation(const SectionEntry &Section, 32a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor uint64_t Offset, 330e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint64_t Value, 340e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint32_t Type, 3587b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola int64_t Addend, 3687b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola bool isPCRel, 3787b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola unsigned LogSize) { 38a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor uint8_t *LocalAddress = Section.Address + Offset; 39a307a1cf859f4a523951ac887d094039547adeb5Andrew Kaylor uint64_t FinalAddress = Section.LoadAddress + Offset; 4087b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola unsigned MachoType = Type; 4187b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola unsigned Size = 1 << LogSize; 420e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 436d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky DEBUG(dbgs() << "resolveRelocation LocalAddress: " 446d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky << format("%p", LocalAddress) 450e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " FinalAddress: " << format("%p", FinalAddress) 460e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " Value: " << format("%p", Value) 470e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " Addend: " << Addend 480e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " isPCRel: " << isPCRel 490e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " MachoType: " << MachoType 500e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << " Size: " << Size 510e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev << "\n"); 520e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 53cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // This just dispatches to the proper target specific routine. 540e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev switch (Arch) { 55858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper default: llvm_unreachable("Unsupported CPU type!"); 560e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::x86_64: 570e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev resolveX86_64Relocation(LocalAddress, 580e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev FinalAddress, 590e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uintptr_t)Value, 600e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev isPCRel, 610e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev MachoType, 620e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Size, 630e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Addend); 640e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 650e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::x86: 660e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev resolveI386Relocation(LocalAddress, 676d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky FinalAddress, 686d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky (uintptr_t)Value, 696d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky isPCRel, 70ba9ba9f9bcb8e627ff9cc4bd11904db21762e5a2Jim Grosbach MachoType, 716d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky Size, 726d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky Addend); 730e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 740e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::arm: // Fall through. 750e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev case Triple::thumb: 760e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev resolveARMRelocation(LocalAddress, 770e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev FinalAddress, 780e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uintptr_t)Value, 790e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev isPCRel, 800e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev MachoType, 810e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Size, 820e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Addend); 830e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 84cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 85cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 86cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 876d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::resolveI386Relocation(uint8_t *LocalAddress, 886d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t FinalAddress, 896d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t Value, 906d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky bool isPCRel, 916d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Type, 926d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Size, 936d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky int64_t Addend) { 94b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan if (isPCRel) 95b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan Value -= FinalAddress + 4; // see resolveX86_64Relocation 96b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan 97b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan switch (Type) { 98b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan default: 99b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan llvm_unreachable("Invalid relocation type!"); 100b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan case macho::RIT_Vanilla: { 101b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan uint8_t *p = LocalAddress; 102b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan uint64_t ValueToWrite = Value + Addend; 103b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan for (unsigned i = 0; i < Size; ++i) { 104b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan *p++ = (uint8_t)(ValueToWrite & 0xff); 105b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan ValueToWrite >>= 8; 106b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan } 1076f6f17197259edbb82cc9b0d800fe0e3cb8e201cJim Grosbach return false; 108b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan } 109b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan case macho::RIT_Difference: 110b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan case macho::RIT_Generic_LocalDifference: 111b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan case macho::RIT_Generic_PreboundLazyPointer: 112b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan return Error("Relocation type not implemented yet!"); 113b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan } 114b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan} 115b38aae442f0e3ce11a6231455b180bfc66ab5d3eSean Callanan 1166d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::resolveX86_64Relocation(uint8_t *LocalAddress, 1176d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t FinalAddress, 1186d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t Value, 1196d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky bool isPCRel, 1206d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Type, 1216d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Size, 1226d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky int64_t Addend) { 123cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the relocation is PC-relative, the value to be encoded is the 124cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // pointer difference. 125cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (isPCRel) 126cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: It seems this value needs to be adjusted by 4 for an effective PC 127cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // address. Is that expected? Only for branches, perhaps? 12861dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Value -= FinalAddress + 4; 129cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 130cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch(Type) { 131cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 132cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 133652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed1: 134652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed2: 135652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed4: 136652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach case macho::RIT_X86_64_Signed: 137cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Unsigned: 138cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Branch: { 139652ca2fe0c8bd406222d064937adc28b281d7b89Jim Grosbach Value += Addend; 140cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask in the target value a byte at a time (we don't have an alignment 141cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // guarantee for the target address, so this is safest). 14261dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint8_t *p = (uint8_t*)LocalAddress; 143cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i < Size; ++i) { 144cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p++ = (uint8_t)Value; 145cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 8; 146cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 147cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 148cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 149cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_GOTLoad: 150cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_GOT: 151cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Subtractor: 152cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_TLV: 153cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Relocation type not implemented yet!"); 154cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 155cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 156cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 1576d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::resolveARMRelocation(uint8_t *LocalAddress, 1586d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t FinalAddress, 1596d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky uint64_t Value, 1606d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky bool isPCRel, 1616d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Type, 1626d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky unsigned Size, 1636d15e8717767af9a6a20c6ea456119c15c77dd00Eli Bendersky int64_t Addend) { 164cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the relocation is PC-relative, the value to be encoded is the 165cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // pointer difference. 166cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (isPCRel) { 16761dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan Value -= FinalAddress; 168cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // ARM PCRel relocations have an effective-PC offset of two instructions 169cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // (four bytes in Thumb mode, 8 bytes in ARM mode). 170cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: For now, assume ARM mode. 171cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value -= 8; 172cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 173cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 174cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch(Type) { 175cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 176cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 177cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_Vanilla: { 178cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask in the target value a byte at a time (we don't have an alignment 179cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // guarantee for the target address, so this is safest). 18061dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint8_t *p = (uint8_t*)LocalAddress; 181cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i < Size; ++i) { 182cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p++ = (uint8_t)Value; 183cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 8; 184cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 185cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 186cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 187cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_Branch24Bit: { 188cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask the value into the target address. We know instructions are 189cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // 32-bit aligned, so we can do it all at once. 19061dfa77fce2b6b6261e43334aec060129eac5c6cSean Callanan uint32_t *p = (uint32_t*)LocalAddress; 191cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // The low two bits of the value are not encoded. 192cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 2; 193cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask the value to 24 bits. 194cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value &= 0xffffff; 195cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: If the destination is a Thumb function (and the instruction 196cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // is a non-predicated BL instruction), we need to change it to a BLX 197cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // instruction instead. 198cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 199cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Insert the value into the instruction. 200cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p = (*p & ~0xffffff) | Value; 201cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 202cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 203cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_ThumbBranch22Bit: 204cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_ThumbBranch32Bit: 205cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_Half: 206cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_HalfDifference: 207cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_Pair: 208cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_Difference: 209cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_LocalDifference: 210cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_PreboundLazyPointer: 211cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Relocation type not implemented yet!"); 212cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 213cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 214cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 215cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 216efa91f6475f6e96552986104ab4857db46185a2aRafael Espindolavoid RuntimeDyldMachO::processRelocationRef(unsigned SectionID, 217ca0e73610056110e9a175c14dd82d6d616fd830fRafael Espindola RelocationRef RelI, 218689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd ObjectImage &Obj, 2190e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev ObjSectionToIDMap &ObjSectionToID, 220d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky const SymbolTableMap &Symbols, 2210e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StubMap &Stubs) { 222efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola const ObjectFile *OF = Obj.getObjectFile(); 223efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola const MachOObjectFile *MachO = static_cast<const MachOObjectFile*>(OF); 224ca0e73610056110e9a175c14dd82d6d616fd830fRafael Espindola macho::RelocationEntry RE = MachO->getRelocation(RelI.getRawDataRefImpl()); 2250e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 226efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola uint32_t RelType = MachO->getAnyRelocationType(RE); 2270e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev RelocationValueRef Value; 228efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola SectionEntry &Section = Sections[SectionID]; 2290e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 230efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola bool isExtern = MachO->getPlainRelocationExternal(RE); 23187b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola bool IsPCRel = MachO->getAnyRelocationPCRel(RE); 23287b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola unsigned Size = MachO->getAnyRelocationLength(RE); 2330e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (isExtern) { 234c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // Obtain the symbol name which is referenced in the relocation 235efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola SymbolRef Symbol; 236ca0e73610056110e9a175c14dd82d6d616fd830fRafael Espindola RelI.getSymbol(Symbol); 2370e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StringRef TargetName; 2380e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Symbol.getName(TargetName); 239c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // First search for the symbol in the local symbol table 240d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky SymbolTableMap::const_iterator lsi = Symbols.find(TargetName.data()); 2410e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (lsi != Symbols.end()) { 2420e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.SectionID = lsi->second.first; 2430e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.Addend = lsi->second.second; 2440e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } else { 245c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // Search for the symbol in the global symbol table 246d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky SymbolTableMap::const_iterator gsi = GlobalSymbolTable.find(TargetName.data()); 247d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky if (gsi != GlobalSymbolTable.end()) { 2480e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.SectionID = gsi->second.first; 2490e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.Addend = gsi->second.second; 2500e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } else 2510e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.SymbolName = TargetName.data(); 252cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 2530e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } else { 2540e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev error_code err; 2550e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint8_t sectionIndex = static_cast<uint8_t>(RelType & 0xFF); 2560e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev section_iterator si = Obj.begin_sections(), 2570e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev se = Obj.end_sections(); 2580e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev for (uint8_t i = 1; i < sectionIndex; i++) { 2590e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev error_code err; 2600e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev si.increment(err); 2610e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (si == se) 2620e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev break; 263799184d8eb140d02385501223cea0a087148b67bDanil Malyshev } 2640e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev assert(si != se && "No section containing relocation!"); 265689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd Value.SectionID = findOrEmitSection(Obj, *si, true, ObjSectionToID); 2667639f98c5fc903339bf50e574aee999d54340cdfJim Grosbach Value.Addend = 0; 2677639f98c5fc903339bf50e574aee999d54340cdfJim Grosbach // FIXME: The size and type of the relocation determines if we can 2687639f98c5fc903339bf50e574aee999d54340cdfJim Grosbach // encode an Addend in the target location itself, and if so, how many 2697639f98c5fc903339bf50e574aee999d54340cdfJim Grosbach // bytes we should read in order to get it. We don't yet support doing 2707639f98c5fc903339bf50e574aee999d54340cdfJim Grosbach // that, and just assuming it's sizeof(intptr_t) is blatantly wrong. 2717639f98c5fc903339bf50e574aee999d54340cdfJim Grosbach //Value.Addend = *(const intptr_t *)Target; 2720e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (Value.Addend) { 273c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // The MachO addend is an offset from the current section. We need it 274c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // to be an offset from the destination section 2750e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Value.Addend += Section.ObjAddress - Sections[Value.SectionID].ObjAddress; 2764b0b8ef1b0edc2c343145f6b029c43b00a6f5c13Danil Malyshev } 277288967dfac246c8e35dc4f85afb667e74d1d26a8Bill Wendling } 278288967dfac246c8e35dc4f85afb667e74d1d26a8Bill Wendling 279efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola uint64_t Offset; 280ca0e73610056110e9a175c14dd82d6d616fd830fRafael Espindola RelI.getOffset(Offset); 28101e1a97021da37588ebaf94352984cd566729c4eJim Grosbach if (Arch == Triple::arm && (RelType & 0xf) == macho::RIT_ARM_Branch24Bit) { 2820e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // This is an ARM branch relocation, need to use a stub function. 2830e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 2840e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Look up for existing stub. 2850e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StubMap::const_iterator i = Stubs.find(Value); 2860e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (i != Stubs.end()) 287efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola resolveRelocation(Section, Offset, 2880e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uint64_t)Section.Address + i->second, 28987b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola RelType, 0, IsPCRel, Size); 2900e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev else { 2910e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Create a new stub function. 2920e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Stubs[Value] = Section.StubOffset; 2930e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint8_t *StubTargetAddr = createStubFunction(Section.Address + 2940e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Section.StubOffset); 295efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola RelocationEntry RE(SectionID, StubTargetAddr - Section.Address, 296c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky macho::RIT_Vanilla, Value.Addend); 297c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky if (Value.SymbolName) 298c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSymbol(RE, Value.SymbolName); 299c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky else 300c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSection(RE, Value.SectionID); 301efa91f6475f6e96552986104ab4857db46185a2aRafael Espindola resolveRelocation(Section, Offset, 3020e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev (uint64_t)Section.Address + Section.StubOffset, 30387b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola RelType, 0, IsPCRel, Size); 3040e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Section.StubOffset += getMaxStubSize(); 3050e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } 306c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky } else { 30787b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola RelocationEntry RE(SectionID, Offset, RelType, Value.Addend, 30887b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola IsPCRel, Size); 309c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky if (Value.SymbolName) 310c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSymbol(RE, Value.SymbolName); 311c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky else 312c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky addRelocationForSection(RE, Value.SectionID); 313c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky } 314cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 315cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 316cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 3176d15e8717767af9a6a20c6ea456119c15c77dd00Eli Benderskybool RuntimeDyldMachO::isCompatibleFormat( 3183f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor const ObjectBuffer *InputBuffer) const { 3193f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor if (InputBuffer->getBufferSize() < 4) 3203f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor return false; 3213f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor StringRef Magic(InputBuffer->getBufferStart(), 4); 322cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xFE\xED\xFA\xCE") return true; 323cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xCE\xFA\xED\xFE") return true; 324cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xFE\xED\xFA\xCF") return true; 325cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xCF\xFA\xED\xFE") return true; 326cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 327cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 328cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 329cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} // end namespace llvm 330