]>
Commit | Line | Data |
---|---|---|
6f15f698 TC |
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 | ||
6f317ef3 | 36 | /* Set up trampolines. */ |
6f15f698 TC |
37 | |
38 | .text | |
39 | .align 2 | |
40 | Ltrampoline_initial: | |
41 | mflr r0 | |
42 | bl 1f | |
43 | Lfunc = .-Ltrampoline_initial | |
44 | .long 0 /* will be replaced with function address */ | |
45 | Lchain = .-Ltrampoline_initial | |
46 | .long 0 /* will be replaced with static chain */ | |
47 | 1: 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 | ||
54 | trampoline_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 */ | |
65 | LCF0: | |
66 | mflr r11 | |
67 | addi 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 */ | |
80 | Lmove: | |
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 | |
91 | Lcache: | |
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 | ||
102 | Labort: | |
103 | #ifdef __DYNAMIC__ | |
104 | bl L_abort$stub | |
105 | .data | |
106 | .picsymbol_stub | |
107 | L_abort$stub: | |
108 | .indirect_symbol _abort | |
109 | mflr r0 | |
110 | bcl 20,31,L0$_abort | |
111 | L0$_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 | |
121 | L_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 | |
129 | LTRAMP: | |
130 | .long Ltrampoline_initial | |
131 |