1 |
voyageur 08/06/30 13:08:51 |
2 |
|
3 |
Added: gnustep-base-1.16.1-libffi_fix.patch |
4 |
Log: |
5 |
Fix libbfi support on amd64, bug #189205 |
6 |
(Portage version: 2.2_rc1/cvs/Linux 2.6.25-gentoo-r4 x86_64) |
7 |
|
8 |
Revision Changes Path |
9 |
1.1 gnustep-base/gnustep-base/files/gnustep-base-1.16.1-libffi_fix.patch |
10 |
|
11 |
file : http://sources.gentoo.org/viewcvs.py/gentoo-x86/gnustep-base/gnustep-base/files/gnustep-base-1.16.1-libffi_fix.patch?rev=1.1&view=markup |
12 |
plain: http://sources.gentoo.org/viewcvs.py/gentoo-x86/gnustep-base/gnustep-base/files/gnustep-base-1.16.1-libffi_fix.patch?rev=1.1&content-type=text/plain |
13 |
|
14 |
Index: gnustep-base-1.16.1-libffi_fix.patch |
15 |
=================================================================== |
16 |
diff -Naur gnustep-base-1.16.1.orig/configure gnustep-base-1.16.1/configure |
17 |
--- gnustep-base-1.16.1.orig/configure 2008-06-30 14:54:14.000000000 +0200 |
18 |
+++ gnustep-base-1.16.1/configure 2008-06-30 14:54:20.000000000 +0200 |
19 |
@@ -13140,7 +13140,7 @@ |
20 |
|
21 |
|
22 |
#-------------------------------------------------------------------- |
23 |
-# These functions needed by NSData.m |
24 |
+# These functions needed by NSData.m and GSFFIInvocation.m |
25 |
#-------------------------------------------------------------------- |
26 |
|
27 |
for ac_func in mkstemp |
28 |
@@ -13425,6 +13425,240 @@ |
29 |
done |
30 |
|
31 |
|
32 |
+for ac_func in mprotect |
33 |
+do |
34 |
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` |
35 |
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5 |
36 |
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } |
37 |
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then |
38 |
+ echo $ECHO_N "(cached) $ECHO_C" >&6 |
39 |
+else |
40 |
+ cat >conftest.$ac_ext <<_ACEOF |
41 |
+/* confdefs.h. */ |
42 |
+_ACEOF |
43 |
+cat confdefs.h >>conftest.$ac_ext |
44 |
+cat >>conftest.$ac_ext <<_ACEOF |
45 |
+/* end confdefs.h. */ |
46 |
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. |
47 |
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */ |
48 |
+#define $ac_func innocuous_$ac_func |
49 |
+ |
50 |
+/* System header to define __stub macros and hopefully few prototypes, |
51 |
+ which can conflict with char $ac_func (); below. |
52 |
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since |
53 |
+ <limits.h> exists even on freestanding compilers. */ |
54 |
+ |
55 |
+#ifdef __STDC__ |
56 |
+# include <limits.h> |
57 |
+#else |
58 |
+# include <assert.h> |
59 |
+#endif |
60 |
+ |
61 |
+#undef $ac_func |
62 |
+ |
63 |
+/* Override any GCC internal prototype to avoid an error. |
64 |
+ Use char because int might match the return type of a GCC |
65 |
+ builtin and then its argument prototype would still apply. */ |
66 |
+#ifdef __cplusplus |
67 |
+extern "C" |
68 |
+#endif |
69 |
+char $ac_func (); |
70 |
+/* The GNU C library defines this for functions which it implements |
71 |
+ to always fail with ENOSYS. Some functions are actually named |
72 |
+ something starting with __ and the normal name is an alias. */ |
73 |
+#if defined __stub_$ac_func || defined __stub___$ac_func |
74 |
+choke me |
75 |
+#endif |
76 |
+ |
77 |
+int |
78 |
+main () |
79 |
+{ |
80 |
+return $ac_func (); |
81 |
+ ; |
82 |
+ return 0; |
83 |
+} |
84 |
+_ACEOF |
85 |
+rm -f conftest.$ac_objext conftest$ac_exeext |
86 |
+if { (ac_try="$ac_link" |
87 |
+case "(($ac_try" in |
88 |
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; |
89 |
+ *) ac_try_echo=$ac_try;; |
90 |
+esac |
91 |
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 |
92 |
+ (eval "$ac_link") 2>conftest.er1 |
93 |
+ ac_status=$? |
94 |
+ grep -v '^ *+' conftest.er1 >conftest.err |
95 |
+ rm -f conftest.er1 |
96 |
+ cat conftest.err >&5 |
97 |
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
98 |
+ (exit $ac_status); } && { |
99 |
+ test -z "$ac_c_werror_flag" || |
100 |
+ test ! -s conftest.err |
101 |
+ } && test -s conftest$ac_exeext && |
102 |
+ $as_test_x conftest$ac_exeext; then |
103 |
+ eval "$as_ac_var=yes" |
104 |
+else |
105 |
+ echo "$as_me: failed program was:" >&5 |
106 |
+sed 's/^/| /' conftest.$ac_ext >&5 |
107 |
+ |
108 |
+ eval "$as_ac_var=no" |
109 |
+fi |
110 |
+ |
111 |
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ |
112 |
+ conftest$ac_exeext conftest.$ac_ext |
113 |
+fi |
114 |
+ac_res=`eval echo '${'$as_ac_var'}'` |
115 |
+ { echo "$as_me:$LINENO: result: $ac_res" >&5 |
116 |
+echo "${ECHO_T}$ac_res" >&6; } |
117 |
+if test `eval echo '${'$as_ac_var'}'` = yes; then |
118 |
+ cat >>confdefs.h <<_ACEOF |
119 |
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 |
120 |
+_ACEOF |
121 |
+ |
122 |
+fi |
123 |
+done |
124 |
+ |
125 |
+ |
126 |
+for ac_header in sys/mman.h |
127 |
+do |
128 |
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` |
129 |
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then |
130 |
+ { echo "$as_me:$LINENO: checking for $ac_header" >&5 |
131 |
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } |
132 |
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then |
133 |
+ echo $ECHO_N "(cached) $ECHO_C" >&6 |
134 |
+fi |
135 |
+ac_res=`eval echo '${'$as_ac_Header'}'` |
136 |
+ { echo "$as_me:$LINENO: result: $ac_res" >&5 |
137 |
+echo "${ECHO_T}$ac_res" >&6; } |
138 |
+else |
139 |
+ # Is the header compilable? |
140 |
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 |
141 |
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } |
142 |
+cat >conftest.$ac_ext <<_ACEOF |
143 |
+/* confdefs.h. */ |
144 |
+_ACEOF |
145 |
+cat confdefs.h >>conftest.$ac_ext |
146 |
+cat >>conftest.$ac_ext <<_ACEOF |
147 |
+/* end confdefs.h. */ |
148 |
+$ac_includes_default |
149 |
+#include <$ac_header> |
150 |
+_ACEOF |
151 |
+rm -f conftest.$ac_objext |
152 |
+if { (ac_try="$ac_compile" |
153 |
+case "(($ac_try" in |
154 |
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; |
155 |
+ *) ac_try_echo=$ac_try;; |
156 |
+esac |
157 |
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 |
158 |
+ (eval "$ac_compile") 2>conftest.er1 |
159 |
+ ac_status=$? |
160 |
+ grep -v '^ *+' conftest.er1 >conftest.err |
161 |
+ rm -f conftest.er1 |
162 |
+ cat conftest.err >&5 |
163 |
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
164 |
+ (exit $ac_status); } && { |
165 |
+ test -z "$ac_c_werror_flag" || |
166 |
+ test ! -s conftest.err |
167 |
+ } && test -s conftest.$ac_objext; then |
168 |
+ ac_header_compiler=yes |
169 |
+else |
170 |
+ echo "$as_me: failed program was:" >&5 |
171 |
+sed 's/^/| /' conftest.$ac_ext >&5 |
172 |
+ |
173 |
+ ac_header_compiler=no |
174 |
+fi |
175 |
+ |
176 |
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext |
177 |
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 |
178 |
+echo "${ECHO_T}$ac_header_compiler" >&6; } |
179 |
+ |
180 |
+# Is the header present? |
181 |
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 |
182 |
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } |
183 |
+cat >conftest.$ac_ext <<_ACEOF |
184 |
+/* confdefs.h. */ |
185 |
+_ACEOF |
186 |
+cat confdefs.h >>conftest.$ac_ext |
187 |
+cat >>conftest.$ac_ext <<_ACEOF |
188 |
+/* end confdefs.h. */ |
189 |
+#include <$ac_header> |
190 |
+_ACEOF |
191 |
+if { (ac_try="$ac_cpp conftest.$ac_ext" |
192 |
+case "(($ac_try" in |
193 |
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; |
194 |
+ *) ac_try_echo=$ac_try;; |
195 |
+esac |
196 |
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 |
197 |
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 |
198 |
+ ac_status=$? |
199 |
+ grep -v '^ *+' conftest.er1 >conftest.err |
200 |
+ rm -f conftest.er1 |
201 |
+ cat conftest.err >&5 |
202 |
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 |
203 |
+ (exit $ac_status); } >/dev/null && { |
204 |
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || |
205 |
+ test ! -s conftest.err |
206 |
+ }; then |
207 |
+ ac_header_preproc=yes |
208 |
+else |
209 |
+ echo "$as_me: failed program was:" >&5 |
210 |
+sed 's/^/| /' conftest.$ac_ext >&5 |
211 |
+ |
212 |
+ ac_header_preproc=no |
213 |
+fi |
214 |
+ |
215 |
+rm -f conftest.err conftest.$ac_ext |
216 |
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 |
217 |
+echo "${ECHO_T}$ac_header_preproc" >&6; } |
218 |
+ |
219 |
+# So? What about this header? |
220 |
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in |
221 |
+ yes:no: ) |
222 |
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 |
223 |
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} |
224 |
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 |
225 |
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} |
226 |
+ ac_header_preproc=yes |
227 |
+ ;; |
228 |
+ no:yes:* ) |
229 |
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 |
230 |
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} |
231 |
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 |
232 |
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} |
233 |
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 |
234 |
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} |
235 |
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 |
236 |
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} |
237 |
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 |
238 |
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} |
239 |
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 |
240 |
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} |
241 |
+ |
242 |
+ ;; |
243 |
+esac |
244 |
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5 |
245 |
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } |
246 |
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then |
247 |
+ echo $ECHO_N "(cached) $ECHO_C" >&6 |
248 |
+else |
249 |
+ eval "$as_ac_Header=\$ac_header_preproc" |
250 |
+fi |
251 |
+ac_res=`eval echo '${'$as_ac_Header'}'` |
252 |
+ { echo "$as_me:$LINENO: result: $ac_res" >&5 |
253 |
+echo "${ECHO_T}$ac_res" >&6; } |
254 |
+ |
255 |
+fi |
256 |
+if test `eval echo '${'$as_ac_Header'}'` = yes; then |
257 |
+ cat >>confdefs.h <<_ACEOF |
258 |
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 |
259 |
+_ACEOF |
260 |
+ |
261 |
+fi |
262 |
+ |
263 |
+done |
264 |
+ |
265 |
+ |
266 |
#-------------------------------------------------------------------- |
267 |
# These functions needed by NSTask.m |
268 |
#-------------------------------------------------------------------- |
269 |
diff -Naur gnustep-base-1.16.1.orig/configure.ac gnustep-base-1.16.1/configure.ac |
270 |
--- gnustep-base-1.16.1.orig/configure.ac 2008-06-30 14:54:14.000000000 +0200 |
271 |
+++ gnustep-base-1.16.1/configure.ac 2008-06-30 14:54:20.000000000 +0200 |
272 |
@@ -1496,11 +1496,13 @@ |
273 |
AC_CHECK_FUNCS(times) |
274 |
|
275 |
#-------------------------------------------------------------------- |
276 |
-# These functions needed by NSData.m |
277 |
+# These functions needed by NSData.m and GSFFIInvocation.m |
278 |
#-------------------------------------------------------------------- |
279 |
AC_CHECK_FUNCS(mkstemp) |
280 |
AC_CHECK_FUNCS(shmctl) |
281 |
AC_CHECK_FUNCS(mmap) |
282 |
+AC_CHECK_FUNCS(mprotect) |
283 |
+AC_CHECK_HEADERS(sys/mman.h) |
284 |
|
285 |
#-------------------------------------------------------------------- |
286 |
# These functions needed by NSTask.m |
287 |
diff -Naur gnustep-base-1.16.1.orig/Headers/Additions/GNUstepBase/config.h.in gnustep-base-1.16.1/Headers/Additions/GNUstepBase/config.h.in |
288 |
--- gnustep-base-1.16.1.orig/Headers/Additions/GNUstepBase/config.h.in 2008-06-30 14:54:15.000000000 +0200 |
289 |
+++ gnustep-base-1.16.1/Headers/Additions/GNUstepBase/config.h.in 2008-06-30 14:54:20.000000000 +0200 |
290 |
@@ -334,6 +334,9 @@ |
291 |
/* Define to 1 if you have the `mmap' function. */ |
292 |
#undef HAVE_MMAP |
293 |
|
294 |
+/* Define to 1 if you have the `mprotect' function. */ |
295 |
+#undef HAVE_MPROTECT |
296 |
+ |
297 |
/* Define to 1 if you have the `nanosleep' function. */ |
298 |
#undef HAVE_NANOSLEEP |
299 |
|
300 |
@@ -467,6 +470,9 @@ |
301 |
/* Define to 1 if you have the <sys/ioctl.h> header file. */ |
302 |
#undef HAVE_SYS_IOCTL_H |
303 |
|
304 |
+/* Define to 1 if you have the <sys/mman.h> header file. */ |
305 |
+#undef HAVE_SYS_MMAN_H |
306 |
+ |
307 |
/* Define to 1 if you have the <sys/mount.h> header file. */ |
308 |
#undef HAVE_SYS_MOUNT_H |
309 |
|
310 |
diff -Naur gnustep-base-1.16.1.orig/Source/cifframe.h gnustep-base-1.16.1/Source/cifframe.h |
311 |
--- gnustep-base-1.16.1.orig/Source/cifframe.h 2008-06-30 14:54:14.000000000 +0200 |
312 |
+++ gnustep-base-1.16.1/Source/cifframe.h 2008-06-30 14:54:20.000000000 +0200 |
313 |
@@ -52,6 +52,8 @@ |
314 |
|
315 |
extern cifframe_t *cifframe_from_info (NSArgumentInfo *info, int numargs, |
316 |
void **retval); |
317 |
+extern unsigned retval_offset_from_info (NSArgumentInfo *info, int numargs); |
318 |
+ |
319 |
extern void cifframe_set_arg(cifframe_t *cframe, int index, void *buffer, |
320 |
int size); |
321 |
extern void cifframe_get_arg(cifframe_t *cframe, int index, void *buffer, |
322 |
diff -Naur gnustep-base-1.16.1.orig/Source/cifframe.m gnustep-base-1.16.1/Source/cifframe.m |
323 |
--- gnustep-base-1.16.1.orig/Source/cifframe.m 2008-06-30 14:54:14.000000000 +0200 |
324 |
+++ gnustep-base-1.16.1/Source/cifframe.m 2008-06-30 14:54:20.000000000 +0200 |
325 |
@@ -246,6 +246,75 @@ |
326 |
return cframe; |
327 |
} |
328 |
|
329 |
+/* NB. this must match the code in cifframe_from_info() so that it |
330 |
+ * returns the offset for the returne value in the cframe. |
331 |
+ */ |
332 |
+unsigned |
333 |
+retval_offset_from_info (NSArgumentInfo *info, int numargs) |
334 |
+{ |
335 |
+ unsigned size = sizeof(cifframe_t); |
336 |
+ unsigned align = __alignof(double); |
337 |
+ unsigned type_offset = 0; |
338 |
+ unsigned offset = 0; |
339 |
+ int i; |
340 |
+ ffi_type *arg_types[numargs]; |
341 |
+ ffi_type *rtype; |
342 |
+ |
343 |
+ /* FIXME: in cifframe_type, return values/arguments that are structures |
344 |
+ have custom ffi_types with are allocated separately. We should allocate |
345 |
+ them in our cifframe so we don't leak memory. Or maybe we could |
346 |
+ cache structure types? */ |
347 |
+ rtype = cifframe_type(info[0].type, NULL); |
348 |
+ if (rtype == 0 || (rtype->size == 0 && rtype->elements == NULL)) |
349 |
+ { |
350 |
+ return 0; |
351 |
+ } |
352 |
+ |
353 |
+ for (i = 0; i < numargs; i++) |
354 |
+ { |
355 |
+ arg_types[i] = cifframe_type(info[i+1].type, NULL); |
356 |
+ } |
357 |
+ |
358 |
+ if (numargs > 0) |
359 |
+ { |
360 |
+ if (size % align != 0) |
361 |
+ { |
362 |
+ size += align - (size % align); |
363 |
+ } |
364 |
+ type_offset = size; |
365 |
+ /* Make room to copy the arg_types */ |
366 |
+ size += sizeof(ffi_type *) * numargs; |
367 |
+ if (size % align != 0) |
368 |
+ { |
369 |
+ size += align - (size % align); |
370 |
+ } |
371 |
+ offset = size; |
372 |
+ size += numargs * sizeof(void*); |
373 |
+ if (size % align != 0) |
374 |
+ { |
375 |
+ size += (align - (size % align)); |
376 |
+ } |
377 |
+ for (i = 0; i < numargs; i++) |
378 |
+ { |
379 |
+ if (arg_types[i]->elements) |
380 |
+ size += cifframe_guess_struct_size(arg_types[i]); |
381 |
+ else |
382 |
+ size += arg_types[i]->size; |
383 |
+ |
384 |
+ if (size % align != 0) |
385 |
+ { |
386 |
+ size += (align - size % align); |
387 |
+ } |
388 |
+ } |
389 |
+ } |
390 |
+ |
391 |
+ if (size % align != 0) |
392 |
+ { |
393 |
+ size += (align - size % align); |
394 |
+ } |
395 |
+ return size; |
396 |
+} |
397 |
+ |
398 |
void |
399 |
cifframe_set_arg(cifframe_t *cframe, int index, void *buffer, int size) |
400 |
{ |
401 |
diff -Naur gnustep-base-1.16.1.orig/Source/GSFFIInvocation.m gnustep-base-1.16.1/Source/GSFFIInvocation.m |
402 |
--- gnustep-base-1.16.1.orig/Source/GSFFIInvocation.m 2008-06-30 14:54:14.000000000 +0200 |
403 |
+++ gnustep-base-1.16.1/Source/GSFFIInvocation.m 2008-06-30 14:54:20.000000000 +0200 |
404 |
@@ -31,6 +31,7 @@ |
405 |
#import <objc/objc-api.h> |
406 |
#import "cifframe.h" |
407 |
#import "mframe.h" |
408 |
+#import "GSPrivate.h" |
409 |
|
410 |
#ifndef INLINE |
411 |
#define INLINE inline |
412 |
@@ -146,6 +147,7 @@ |
413 |
cifframe_t *cframe; |
414 |
ffi_closure *cclosure; |
415 |
NSMethodSignature *sig; |
416 |
+ GSCodeBuffer *memory; |
417 |
|
418 |
sig = [receiver methodSignatureForSelector: sel]; |
419 |
|
420 |
@@ -185,7 +187,9 @@ |
421 |
worry about freeing it */ |
422 |
cframe = cifframe_from_info([sig methodInfo], [sig numberOfArguments], NULL); |
423 |
/* Autorelease the closure through GSAutoreleasedBuffer */ |
424 |
- cclosure = (ffi_closure *)GSAutoreleasedBuffer(sizeof(ffi_closure)); |
425 |
+ |
426 |
+ memory = [GSCodeBuffer memoryWithSize: sizeof(ffi_closure)]; |
427 |
+ cclosure = [memory buffer]; |
428 |
if (cframe == NULL || cclosure == NULL) |
429 |
{ |
430 |
[NSException raise: NSMallocException format: @"Allocating closure"]; |
431 |
@@ -195,6 +199,7 @@ |
432 |
{ |
433 |
[NSException raise: NSGenericException format: @"Preping closure"]; |
434 |
} |
435 |
+ [memory protect]; |
436 |
|
437 |
return (IMP)cclosure; |
438 |
} |
439 |
@@ -248,23 +253,28 @@ |
440 |
frame: (cifframe_t *)frame |
441 |
signature: (NSMethodSignature*)aSignature |
442 |
{ |
443 |
+ int i; |
444 |
+ |
445 |
_sig = RETAIN(aSignature); |
446 |
_numArgs = [aSignature numberOfArguments]; |
447 |
_info = [aSignature methodInfo]; |
448 |
_cframe = frame; |
449 |
((cifframe_t *)_cframe)->cif = *cif; |
450 |
|
451 |
+ /* Copy the arguments into our frame so that they are preserved |
452 |
+ * in the NSInvocation if the stack is changed before the |
453 |
+ * invocation is used. |
454 |
+ */ |
455 |
#if MFRAME_STRUCT_BYREF |
456 |
-{ |
457 |
- int i; |
458 |
- /* Fix up some of the values. Do this on all processors that pass |
459 |
- structs by reference. Is there an automatic way to determine this? */ |
460 |
for (i = 0; i < ((cifframe_t *)_cframe)->nargs; i++) |
461 |
{ |
462 |
const char *t = _info[i+1].type; |
463 |
|
464 |
if (*t == _C_STRUCT_B || *t == _C_UNION_B || *t == _C_ARY_B) |
465 |
{ |
466 |
+ /* Fix up some of the values. Do this on all processors that pass |
467 |
+ structs by reference. |
468 |
+ Is there an automatic way to determine this? */ |
469 |
memcpy(((cifframe_t *)_cframe)->values[i], *(void **)vals[i], |
470 |
((cifframe_t *)_cframe)->arg_types[i]->size); |
471 |
} |
472 |
@@ -274,14 +284,22 @@ |
473 |
((cifframe_t *)_cframe)->arg_types[i]->size); |
474 |
} |
475 |
} |
476 |
-} |
477 |
#else |
478 |
- ((cifframe_t *)_cframe)->values = vals; |
479 |
+ for (i = 0; i < ((cifframe_t *)_cframe)->nargs; i++) |
480 |
+ { |
481 |
+ memcpy(((cifframe_t *)_cframe)->values[i], vals[i], |
482 |
+ ((cifframe_t *)_cframe)->arg_types[i]->size); |
483 |
+ } |
484 |
#endif |
485 |
_retval = retp; |
486 |
return self; |
487 |
} |
488 |
|
489 |
+- (void) _storeRetval |
490 |
+{ |
491 |
+ _retval = _cframe + retval_offset_from_info (_info, _numArgs); |
492 |
+} |
493 |
+ |
494 |
/* |
495 |
* This is implemented as a function so it can be used by other |
496 |
* routines (like the DO forwarding) |
497 |
diff -Naur gnustep-base-1.16.1.orig/Source/GSPrivate.h gnustep-base-1.16.1/Source/GSPrivate.h |
498 |
--- gnustep-base-1.16.1.orig/Source/GSPrivate.h 2008-06-30 14:54:14.000000000 +0200 |
499 |
+++ gnustep-base-1.16.1/Source/GSPrivate.h 2008-06-30 14:54:20.000000000 +0200 |
500 |
@@ -498,5 +498,19 @@ |
501 |
GSPrivateUnloadModule(FILE *errorStream, |
502 |
void (*unloadCallback)(Class, struct objc_category *)) GS_ATTRIB_PRIVATE; |
503 |
|
504 |
+ |
505 |
+/* Memory to use to put executabel code in. |
506 |
+ */ |
507 |
+@interface GSCodeBuffer : NSObject |
508 |
+{ |
509 |
+ unsigned size; |
510 |
+ void *buffer; |
511 |
+} |
512 |
++ (GSCodeBuffer*) memoryWithSize: (unsigned)_size; |
513 |
+- (void*) buffer; |
514 |
+- (id) initWithSize: (unsigned)_size; |
515 |
+- (void) protect; |
516 |
+@end |
517 |
+ |
518 |
#endif /* _GSPrivate_h_ */ |
519 |
|
520 |
diff -Naur gnustep-base-1.16.1.orig/Source/NSInvocation.m gnustep-base-1.16.1/Source/NSInvocation.m |
521 |
--- gnustep-base-1.16.1.orig/Source/NSInvocation.m 2008-06-30 14:54:14.000000000 +0200 |
522 |
+++ gnustep-base-1.16.1/Source/NSInvocation.m 2008-06-30 14:54:20.000000000 +0200 |
523 |
@@ -31,6 +31,7 @@ |
524 |
#include "Foundation/NSInvocation.h" |
525 |
#include "GSInvocation.h" |
526 |
#include "config.h" |
527 |
+#include "GSPrivate.h" |
528 |
#include <mframe.h> |
529 |
#if defined(USE_LIBFFI) |
530 |
#include "cifframe.h" |
531 |
@@ -38,6 +39,105 @@ |
532 |
#include "callframe.h" |
533 |
#endif |
534 |
|
535 |
+#if defined(HAVE_SYS_MMAN_H) |
536 |
+#include <sys/mman.h> |
537 |
+#endif |
538 |
+ |
539 |
+@interface NSInvocation (Private) |
540 |
+/* Tell the invocation to store return values locally rather than writing |
541 |
+ * themto the stack location specified when the invocation was produced |
542 |
+ */ |
543 |
+- (void) _storeRetval; |
544 |
+@end |
545 |
+ |
546 |
+@implementation GSCodeBuffer |
547 |
+ |
548 |
++ (GSCodeBuffer*) memoryWithSize: (unsigned)_size |
549 |
+{ |
550 |
+ return [[[self alloc] initWithSize: _size] autorelease]; |
551 |
+} |
552 |
+ |
553 |
+- (void*) buffer |
554 |
+{ |
555 |
+ return buffer; |
556 |
+} |
557 |
+ |
558 |
+- (void) dealloc |
559 |
+{ |
560 |
+ if (size > 0) |
561 |
+ { |
562 |
+#if defined(HAVE_MMAP) |
563 |
+ munmap(buffer, size); |
564 |
+#elif defined(__MINGW32__) |
565 |
+ VirtualFree(buffer, 0, MEM_RELEASE); |
566 |
+#else |
567 |
+ free(buffer); |
568 |
+#endif |
569 |
+ } |
570 |
+ [super dealloc]; |
571 |
+} |
572 |
+ |
573 |
+- (id) initWithSize: (unsigned)_size |
574 |
+{ |
575 |
+#if defined(HAVE_MMAP) |
576 |
+#ifndef MAP_ANONYMOUS |
577 |
+#define MAP_ANONYMOUS MAP_ANON |
578 |
+#endif |
579 |
+#if defined(HAVE_MPROTECT) |
580 |
+ /* We have mprotect, so we create memory as writable and change it to |
581 |
+ * executable later (writable and executable may not be possible at |
582 |
+ * the same time). |
583 |
+ */ |
584 |
+ buffer = mmap (NULL, _size, PROT_READ|PROT_WRITE, |
585 |
+ MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); |
586 |
+#else |
587 |
+ /* We do not have mprotect, so we have to try to create writable and |
588 |
+ * executable memory. |
589 |
+ */ |
590 |
+ buffer = mmap (NULL, _size, PROT_READ|PROT_WRITE|PROT_EXEC, |
591 |
+ MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); |
592 |
+#endif /* HAVE_MPROTECT */ |
593 |
+ if (buffer == (void*)-1) buffer = (void*)0; |
594 |
+#elif defined(__MINGW32__) |
595 |
+ buffer = VirtualAlloc(NULL, _size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); |
596 |
+#else |
597 |
+ buffer = malloc(_size); |
598 |
+#endif /* HAVE_MMAP */ |
599 |
+ |
600 |
+ if (buffer == (void*)0) |
601 |
+ { |
602 |
+ NSLog(@"Failed to map %u bytes for execute: %@", _size, [NSError _last]); |
603 |
+ buffer = 0; |
604 |
+ [self dealloc]; |
605 |
+ self = nil; |
606 |
+ } |
607 |
+ else |
608 |
+ { |
609 |
+ size = _size; |
610 |
+ } |
611 |
+ return self; |
612 |
+} |
613 |
+ |
614 |
+/* Ensure that the protection on the buffer is such that it will execute |
615 |
+ * on any architecture. |
616 |
+ */ |
617 |
+- (void) protect |
618 |
+{ |
619 |
+#if defined(__MINGW32__) |
620 |
+ DWORD old; |
621 |
+ if (VirtualProtect(buffer, size, PAGE_EXECUTE, &old) == 0) |
622 |
+ { |
623 |
+ NSLog(@"Failed to protect memory as executable: %@", [NSError _last]); |
624 |
+ } |
625 |
+#elif defined(HAVE_MPROTECT) |
626 |
+ if (mprotect(buffer, size, PROT_READ|PROT_EXEC) == -1) |
627 |
+ { |
628 |
+ NSLog(@"Failed to protect memory as executable: %@", [NSError _last]); |
629 |
+ } |
630 |
+#endif |
631 |
+} |
632 |
+@end |
633 |
+ |
634 |
static Class NSInvocation_abstract_class; |
635 |
static Class NSInvocation_concrete_class; |
636 |
|
637 |
@@ -1054,6 +1154,7 @@ |
638 |
- (void) forwardInvocation: (NSInvocation*)anInvocation |
639 |
{ |
640 |
invocation = anInvocation; |
641 |
+ [invocation _storeRetval]; |
642 |
} |
643 |
- (NSMethodSignature*) methodSignatureForSelector: (SEL)aSelector |
644 |
{ |
645 |
@@ -1068,3 +1169,10 @@ |
646 |
return invocation; |
647 |
} |
648 |
@end |
649 |
+ |
650 |
+@implementation NSInvocation (Private) |
651 |
+- (void) _storeRetval |
652 |
+{ |
653 |
+ return; // subclass should implemente where necessary |
654 |
+} |
655 |
+@end |
656 |
|
657 |
|
658 |
|
659 |
-- |
660 |
gentoo-commits@l.g.o mailing list |