Mercurial > pub > dyncall > dyncall
annotate dyncall/dyncall_callvm_arm32_arm.c @ 27:523c45dfa8fb
- refactored arm calling conventions' callvm code, so that the code that keeps
the caller from overwriting the return value on some platforms also works on
OpenBSD (before we casted the function pointer to have long long as return
type, to hint the caller that there is one, but that triggers an intentional
SIGABRT on OpenBSD for security reasons; now the decl reflects this, directly)
author | cslag |
---|---|
date | Tue, 15 Sep 2015 12:48:52 +0200 |
parents | 17b10cc8ce8b |
children | 67961454902b |
rev | line source |
---|---|
0 | 1 /* |
2 | |
3 Package: dyncall | |
4 Library: dyncall | |
5 File: dyncall/dyncall_callvm_arm32_arm.c | |
6 Description: ARM 32-bit "arm" ABI callvm implementation | |
7 License: | |
8 | |
9 Copyright (c) 2007-2015 Daniel Adler <dadler@uni-goettingen.de>, | |
10 Tassilo Philipp <tphilipp@potion-studios.com> | |
11 | |
12 Permission to use, copy, modify, and distribute this software for any | |
13 purpose with or without fee is hereby granted, provided that the above | |
14 copyright notice and this permission notice appear in all copies. | |
15 | |
16 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
17 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
18 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
19 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
22 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
23 | |
24 */ | |
25 | |
26 | |
27 | |
28 /* | |
29 | |
30 dyncall callvm for 32bit ARM32 family of processors | |
31 | |
32 SUPPORTED CALLING CONVENTIONS | |
33 armcall | |
34 | |
35 REVISION | |
36 2007/12/11 initial | |
37 | |
38 */ | |
39 | |
40 | |
41 #include "dyncall_callvm_arm32_arm.h" | |
42 #include "dyncall_alloc.h" | |
43 | |
44 static void dc_callvm_mode_arm32_arm(DCCallVM* in_self,DCint mode); | |
45 | |
46 static DCCallVM* dc_callvm_new_arm32_arm(DCCallVM_vt* vt, DCsize size) | |
47 { | |
48 /* Store at least 16 bytes (4 words) for internal spill area. Assembly code depends on it. */ | |
49 DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*)dcAllocMem(sizeof(DCCallVM_arm32_arm)+size+16); | |
50 dc_callvm_base_init(&self->mInterface, vt); | |
51 dcVecInit(&self->mVecHead, size); | |
52 return (DCCallVM*)self; | |
53 } | |
54 | |
55 | |
56 static void dc_callvm_free_arm32_arm(DCCallVM* in_self) | |
57 { | |
58 dcFreeMem(in_self); | |
59 } | |
60 | |
61 | |
62 static void dc_callvm_reset_arm32_arm(DCCallVM* in_self) | |
63 { | |
64 DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*)in_self; | |
65 dcVecReset(&self->mVecHead); | |
66 } | |
67 | |
68 | |
69 static void dc_callvm_argInt_arm32_arm(DCCallVM* in_self, DCint x) | |
70 { | |
71 DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*)in_self; | |
72 dcVecAppend(&self->mVecHead, &x, sizeof(DCint)); | |
73 } | |
74 | |
75 | |
76 static void dc_callvm_argBool_arm32_arm(DCCallVM* in_self, DCbool x) | |
77 { | |
78 dc_callvm_argInt_arm32_arm(in_self, (DCint)x); | |
79 } | |
80 | |
81 | |
82 static void dc_callvm_argChar_arm32_arm(DCCallVM* in_self, DCchar x) | |
83 { | |
84 dc_callvm_argInt_arm32_arm(in_self, x); | |
85 } | |
86 | |
87 | |
88 static void dc_callvm_argShort_arm32_arm(DCCallVM* in_self, DCshort x) | |
89 { | |
90 dc_callvm_argInt_arm32_arm(in_self, x); | |
91 } | |
92 | |
93 | |
94 static void dc_callvm_argLong_arm32_arm(DCCallVM* in_self, DClong x) | |
95 { | |
96 dc_callvm_argInt_arm32_arm(in_self, x); | |
97 } | |
98 | |
99 | |
100 static void dc_callvm_argLongLong_arm32_arm(DCCallVM* in_self, DClonglong x) | |
101 { | |
102 DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*)in_self; | |
103 dcVecAppend(&self->mVecHead, &x, sizeof(DClonglong)); | |
104 } | |
105 | |
106 | |
107 static void dc_callvm_argLongLong_arm32_arm_eabi(DCCallVM* in_self, DClonglong x) | |
108 { | |
109 DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*)in_self; | |
110 | |
111 /* 64 bit values need to be aligned on 8 byte boundaries */ | |
112 dcVecSkip(&self->mVecHead, dcVecSize(&self->mVecHead) & 4); | |
113 dcVecAppend(&self->mVecHead, &x, sizeof(DClonglong)); | |
114 } | |
115 | |
116 | |
117 static void dc_callvm_argFloat_arm32_arm(DCCallVM* in_self, DCfloat x) | |
118 { | |
119 DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*)in_self; | |
120 dcVecAppend(&self->mVecHead, &x, sizeof(DCfloat)); | |
121 } | |
122 | |
123 | |
124 static void dc_callvm_argDouble_arm32_arm(DCCallVM* in_self, DCdouble x) | |
125 { | |
126 DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*)in_self; | |
127 dcVecAppend(&self->mVecHead, &x, sizeof(DCdouble)); | |
128 } | |
129 | |
130 | |
131 static void dc_callvm_argDouble_arm32_arm_eabi(DCCallVM* in_self, DCdouble x) | |
132 { | |
133 DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*)in_self; | |
134 | |
135 /* 64 bit values need to be aligned on 8 byte boundaries */ | |
136 dcVecSkip(&self->mVecHead, dcVecSize(&self->mVecHead) & 4); | |
137 dcVecAppend(&self->mVecHead, &x, sizeof(DCdouble)); | |
138 } | |
139 | |
140 | |
141 static void dc_callvm_argPointer_arm32_arm(DCCallVM* in_self, DCpointer x) | |
142 { | |
143 DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*)in_self; | |
144 dcVecAppend(&self->mVecHead, &x, sizeof(DCpointer)); | |
145 } | |
146 | |
147 | |
148 /* Call. */ | |
149 void dc_callvm_call_arm32_arm(DCCallVM* in_self, DCpointer target) | |
150 { | |
151 DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*)in_self; | |
27
523c45dfa8fb
- refactored arm calling conventions' callvm code, so that the code that keeps
cslag
parents:
17
diff
changeset
|
152 dcCall_arm32_arm(target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead)); |
0 | 153 } |
154 | |
155 | |
156 DCCallVM_vt gVT_arm32_arm = | |
157 { | |
158 &dc_callvm_free_arm32_arm | |
159 , &dc_callvm_reset_arm32_arm | |
160 , &dc_callvm_mode_arm32_arm | |
161 , &dc_callvm_argBool_arm32_arm | |
162 , &dc_callvm_argChar_arm32_arm | |
163 , &dc_callvm_argShort_arm32_arm | |
164 , &dc_callvm_argInt_arm32_arm | |
165 , &dc_callvm_argLong_arm32_arm | |
166 , &dc_callvm_argLongLong_arm32_arm | |
167 , &dc_callvm_argFloat_arm32_arm | |
168 , &dc_callvm_argDouble_arm32_arm | |
169 , &dc_callvm_argPointer_arm32_arm | |
170 , NULL /* argStruct */ | |
171 , (DCvoidvmfunc*) &dc_callvm_call_arm32_arm | |
172 , (DCboolvmfunc*) &dc_callvm_call_arm32_arm | |
173 , (DCcharvmfunc*) &dc_callvm_call_arm32_arm | |
174 , (DCshortvmfunc*) &dc_callvm_call_arm32_arm | |
175 , (DCintvmfunc*) &dc_callvm_call_arm32_arm | |
176 , (DClongvmfunc*) &dc_callvm_call_arm32_arm | |
177 , (DClonglongvmfunc*) &dc_callvm_call_arm32_arm | |
178 , (DCfloatvmfunc*) &dc_callvm_call_arm32_arm | |
179 , (DCdoublevmfunc*) &dc_callvm_call_arm32_arm | |
180 , (DCpointervmfunc*) &dc_callvm_call_arm32_arm | |
181 , NULL /* callStruct */ | |
182 }; | |
183 | |
184 | |
185 DCCallVM_vt gVT_arm32_arm_eabi = | |
186 { | |
187 &dc_callvm_free_arm32_arm | |
188 , &dc_callvm_reset_arm32_arm | |
189 , &dc_callvm_mode_arm32_arm | |
190 , &dc_callvm_argBool_arm32_arm | |
191 , &dc_callvm_argChar_arm32_arm | |
192 , &dc_callvm_argShort_arm32_arm | |
193 , &dc_callvm_argInt_arm32_arm | |
194 , &dc_callvm_argLong_arm32_arm | |
195 , &dc_callvm_argLongLong_arm32_arm_eabi | |
196 , &dc_callvm_argFloat_arm32_arm | |
197 , &dc_callvm_argDouble_arm32_arm_eabi | |
198 , &dc_callvm_argPointer_arm32_arm | |
199 , NULL /* argStruct */ | |
200 , (DCvoidvmfunc*) &dc_callvm_call_arm32_arm | |
201 , (DCboolvmfunc*) &dc_callvm_call_arm32_arm | |
202 , (DCcharvmfunc*) &dc_callvm_call_arm32_arm | |
203 , (DCshortvmfunc*) &dc_callvm_call_arm32_arm | |
204 , (DCintvmfunc*) &dc_callvm_call_arm32_arm | |
205 , (DClongvmfunc*) &dc_callvm_call_arm32_arm | |
206 , (DClonglongvmfunc*) &dc_callvm_call_arm32_arm | |
207 , (DCfloatvmfunc*) &dc_callvm_call_arm32_arm | |
208 , (DCdoublevmfunc*) &dc_callvm_call_arm32_arm | |
209 , (DCpointervmfunc*) &dc_callvm_call_arm32_arm | |
210 , NULL /* callStruct */ | |
211 }; | |
212 | |
213 | |
214 DCCallVM* dcNewCallVM_arm32_arm(DCsize size) | |
215 { | |
216 /* Check OS if we need EABI as default. */ | |
217 #if defined(DC__ABI_ARM_EABI) | |
218 return dc_callvm_new_arm32_arm(&gVT_arm32_arm_eabi, size); | |
219 #else | |
220 return dc_callvm_new_arm32_arm(&gVT_arm32_arm, size); | |
221 #endif | |
222 } | |
223 | |
224 | |
225 DCCallVM* dcNewCallVM(DCsize size) | |
226 { | |
227 return dcNewCallVM_arm32_arm(size); | |
228 } | |
229 | |
230 static void dc_callvm_mode_arm32_arm(DCCallVM* in_self,DCint mode) | |
231 { | |
232 DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*) in_self; | |
233 DCCallVM_vt* vt; | |
234 switch(mode) { | |
235 /* Check OS if we need EABI as default. */ | |
236 case DC_CALL_C_ELLIPSIS: | |
237 case DC_CALL_C_ELLIPSIS_VARARGS: | |
238 #if defined(DC__ABI_ARM_EABI) | |
239 case DC_CALL_C_DEFAULT: vt = &gVT_arm32_arm_eabi; break; | |
240 #else | |
241 case DC_CALL_C_DEFAULT: vt = &gVT_arm32_arm; break; | |
242 #endif | |
243 case DC_CALL_C_ARM_ARM: vt = &gVT_arm32_arm; break; | |
244 case DC_CALL_C_ARM_ARM_EABI: vt = &gVT_arm32_arm_eabi; break; | |
245 default: | |
246 in_self->mError = DC_ERROR_UNSUPPORTED_MODE; | |
247 return; | |
248 } | |
249 self->mInterface.mVTpointer = vt; | |
250 } | |
251 |