Mercurial > pub > dyncall > dyncall
annotate dyncallback/dyncall_callback_ppc64.S @ 312:18de5758980e
- stability fix: avoid sigsegv in dynload's dlGetLibraryPath() in some cases (e.g. wrong handle given or OS specific quirk)
author | Tassilo Philipp |
---|---|
date | Tue, 29 Oct 2019 16:09:58 +0100 |
parents | 891e8ba15862 |
children | d982a00c2177 |
rev | line source |
---|---|
0 | 1 /* |
2 | |
3 Package: dyncall | |
4 Library: dyncallback | |
5 File: dyncallback/dyncall_callback_ppc64.S | |
6 Description: Callback Thunk - Implementation for PowerPC 64-bit | |
7 License: | |
8 | |
9 Copyright (c) 2014-2015 Masanori Mitsugi <mitsugi@linux.vnet.ibm.com> | |
10 | |
11 Permission to use, copy, modify, and distribute this software for any | |
12 purpose with or without fee is hereby granted, provided that the above | |
13 copyright notice and this permission notice appear in all copies. | |
14 | |
15 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
16 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
17 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
18 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
21 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
22 | |
23 */ | |
24 | |
7 | 25 #include "../portasm/portasm-ppc64.S" |
0 | 26 |
7 | 27 .text |
28 .align 2 | |
0 | 29 |
30 /* struct DCCallback */ | |
7 | 31 |
32 #if DC__ABI_PPC64_ELF_V != 2 | |
33 DCB_THUNK = 0 /* v1 */ | |
34 DCB_HANDLER = 64 | |
35 DCB_STACKCLEAN = 72 | |
36 DCB_USERDATA = 80 | |
37 #else | |
38 DCB_THUNK = 0 /* v2 */ | |
0 | 39 DCB_HANDLER = 48 |
40 DCB_STACKCLEAN = 56 | |
41 DCB_USERDATA = 64 | |
42 #endif | |
43 | |
44 /* struct DCArgs */ | |
7 | 45 |
46 ARGS_IREGS = 0 | |
47 ARGS_FREGS = ARGS_IREGS + 8*8 | |
48 ARGS_SP = ARGS_FREGS + 8*13 | |
49 ARGS_ICNT = ARGS_SP + 8 | |
50 ARGS_FCNT = ARGS_ICNT + 4 | |
51 ARGS_SIZE = ARGS_FCNT + 4 | |
0 | 52 |
53 /* struct DCValue */ | |
7 | 54 |
55 RESULT_SIZE = 8 | |
56 | |
57 /* Stack Offsets */ | |
0 | 58 |
7 | 59 SP_PREV = 0 |
60 SP_CR = SP_PREV + 8 | |
61 SP_LR = SP_CR + 8 | |
62 #if DC__ABI_PPC64_ELF_V != 2 | |
63 SP_TOC = 40 | |
64 SP_PAR = 48 | |
65 PAR_SZ = 64 | |
66 #else | |
67 SP_TOC = 24 | |
68 SP_PAR = 32 | |
69 PAR_SZ = 0 | |
70 #endif | |
71 SP_ARGS = SP_PAR + PAR_SZ | |
72 SP_IREGS = SP_ARGS + ARGS_IREGS | |
73 SP_FREGS = SP_ARGS + ARGS_FREGS | |
74 SP_SP = SP_ARGS + ARGS_SP | |
75 SP_ICNT = SP_ARGS + ARGS_ICNT | |
76 SP_FCNT = SP_ARGS + ARGS_FCNT | |
77 SP_RESULT = SP_ARGS + ARGS_SIZE | |
78 SP_LOCAL = SP_RESULT + RESULT_SIZE /* additional locals (reg 30/31) */ | |
79 SP_SIZE = SP_LOCAL + 2*8 | |
0 | 80 |
7 | 81 #define ALIGN(M,X) ( M+(X-1) & (-X) ) |
82 | |
83 FRAMESIZE = ALIGN(SP_SIZE,16) | |
84 | |
85 GLOBAL_C(dcCallbackThunkEntry) | |
86 ENTRY_C(dcCallbackThunkEntry) | |
87 | |
88 /* -------------------------------------------------------------------------- | |
89 | |
90 Input: | |
91 r1 Stack Pointer | |
92 r3-r10 Integer Arguments | |
93 f1-f8 Floating-point Arguments | |
94 r11 Thunk Pointer | |
95 | |
0 | 96 */ |
97 | |
98 mflr r0 | |
7 | 99 std r0, SP_LR(r1) /* store return address */ |
100 std r31, -8(r1) /* store preserved registers (r31) */ | |
101 addi r12, r1, SP_PAR /* temporary r12 = parameter area on callers stack frame */ | |
102 stdu r1, -FRAMESIZE(r1) /* save callers stack pointer and make new stack frame. */ | |
0 | 103 |
7 | 104 std r3, SP_IREGS + 0*8(r1) /* spill 8 integer parameter registers */ |
105 std r4, SP_IREGS + 1*8(r1) | |
106 std r5, SP_IREGS + 2*8(r1) | |
107 std r6, SP_IREGS + 3*8(r1) | |
108 std r7, SP_IREGS + 4*8(r1) | |
109 std r8, SP_IREGS + 5*8(r1) | |
110 std r9, SP_IREGS + 6*8(r1) | |
111 std r10,SP_IREGS + 7*8(r1) | |
112 stfd f1, SP_FREGS + 0*8(r1) /* spill 13 float parameter registers */ | |
113 stfd f2, SP_FREGS + 1*8(r1) | |
114 stfd f3, SP_FREGS + 2*8(r1) | |
115 stfd f4, SP_FREGS + 3*8(r1) | |
116 stfd f5, SP_FREGS + 4*8(r1) | |
117 stfd f6, SP_FREGS + 5*8(r1) | |
118 stfd f7, SP_FREGS + 6*8(r1) | |
119 stfd f8, SP_FREGS + 7*8(r1) | |
120 stfd f9, SP_FREGS + 8*8(r1) | |
121 stfd f10,SP_FREGS + 9*8(r1) | |
122 stfd f11,SP_FREGS +10*8(r1) | |
123 stfd f12,SP_FREGS +11*8(r1) | |
124 stfd f13,SP_FREGS +12*8(r1) | |
0 | 125 /* initialize struct DCCallback */ |
7 | 126 std r12,SP_SP(r1) /* init stack pointer */ |
0 | 127 xor r0, r0, r0 /* init register counters */ |
7 | 128 std r0, SP_ICNT(r1) |
129 std r0, SP_FCNT(r1) | |
130 std r0, SP_RESULT(r1) /* init result object */ | |
0 | 131 /* invoke callback handler */ |
7 | 132 mr r3, r11 /* arg 1: DCCallback* pcb (r11 is thunk pointer) */ |
133 addi r4, r1, SP_ARGS /* arg 2: DCArgs* args */ | |
134 addi r5, r1, SP_RESULT /* arg 3: DCValue* result */ | |
0 | 135 ld r6, DCB_USERDATA(r11) /* arg 4: void* userdata */ |
136 | |
137 /* branch-and-link to DCCallback.handler */ | |
138 ld r12, DCB_HANDLER(r11) | |
7 | 139 std r2, SP_TOC(r1) |
0 | 140 #if DC__ABI_PPC64_ELF_V != 2 |
141 ld r2, 8(r12) | |
142 ld r0, 0(r12) | |
143 mtctr r0 | |
144 #else | |
145 mtctr r12 | |
146 #endif | |
147 bctrl | |
148 | |
7 | 149 /* check result type */ |
240
891e8ba15862
- replaced character constants in ppc assembly files with their values for compatibility with older toolchains
Tassilo Philipp
parents:
7
diff
changeset
|
150 cmpi cr0, r3, 0x66 /* 'f */ |
0 | 151 beq .f32 |
240
891e8ba15862
- replaced character constants in ppc assembly files with their values for compatibility with older toolchains
Tassilo Philipp
parents:
7
diff
changeset
|
152 cmpi cr0, r3, 0x64 /* 'd */ |
0 | 153 beq .f64 |
7 | 154 .i64: |
155 ld r3, SP_RESULT(r1) | |
0 | 156 b .end |
157 .end: | |
158 | |
7 | 159 ld r2, SP_TOC(r1) |
160 ld r1, SP_PREV(r1) /* restore stack pointer */ | |
161 ld r31, -8(r1) /* restore preserved registers */ | |
162 ld r0, SP_LR(r1) /* load link register with return address */ | |
0 | 163 mtlr r0 |
7 | 164 blr /* branch back to link register */ |
165 .f32: | |
166 lfs f1, SP_RESULT(r1) | |
167 b .end | |
168 .f64: | |
169 lfd f1, SP_RESULT(r1) | |
170 b .end |