1/* Special support for trampolines 2 * 3 * Copyright (C) 1996, 1997, 2000 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 2, or (at your option) any 9 * later version. 10 * 11 * In addition to the permissions in the GNU General Public License, the 12 * Free Software Foundation gives you unlimited permission to link the 13 * compiled version of this file with other programs, and to distribute 14 * those programs without any restriction coming from the use of this 15 * file. (The General Public License restrictions do apply in other 16 * respects; for example, they cover modification of the file, and 17 * distribution when not linked into another program.) 18 * 19 * This file is distributed in the hope that it will be useful, but 20 * WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 * General Public License for more details. 23 * 24 * You should have received a copy of the GNU General Public License 25 * along with this program; see the file COPYING. If not, write to 26 * the Free Software Foundation, 59 Temple Place - Suite 330, 27 * Boston, MA 02111-1307, USA. 28 * 29 * As a special exception, if you link this library with files 30 * compiled with GCC to produce an executable, this does not cause the 31 * resulting executable to be covered by the GNU General Public License. 32 * This exception does not however invalidate any other reasons why the 33 * executable file might be covered by the GNU General Public License. 34 */ 35 36/* Set up trampolines. */ 37 38.text 39 .align 2 40Ltrampoline_initial: 41 mflr r0 42 bl 1f 43Lfunc = .-Ltrampoline_initial 44 .long 0 /* will be replaced with function address */ 45Lchain = .-Ltrampoline_initial 46 .long 0 /* will be replaced with static chain */ 471: mflr r11 48 lwz r12,0(r11) /* function address */ 49 mtlr r0 50 mtctr r12 51 lwz r11,4(r11) /* static chain */ 52 bctr 53 54trampoline_size = .-Ltrampoline_initial 55 56/* R3 = stack address to store trampoline */ 57/* R4 = length of trampoline area */ 58/* R5 = function address */ 59/* R6 = static chain */ 60 61 .globl ___trampoline_setup 62___trampoline_setup: 63 mflr r0 /* save return address */ 64 bcl 20,31,LCF0 /* load up __trampoline_initial into r7 */ 65LCF0: 66 mflr r11 67 addis r7,r11,ha16(LTRAMP-LCF0) 68 lwz r7,lo16(LTRAMP-LCF0)(r7) 69 subi r7,r7,4 70 li r8,trampoline_size /* verify trampoline big enough */ 71 cmpw cr1,r8,r4 72 srwi r4,r4,2 /* # words to move */ 73 addi r9,r3,-4 /* adjust pointer for lwzu */ 74 mtctr r4 75 blt cr1,Labort 76 77 mtlr r0 78 79 /* Copy the instructions to the stack */ 80Lmove: 81 lwzu r10,4(r7) 82 stwu r10,4(r9) 83 bdnz Lmove 84 85 /* Store correct function and static chain */ 86 stw r5,Lfunc(r3) 87 stw r6,Lchain(r3) 88 89 /* Now flush both caches */ 90 mtctr r4 91Lcache: 92 icbi 0,r3 93 dcbf 0,r3 94 addi r3,r3,4 95 bdnz Lcache 96 97 /* Finally synchronize things & return */ 98 sync 99 isync 100 blr 101 102Labort: 103#ifdef __DYNAMIC__ 104 bl L_abort$stub 105.data 106.picsymbol_stub 107L_abort$stub: 108 .indirect_symbol _abort 109 mflr r0 110 bcl 20,31,L0$_abort 111L0$_abort: 112 mflr r11 113 addis r11,r11,ha16(L_abort$lazy_ptr-L0$_abort) 114 mtlr r0 115 lwz r12,lo16(L_abort$lazy_ptr-L0$_abort)(r11) 116 mtctr r12 117 addi r11,r11,lo16(L_abort$lazy_ptr-L0$_abort) 118 bctr 119.data 120.lazy_symbol_pointer 121L_abort$lazy_ptr: 122 .indirect_symbol _abort 123 .long dyld_stub_binding_helper 124#else 125 bl _abort 126#endif 127.data 128 .align 2 129LTRAMP: 130 .long Ltrampoline_initial 131 132