From: SourceForge.net <no...@so...> - 2008-01-11 07:52:22
|
Bugs item #1535284, was opened at 2006-08-06 07:57 Message generated for change (Comment added) made by hcab You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=101355&aid=1535284&group_id=1355 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: ffcall Group: build problems Status: Open Resolution: None Priority: 5 Private: No Submitted By: Edward Carrel (azanar) Assigned to: Bruno Haible (haible) Summary: trampoline_r test1 fails on i386 running Mac OS Initial Comment: trampoline_r fails to configure on a MacBook running Mac OS 10.4.7. Get the following output from configure: cd trampoline_r; make all make[1]: Nothing to be done for `all'. /bin/sh ./libtool --mode=link gcc -o libcallback.la -rpath /usr/local/ lib vacall_r/vacall.lo vacall_r/misc.lo vacall_r/structcpy.lo trampoline_r/ *.lo rm -fr .libs/libcallback.a .libs/libcallback.la .libs/libcallback.lai ar cru .libs/libcallback.a vacall_r/vacall-i386.o vacall_r/misc.o vacall_r/structcpy.o trampoline_r/trampoline.o ranlib .libs/libcallback.a creating libcallback.la (cd .libs && rm -f libcallback.la && ln -s ../libcallback.la libcallback.la) ./minitests > minitests.out LC_ALL=C uniq -u < minitests.out > minitests.output.i386-apple- darwin8.7.1 test '!' -s minitests.output.i386-apple-darwin8.7.1 cd vacall_r; make all make[1]: Nothing to be done for `all'. cd trampoline_r; make all make[1]: Nothing to be done for `all'. cd vacall_r; make check make[1]: Nothing to be done for `check'. cd trampoline_r; make check gcc -g -O2 -I. -I../../../ffcall/callback/trampoline_r -c ../../../ffcall/ callback/trampoline_r/test1.c /bin/sh ./libtool --mode=link gcc -g -O2 -x none test1.o trampoline.lo -o test1 gcc -g -O2 -x none test1.o trampoline.o -o test1 gcc -g -O2 -I. -I../../../ffcall/callback/trampoline_r -c ../../../ffcall/ callback/trampoline_r/test2.c /bin/sh ./libtool --mode=link gcc -g -O2 -x none test2.o trampoline.lo -o test2 gcc -g -O2 -x none test2.o trampoline.o -o test2 ./test1 make[1]: *** [check] Illegal instruction (core dumped) The core provides nothing really useful: $ gdb ~/clisp-2.39/src/callback/trampoline_r/test1 /cores/core. 18128 GNU gdb 6.3.50-20050815 (Apple version gdb-477) (Sun Apr 30 20:01:44 GMT 2006) Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-apple-darwin"...Reading symbols for shared libraries .. done Core was generated by `./test1'. #0 0x8fe13914 in __dyld_stub_binding_helper_interface () (gdb) bt #0 0x8fe13914 in __dyld_stub_binding_helper_interface () #1 0x00000000 in ?? () (gdb) I realize this isn't a lot to go on. Let me know if I can provide anything else that might make diagnosing this any easier. ---------------------------------------------------------------------- Comment By: Christoph Mayer (hcab) Date: 2008-01-11 08:52 Message: Logged In: YES user_id=1977958 Originator: NO The following modifications fix the minitests in ffcall/callback on MAC OS on i386. With this patch clisp compiles on a Macbook Pro (intel core duo) providing :ffi and passing all ffi tests. It seems that the arguments have an offset by 12 bytes after the modification of trampoline_r where 12 extra bytes are pushed on the stack, whereas for the modification in vacall-i386-macro.S I do not know why the last "ret $4" instruction has to be replaced by "ret". ======================================= diff clisp-2.40/ffcall/callback/vacall_r/vacall_r.h.in clisp-2.40-mod/ffcall/callback/vacall_r/vacall_r.h.in 408a409,415 > #if defined(__i386__) && defined (__APPLE__) > #define __va_start(LIST,RETTYPE) \ > ((LIST)->flags = __VA_START_FLAGS, \ > (LIST)->rtype = (RETTYPE), \ > (LIST)->aptr += 12 \ > ) > #else 412a420 > #endif ========================================= diff clisp-2.40/ffcall/callback/vacall_r/vacall-i386-macro.S clisp-2.40-mod/ffcall/callback/vacall_r/vacall-i386-macro.S 127a128 > #ifndef __APPLE__ 129a131 > #endif ---------------------------------------------------------------------- Comment By: Raph Levien (raph) Date: 2007-02-09 09:41 Message: Logged In: YES user_id=379 Originator: NO Ok, I can't find the attach button, so I'll just post it inline. However, this patch still doesn't bring joy to the entire compile - it fixes test1 and test2, but not the minitest, which exercises the vacall mechanism. I think there are nontrivial changes needed to that function as well. *** dist-trampoline.c Thu Feb 8 22:13:51 2007 --- trampoline.c Fri Feb 9 00:38:51 2007 *************** *** 235,239 **** --- 235,243 ---- #ifdef __i386__ #ifdef __APPLE__ + /* Must align esp to 16-byte boundaries, so use longer sequence */ + #define TRAMP_LENGTH 32 + #else #define TRAMP_LENGTH 16 + #endif #define TRAMP_ALIGN 16 /* 4 for a i386, 16 for a i486 */ #endif *************** *** 408,411 **** --- 412,449 ---- */ #ifdef __i386__ + #if TRAMP_LENGTH == 32 + /* function: + * popl %ecx 59 + * mov (%esp), %edx 8b 14 24 + * and $0xfffffff0, %esp 83 e4 f0 + * sub $8, %esp 83 ec 08 + * pushl %edx 52 + * pushl $<data> 68 <data> + * pushl %ecx 51 + * jmp <address> E9 <address>-<here> + * here: + * nop 90 + * nop 90 + * nop 90 + * nop 90 + */ + *(long *) (function + 0) = 0x24148b59; + *(long *) (function + 4) = 0x83f0e483; + *(long *) (function + 8) = 0x685208ec; + *(long *) (function + 12) = (long) data; + *(short *) (function + 16) = 0xE951; + *(long *) (function + 18) = (long) address - (long) (function + 22); + *(short *) (function + 22) = 0x90909090; /* nop nop nop nop, for alignment */ + *(long *) (function + 24) = 0x90909090; /* nop nop nop nop, for alignment */ + *(long *) (function + 28) = 0x90909090; /* nop nop nop nop, for alignment */ + #define is_tramp(function) \ + *(long *) (function + 0) == 0x24148b59 && \ + *(long *) (function + 4) == 0x83f0e483 && \ + *(unsigned short *) (function + 16) == 0xE951 + #define tramp_address(function) \ + *(long *) (function + 18) + (long) (function + 22) + #define tramp_data(function) \ + *(long *) (function + 12) + #else /* function: * popl %ecx 59 *************** *** 442,445 **** --- 480,484 ---- *(long *) (function + 2) #endif + #endif #ifdef __m68k__ #ifdef __NetBSD__ ---------------------------------------------------------------------- Comment By: Raph Levien (raph) Date: 2007-02-09 07:28 Message: Logged In: YES user_id=379 Originator: NO It's failing because Apple made a tweak to the ABI, always expecting the stack pointer to be 16-byte aligned (they use some SSE2 instructions to manipulate the stack inside the dyld helper functions). I've made a patch which pads out the stack with 3 extra 4-byte pushes when adding the env. Hopefully I'll be able to attach it to this bug, if I can figure out the attachment mechanism. ---------------------------------------------------------------------- Comment By: Jorge Acereda Macijacereda) Date: 2007-01-14 23:13 Message: Logged In: YES user_id=346809 Originator: NO Some more hints: $esp gets messed after returning from the trampoline, and the offending instruction is inside printf. (gdb) p/x $esp # After alloc_trampoline_r() $4 = 0xbffff5e0 (gdb) n (gdb) p/x $esp # After calling trampoline $5 = 0xbffff5dc # calling printf will segfault now ---------------------------------------------------------------------- Comment By: Jorge Acereda Macijacereda) Date: 2007-01-14 23:01 Message: Logged In: YES user_id=346809 Originator: NO The problem here is an unaligned vector store: (gdb) disass Dump of assembler code for function __dyld_stub_binding_helper_interface: 0x8fe12f72 <__dyld_stub_binding_helper_interface+0>: push %ebp 0x8fe12f73 <__dyld_stub_binding_helper_interface+1>: mov %esp,%ebp 0x8fe12f75 <__dyld_stub_binding_helper_interface+3>: sub $0x60,%esp 0x8fe12f78 <__dyld_stub_binding_helper_interface+6>: mov %eax,8(%esp) 0x8fe12f7c <__dyld_stub_binding_helper_interface+10>: mov %ecx,12(%esp) 0x8fe12f80 <__dyld_stub_binding_helper_interface+14>: mov %edx,16(%esp) 0x8fe12f84 <__dyld_stub_binding_helper_interface+18>: movdqa %xmm0,32(%esp) 0x8fe12f8a <__dyld_stub_binding_helper_interface+24>: movdqa %xmm1,48(%esp) 0x8fe12f90 <__dyld_stub_binding_helper_interface+30>: movdqa %xmm2,64(%esp) 0x8fe12f96 <__dyld_stub_binding_helper_interface+36>: movdqa %xmm3,80(%esp) 0x8fe12f9c <__dyld_stub_binding_helper_interface+42>: mov 4(%ebp),%eax 0x8fe12f9f <__dyld_stub_binding_helper_interface+45>: mov %eax,0(%esp) 0x8fe12fa3 <__dyld_stub_binding_helper_interface+49>: mov 8(%ebp),%eax 0x8fe12fa6 <__dyld_stub_binding_helper_interface+52>: mov %eax,4(%esp) 0x8fe12faa <__dyld_stub_binding_helper_interface+56>: call 0x8fe05276 <__dyld__ZN4dyld14bindLazySymbolEPK11mach_headerPm> 0x8fe12faf <__dyld_stub_binding_helper_interface+61>: mov %eax,8(%ebp) 0x8fe12fb2 <__dyld_stub_binding_helper_interface+64>: movdqa 32(%esp),%xmm0 0x8fe12fb8 <__dyld_stub_binding_helper_interface+70>: movdqa 48(%esp),%xmm1 0x8fe12fbe <__dyld_stub_binding_helper_interface+76>: movdqa 64(%esp),%xmm2 0x8fe12fc4 <__dyld_stub_binding_helper_interface+82>: movdqa 80(%esp),%xmm3 0x8fe12fca <__dyld_stub_binding_helper_interface+88>: mov 8(%esp),%eax 0x8fe12fce <__dyld_stub_binding_helper_interface+92>: mov 12(%esp),%ecx 0x8fe12fd2 <__dyld_stub_binding_helper_interface+96>: mov 16(%esp),%edx 0x8fe12fd6 <__dyld_stub_binding_helper_interface+100>: add $0x60,%esp 0x8fe12fd9 <__dyld_stub_binding_helper_interface+103>: pop %ebp 0x8fe12fda <__dyld_stub_binding_helper_interface+104>: add $0x4,%esp 0x8fe12fdd <__dyld_stub_binding_helper_interface+107>: ret 0x8fe12fde <__dyld_stub_binding_helper_interface+108>: add %al,(%eax) End of assembler dump. (gdb) p/x $pc $1 = 0x8fe12f84 (gdb) p/x $esp $2 = 0xbffff56c (gdb) The OS X ABI requires the stack to be aligned to 16 bytes. ---------------------------------------------------------------------- Comment By: Edward Carrel (azanar) Date: 2006-08-06 20:44 Message: Logged In: YES user_id=635878 I stepped through the execution of test1 in GDB and found that the illegal instruction is occuring in a call to free(3). I've included a trace of the program execution following a few variables of interest below. Breakpoint 2 at 0x1e08: file ./test1.c, line 96. Starting program: *snip*/clisp-2.39/ffcall/callback/trampoline_r/test1 Breakpoint 2, main () at ./test1.c:96 96 function cf = alloc_trampoline_r((function)&f, (void*)MAGIC1, (void*) MAGIC2); (gdb) s alloc_trampoline_r (address=0x1de6 <f>, data0=0x9db9af42, data1=0x614a13c9) at ./trampoline.c:394 394 { char* room = (char*) malloc(sizeof(void*) + TRAMP_TOTAL_LENGTH + TRAMP_ALIGN-1); (gdb) s 395 if (!room) (gdb) s 397 function = (char*)(((long)room + sizeof(void*) + TRAMP_ALIGN-1) & -TRAMP_ALIGN); (gdb) s 398 ((char**)function)[-1] = room; /* backpointer for free_trampoline() */ (gdb) s 403 data = function + TRAMP_LENGTH; (gdb) print function $4 = 0x300100 "" (gdb) s 420 *(short *) (function + 0) = 0x6859; (gdb) s 421 *(long *) (function + 2) = (long) data; (gdb) s 422 *(short *) (function + 6) = 0xE951; (gdb) s 423 *(long *) (function + 8) = (long) address - (long) (function + 12); (gdb) s 424 *(long *) (function +12) = 0x90909090; /* nop nop nop nop, for alignment */ (gdb) s 1061 *(long *) (data + 0*sizeof(void*)) = (long) data0; (gdb) s 1062 *(long *) (data + 1*sizeof(void*)) = (long) data1; (gdb) s 1193 } (gdb) print function $5 = 0x300100 "Yh\020\0010" (gdb) s main () at ./test1.c:98 98 if ((*cf)(MAGIC4) == MAGIC1+MAGIC2+MAGIC3+MAGIC4) (gdb) print cf $6 = (function) 0x300100 (gdb) s 102 { free_trampoline_r(cf); printf("Works, test1 passed.\n"); exit(0); } (gdb) s free_trampoline_r (function=0x300100) at ./trampoline.c:1204 1204 free(((char**)function)[-1]); (gdb) s 1206 } (gdb) s free_trampoline_r (function=0x1) at ./trampoline.c:1204 1204 free(((char**)function)[-1]); (gdb) s 0x00003033 in dyld_stub_free () (gdb) s Single stepping until exit from function dyld_stub_free, which has no line number information. 0x8fe13900 in __dyld_fast_stub_binding_helper_interface () (gdb) s Single stepping until exit from function __dyld_fast_stub_binding_helper_interface, which has no line number information. 0x8fe13902 in __dyld_stub_binding_helper_interface () (gdb) s Single stepping until exit from function __dyld_stub_binding_helper_interface, which has no line number information. Program received signal EXC_BAD_INSTRUCTION, Illegal instruction/operand. 0x8fe13914 in __dyld_stub_binding_helper_interface () (gdb) So, freeing the space allocated eariler and coerced into being a function pointer is causing an illegal instruction to be executed. Odd. I also tested out putting a printout of where the pointer was just before it's freed, and got the same execution path until the print: 1204 printf("%p\n", (char**)function); (gdb) s Program received signal EXC_BAD_INSTRUCTION, Illegal instruction/operand. 0x8fe13914 in __dyld_stub_binding_helper_interface () (gdb) s Single stepping until exit from function __dyld_stub_binding_helper_interface, It looks like the dynamic linker in OS X is getting confused about what it's being passed. Thoughts? Other tests to run to try to pin this down? ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=101355&aid=1535284&group_id=1355 |