137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===-- RuntimeDyldMachOAArch64.h -- MachO/AArch64 specific code. -*- C++ -*-=// 237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// The LLVM Compiler Infrastructure 437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// This file is distributed under the University of Illinois Open Source 637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// License. See LICENSE.TXT for details. 737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===// 937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 1037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDMACHOAARCH64_H 1137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDMACHOAARCH64_H 1237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 1337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "../RuntimeDyldMachO.h" 1437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/Endian.h" 1537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 1637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define DEBUG_TYPE "dyld" 1737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 1837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesnamespace llvm { 1937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 2037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesclass RuntimeDyldMachOAArch64 2137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines : public RuntimeDyldMachOCRTPBase<RuntimeDyldMachOAArch64> { 2237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinespublic: 2337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 2437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines typedef uint64_t TargetPtrT; 2537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 262c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar RuntimeDyldMachOAArch64(RuntimeDyld::MemoryManager &MM, 272c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar RuntimeDyld::SymbolResolver &Resolver) 282c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar : RuntimeDyldMachOCRTPBase(MM, Resolver) {} 2937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 3037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines unsigned getMaxStubSize() override { return 8; } 3137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 3237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines unsigned getStubAlignment() override { return 8; } 3337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 3437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /// Extract the addend encoded in the instruction / memory location. 3537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int64_t decodeAddend(const RelocationEntry &RE) const { 3637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const SectionEntry &Section = Sections[RE.SectionID]; 3737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint8_t *LocalAddress = Section.Address + RE.Offset; 3837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines unsigned NumBytes = 1 << RE.Size; 3937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int64_t Addend = 0; 4037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Verify that the relocation has the correct size and alignment. 4137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines switch (RE.RelType) { 4237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines default: 4337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm_unreachable("Unsupported relocation type!"); 4437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_UNSIGNED: 4537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert((NumBytes == 4 || NumBytes == 8) && "Invalid relocation size."); 4637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 4737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_BRANCH26: 4837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_PAGE21: 4937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_PAGEOFF12: 5037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_GOT_LOAD_PAGE21: 5137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12: 5237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(NumBytes == 4 && "Invalid relocation size."); 5337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert((((uintptr_t)LocalAddress & 0x3) == 0) && 5437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "Instruction address is not aligned to 4 bytes."); 5537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 5637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 5737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 5837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines switch (RE.RelType) { 5937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines default: 6037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm_unreachable("Unsupported relocation type!"); 6137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_UNSIGNED: 6237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // This could be an unaligned memory location. 6337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (NumBytes == 4) 6437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Addend = *reinterpret_cast<support::ulittle32_t *>(LocalAddress); 6537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else 6637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Addend = *reinterpret_cast<support::ulittle64_t *>(LocalAddress); 6737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 6837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_BRANCH26: { 6937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Verify that the relocation points to the expected branch instruction. 7037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress); 7137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert((*p & 0xFC000000) == 0x14000000 && "Expected branch instruction."); 7237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 7337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Get the 26 bit addend encoded in the branch instruction and sign-extend 7437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // to 64 bit. The lower 2 bits are always zeros and are therefore implicit 7537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // (<< 2). 7637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Addend = (*p & 0x03FFFFFF) << 2; 7737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Addend = SignExtend64(Addend, 28); 7837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 7937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 8037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_GOT_LOAD_PAGE21: 8137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_PAGE21: { 8237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Verify that the relocation points to the expected adrp instruction. 8337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress); 8437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert((*p & 0x9F000000) == 0x90000000 && "Expected adrp instruction."); 8537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 8637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Get the 21 bit addend encoded in the adrp instruction and sign-extend 8737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // to 64 bit. The lower 12 bits (4096 byte page) are always zeros and are 8837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // therefore implicit (<< 12). 8937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Addend = ((*p & 0x60000000) >> 29) | ((*p & 0x01FFFFE0) >> 3) << 12; 9037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Addend = SignExtend64(Addend, 33); 9137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 9237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 9337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12: { 9437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Verify that the relocation points to one of the expected load / store 9537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // instructions. 9637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress); 9737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines (void)p; 9837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert((*p & 0x3B000000) == 0x39000000 && 9937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "Only expected load / store instructions."); 10037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } // fall-through 10137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_PAGEOFF12: { 10237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Verify that the relocation points to one of the expected load / store 10337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // or add / sub instructions. 10437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress); 10537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert((((*p & 0x3B000000) == 0x39000000) || 10637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ((*p & 0x11C00000) == 0x11000000) ) && 10737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "Expected load / store or add/sub instruction."); 10837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 10937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Get the 12 bit addend encoded in the instruction. 11037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Addend = (*p & 0x003FFC00) >> 10; 11137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 11237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Check which instruction we are decoding to obtain the implicit shift 11337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // factor of the instruction. 11437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int ImplicitShift = 0; 11537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if ((*p & 0x3B000000) == 0x39000000) { // << load / store 11637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // For load / store instructions the size is encoded in bits 31:30. 11737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ImplicitShift = ((*p >> 30) & 0x3); 11837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (ImplicitShift == 0) { 11937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Check if this a vector op to get the correct shift value. 12037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if ((*p & 0x04800000) == 0x04800000) 12137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ImplicitShift = 4; 12237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 12337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 12437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Compensate for implicit shift. 12537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Addend <<= ImplicitShift; 12637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 12737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 12837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 12937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return Addend; 13037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 13137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 13237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /// Extract the addend encoded in the instruction. 13337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines void encodeAddend(uint8_t *LocalAddress, unsigned NumBytes, 13437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MachO::RelocationInfoType RelType, int64_t Addend) const { 13537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Verify that the relocation has the correct alignment. 13637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines switch (RelType) { 13737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines default: 13837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm_unreachable("Unsupported relocation type!"); 13937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_UNSIGNED: 14037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert((NumBytes == 4 || NumBytes == 8) && "Invalid relocation size."); 14137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 14237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_BRANCH26: 14337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_PAGE21: 14437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_PAGEOFF12: 14537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_GOT_LOAD_PAGE21: 14637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12: 14737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(NumBytes == 4 && "Invalid relocation size."); 14837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert((((uintptr_t)LocalAddress & 0x3) == 0) && 14937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "Instruction address is not aligned to 4 bytes."); 15037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 15137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 15237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 15337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines switch (RelType) { 15437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines default: 15537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm_unreachable("Unsupported relocation type!"); 15637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_UNSIGNED: 15737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // This could be an unaligned memory location. 15837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (NumBytes == 4) 15937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines *reinterpret_cast<support::ulittle32_t *>(LocalAddress) = Addend; 16037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else 16137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines *reinterpret_cast<support::ulittle64_t *>(LocalAddress) = Addend; 16237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 16337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_BRANCH26: { 16437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress); 16537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Verify that the relocation points to the expected branch instruction. 16637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert((*p & 0xFC000000) == 0x14000000 && "Expected branch instruction."); 16737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 16837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Verify addend value. 16937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert((Addend & 0x3) == 0 && "Branch target is not aligned"); 17037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(isInt<28>(Addend) && "Branch target is out of range."); 17137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 17237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Encode the addend as 26 bit immediate in the branch instruction. 17337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines *p = (*p & 0xFC000000) | ((uint32_t)(Addend >> 2) & 0x03FFFFFF); 17437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 17537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 17637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_GOT_LOAD_PAGE21: 17737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_PAGE21: { 17837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Verify that the relocation points to the expected adrp instruction. 17937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress); 18037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert((*p & 0x9F000000) == 0x90000000 && "Expected adrp instruction."); 18137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 18237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Check that the addend fits into 21 bits (+ 12 lower bits). 18337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert((Addend & 0xFFF) == 0 && "ADRP target is not page aligned."); 18437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(isInt<33>(Addend) && "Invalid page reloc value."); 18537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 18637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Encode the addend into the instruction. 187ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint32_t ImmLoValue = ((uint64_t)Addend << 17) & 0x60000000; 188ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines uint32_t ImmHiValue = ((uint64_t)Addend >> 9) & 0x00FFFFE0; 18937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines *p = (*p & 0x9F00001F) | ImmHiValue | ImmLoValue; 19037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 19137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 19237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12: { 19337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Verify that the relocation points to one of the expected load / store 19437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // instructions. 19537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress); 19637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert((*p & 0x3B000000) == 0x39000000 && 19737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "Only expected load / store instructions."); 19837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines (void)p; 19937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } // fall-through 20037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_PAGEOFF12: { 20137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Verify that the relocation points to one of the expected load / store 20237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // or add / sub instructions. 20337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress); 20437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert((((*p & 0x3B000000) == 0x39000000) || 20537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ((*p & 0x11C00000) == 0x11000000) ) && 20637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "Expected load / store or add/sub instruction."); 20737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 20837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Check which instruction we are decoding to obtain the implicit shift 20937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // factor of the instruction and verify alignment. 21037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int ImplicitShift = 0; 21137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if ((*p & 0x3B000000) == 0x39000000) { // << load / store 21237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // For load / store instructions the size is encoded in bits 31:30. 21337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ImplicitShift = ((*p >> 30) & 0x3); 21437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines switch (ImplicitShift) { 21537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case 0: 21637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Check if this a vector op to get the correct shift value. 21737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if ((*p & 0x04800000) == 0x04800000) { 21837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ImplicitShift = 4; 21937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(((Addend & 0xF) == 0) && 22037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "128-bit LDR/STR not 16-byte aligned."); 22137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 22237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 22337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case 1: 22437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(((Addend & 0x1) == 0) && "16-bit LDR/STR not 2-byte aligned."); 22537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 22637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case 2: 22737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(((Addend & 0x3) == 0) && "32-bit LDR/STR not 4-byte aligned."); 22837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 22937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case 3: 23037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(((Addend & 0x7) == 0) && "64-bit LDR/STR not 8-byte aligned."); 23137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 23237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 23337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 23437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Compensate for implicit shift. 23537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Addend >>= ImplicitShift; 23637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(isUInt<12>(Addend) && "Addend cannot be encoded."); 23737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 23837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Encode the addend into the instruction. 23937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines *p = (*p & 0xFFC003FF) | ((uint32_t)(Addend << 10) & 0x003FFC00); 24037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 24137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 24237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 24337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 24437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 24537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines relocation_iterator 24637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines processRelocationRef(unsigned SectionID, relocation_iterator RelI, 247ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const ObjectFile &BaseObjT, 248ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ObjSectionToIDMap &ObjSectionToID, 249ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StubMap &Stubs) override { 25037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const MachOObjectFile &Obj = 251ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines static_cast<const MachOObjectFile &>(BaseObjT); 25237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MachO::any_relocation_info RelInfo = 25337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Obj.getRelocation(RelI->getRawDataRefImpl()); 25437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 25537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(!Obj.isRelocationScattered(RelInfo) && ""); 25637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 25737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // ARM64 has an ARM64_RELOC_ADDEND relocation type that carries an explicit 25837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // addend for the following relocation. If found: (1) store the associated 25937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // addend, (2) consume the next relocation, and (3) use the stored addend to 26037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // override the addend. 26137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int64_t ExplicitAddend = 0; 26237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Obj.getAnyRelocationType(RelInfo) == MachO::ARM64_RELOC_ADDEND) { 26337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(!Obj.getPlainRelocationExternal(RelInfo)); 26437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(!Obj.getAnyRelocationPCRel(RelInfo)); 26537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(Obj.getAnyRelocationLength(RelInfo) == 2); 26637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int64_t RawAddend = Obj.getPlainRelocationSymbolNum(RelInfo); 26737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Sign-extend the 24-bit to 64-bit. 26837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ExplicitAddend = SignExtend64(RawAddend, 24); 26937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ++RelI; 27037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RelInfo = Obj.getRelocation(RelI->getRawDataRefImpl()); 27137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 27237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 273ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI)); 27437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RE.Addend = decodeAddend(RE); 27537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RelocationValueRef Value( 276ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getRelocationValueRef(Obj, RelI, RE, ObjSectionToID)); 27737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 27837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert((ExplicitAddend == 0 || RE.Addend == 0) && "Relocation has "\ 27937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "ARM64_RELOC_ADDEND and embedded addend in the instruction."); 28037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (ExplicitAddend) { 28137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RE.Addend = ExplicitAddend; 28237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Value.Offset = ExplicitAddend; 28337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 28437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 28537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool IsExtern = Obj.getPlainRelocationExternal(RelInfo); 28637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!IsExtern && RE.IsPCRel) 287ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines makeValueAddendPCRel(Value, Obj, RelI, 1 << RE.Size); 28837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 28937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RE.Addend = Value.Offset; 29037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 29137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (RE.RelType == MachO::ARM64_RELOC_GOT_LOAD_PAGE21 || 29237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RE.RelType == MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12) 29337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines processGOTRelocation(RE, Value, Stubs); 29437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else { 29537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Value.SymbolName) 29637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines addRelocationForSymbol(RE, Value.SymbolName); 29737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else 29837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines addRelocationForSection(RE, Value.SectionID); 29937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 30037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 30137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return ++RelI; 30237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 30337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 30437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override { 30537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DEBUG(dumpRelocationToResolve(RE, Value)); 30637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 30737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const SectionEntry &Section = Sections[RE.SectionID]; 30837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint8_t *LocalAddress = Section.Address + RE.Offset; 30937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MachO::RelocationInfoType RelType = 31037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines static_cast<MachO::RelocationInfoType>(RE.RelType); 31137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 31237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines switch (RelType) { 31337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines default: 31437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm_unreachable("Invalid relocation type!"); 31537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_UNSIGNED: { 31637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(!RE.IsPCRel && "PCRel and ARM64_RELOC_UNSIGNED not supported"); 31737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Mask in the target value a byte at a time (we don't have an alignment 31837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // guarantee for the target address, so this is safest). 31937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (RE.Size < 2) 32037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm_unreachable("Invalid size for ARM64_RELOC_UNSIGNED"); 32137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 32237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines encodeAddend(LocalAddress, 1 << RE.Size, RelType, Value + RE.Addend); 32337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 32437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 32537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_BRANCH26: { 32637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(RE.IsPCRel && "not PCRel and ARM64_RELOC_BRANCH26 not supported"); 32737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Check if branch is in range. 32837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint64_t FinalAddress = Section.LoadAddress + RE.Offset; 32937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int64_t PCRelVal = Value - FinalAddress + RE.Addend; 33037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines encodeAddend(LocalAddress, /*Size=*/4, RelType, PCRelVal); 33137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 33237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 33337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_GOT_LOAD_PAGE21: 33437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_PAGE21: { 33537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(RE.IsPCRel && "not PCRel and ARM64_RELOC_PAGE21 not supported"); 33637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Adjust for PC-relative relocation and offset. 33737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uint64_t FinalAddress = Section.LoadAddress + RE.Offset; 33837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int64_t PCRelVal = 33937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ((Value + RE.Addend) & (-4096)) - (FinalAddress & (-4096)); 34037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines encodeAddend(LocalAddress, /*Size=*/4, RelType, PCRelVal); 34137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 34237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 34337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12: 34437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_PAGEOFF12: { 34537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(!RE.IsPCRel && "PCRel and ARM64_RELOC_PAGEOFF21 not supported"); 34637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Add the offset from the symbol. 34737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Value += RE.Addend; 34837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Mask out the page address and only use the lower 12 bits. 34937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Value &= 0xFFF; 35037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines encodeAddend(LocalAddress, /*Size=*/4, RelType, Value); 35137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 35237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 35337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_SUBTRACTOR: 35437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_POINTER_TO_GOT: 35537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21: 35637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12: 35737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm_unreachable("Relocation type not yet implemented!"); 35837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case MachO::ARM64_RELOC_ADDEND: 35937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm_unreachable("ARM64_RELOC_ADDEND should have been handeled by " 36037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "processRelocationRef!"); 36137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 36237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 36337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 364ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void finalizeSection(const ObjectFile &Obj, unsigned SectionID, 36537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const SectionRef &Section) {} 36637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 36737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesprivate: 36837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines void processGOTRelocation(const RelocationEntry &RE, 36937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RelocationValueRef &Value, StubMap &Stubs) { 37037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(RE.Size == 2); 37137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SectionEntry &Section = Sections[RE.SectionID]; 37237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StubMap::const_iterator i = Stubs.find(Value); 37337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int64_t Offset; 37437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (i != Stubs.end()) 37537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Offset = static_cast<int64_t>(i->second); 37637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else { 37737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // FIXME: There must be a better way to do this then to check and fix the 37837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // alignment every time!!! 37937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uintptr_t BaseAddress = uintptr_t(Section.Address); 38037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uintptr_t StubAlignment = getStubAlignment(); 38137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines uintptr_t StubAddress = 38237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines (BaseAddress + Section.StubOffset + StubAlignment - 1) & 38337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines -StubAlignment; 38437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines unsigned StubOffset = StubAddress - BaseAddress; 38537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Stubs[Value] = StubOffset; 38637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines assert(((StubAddress % getStubAlignment()) == 0) && 38737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "GOT entry not aligned"); 38837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RelocationEntry GOTRE(RE.SectionID, StubOffset, 38937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MachO::ARM64_RELOC_UNSIGNED, Value.Offset, 39037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /*IsPCRel=*/false, /*Size=*/3); 39137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Value.SymbolName) 39237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines addRelocationForSymbol(GOTRE, Value.SymbolName); 39337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines else 39437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines addRelocationForSection(GOTRE, Value.SectionID); 39537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Section.StubOffset = StubOffset + getMaxStubSize(); 39637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Offset = static_cast<int64_t>(StubOffset); 39737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 39837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RelocationEntry TargetRE(RE.SectionID, RE.Offset, RE.RelType, Offset, 39937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RE.IsPCRel, RE.Size); 40037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines addRelocationForSection(TargetRE, RE.SectionID); 40137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 40237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}; 40337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 40437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 40537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#undef DEBUG_TYPE 40637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 40737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#endif 408