1/* Special support for trampolines 2 * 3 * Copyright (C) 1996-2020 Free Software Foundation, Inc. 4 * Written By Michael Meissner 5 * 6 * This file is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the 8 * Free Software Foundation; either version 3, or (at your option) any 9 * later version. 10 * 11 * This file is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 * 16 * Under Section 7 of GPL version 3, you are granted additional 17 * permissions described in the GCC Runtime Library Exception, version 18 * 3.1, as published by the Free Software Foundation. 19 * 20 * You should have received a copy of the GNU General Public License and 21 * a copy of the GCC Runtime Library Exception along with this program; 22 * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 * <http://www.gnu.org/licenses/>. 24 */ 25 26#include "darwin-asm.h" 27 28/* Set up trampolines. */ 29 30.text 31 .align LOG2_GPR_BYTES 32Ltrampoline_initial: 33 mflr r0 34 bl 1f 35Lfunc = .-Ltrampoline_initial 36 .g_long 0 /* will be replaced with function address */ 37Lchain = .-Ltrampoline_initial 38 .g_long 0 /* will be replaced with static chain */ 391: mflr r11 40 lg r12,0(r11) /* function address */ 41 mtlr r0 42 mtctr r12 43 lg r11,GPR_BYTES(r11) /* static chain */ 44 bctr 45 46trampoline_size = .-Ltrampoline_initial 47 48/* R3 = stack address to store trampoline */ 49/* R4 = length of trampoline area */ 50/* R5 = function address */ 51/* R6 = static chain */ 52 53 .globl ___trampoline_setup 54___trampoline_setup: 55 mflr r0 /* save return address */ 56 bcl 20,31,LCF0 /* load up __trampoline_initial into r7 */ 57LCF0: 58 mflr r11 59 addis r7,r11,ha16(LTRAMP-LCF0) 60 lg r7,lo16(LTRAMP-LCF0)(r7) 61 subi r7,r7,4 62 li r8,trampoline_size /* verify trampoline big enough */ 63 cmpg cr1,r8,r4 64 srwi r4,r4,2 /* # words to move (insns always 4-byte) */ 65 addi r9,r3,-4 /* adjust pointer for lgu */ 66 mtctr r4 67 blt cr1,Labort 68 69 mtlr r0 70 71 /* Copy the instructions to the stack */ 72Lmove: 73 lwzu r10,4(r7) 74 stwu r10,4(r9) 75 bdnz Lmove 76 77 /* Store correct function and static chain */ 78 stg r5,Lfunc(r3) 79 stg r6,Lchain(r3) 80 81 /* Now flush both caches */ 82 mtctr r4 83Lcache: 84 icbi 0,r3 85 dcbf 0,r3 86 addi r3,r3,4 87 bdnz Lcache 88 89 /* Ensure cache-flushing has finished. */ 90 sync 91 isync 92 93 /* Make stack writeable. */ 94 b ___enable_execute_stack 95 96Labort: 97#ifdef __DYNAMIC__ 98 bl L_abort$stub 99.data 100.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 101 .align 2 102L_abort$stub: 103 .indirect_symbol _abort 104 mflr r0 105 bcl 20,31,L0$_abort 106L0$_abort: 107 mflr r11 108 addis r11,r11,ha16(L_abort$lazy_ptr-L0$_abort) 109 mtlr r0 110 lgu r12,lo16(L_abort$lazy_ptr-L0$_abort)(r11) 111 mtctr r12 112 bctr 113.data 114.lazy_symbol_pointer 115L_abort$lazy_ptr: 116 .indirect_symbol _abort 117 .g_long dyld_stub_binding_helper 118#else 119 bl _abort 120#endif 121.data 122 .align LOG2_GPR_BYTES 123LTRAMP: 124 .g_long Ltrampoline_initial 125 126