This patch fixes the libffi.call/err_bad_abi.c expected test failures, The bug seems to be that various that bad ABI numbers, as used by err_bad_abi.c, generate assertion failures instead of returning FFI_BAD_ABI. If the test is correct then this if the wrong thing. The only unaffected architecture would appear to be m32r.
This patch replaces the assertion failures with if statements that return FFI_BAD_ABI. I think all architecture are covered but do not have access to anything except x86_64 hardware. --- libffi/src/mips/ffi.c.dist 2009-08-09 16:16:19.016509533 +0100 +++ libffi/src/mips/ffi.c 2009-08-09 16:17:03.912006032 +0100 @@ -573,6 +573,12 @@ void * fn; char *clear_location = (char *) codeloc; + /* Reject if bad ABI */ + if (cif == NULL) + return FFI_BAD_ABI; + if (cif->abi < FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI) + return FFI_BAD_ABI; + #if defined(FFI_MIPS_O32) FFI_ASSERT(cif->abi == FFI_O32 || cif->abi == FFI_O32_SOFT_FLOAT); fn = ffi_closure_O32; --- libffi/src/sparc/ffi.c.dist 2009-08-09 16:16:19.476512080 +0100 +++ libffi/src/sparc/ffi.c 2009-08-09 16:27:44.904006388 +0100 @@ -447,7 +447,8 @@ #ifdef SPARC64 /* Trampoline address is equal to the closure address. We take advantage of that to reduce the trampoline size by 8 bytes. */ - FFI_ASSERT (cif->abi == FFI_V9); + if (cif == NULL || c->abi != FFI_V9) + return FFI_BAD_ABI; fn = (unsigned long) ffi_closure_v9; tramp[0] = 0x83414000; /* rd %pc, %g1 */ tramp[1] = 0xca586010; /* ldx [%g1+16], %g5 */ @@ -456,7 +457,8 @@ *((unsigned long *) &tramp[4]) = fn; #else unsigned long ctx = (unsigned long) codeloc; - FFI_ASSERT (cif->abi == FFI_V8); + if (cif == NULL || c->abi != FFI_V9) + return FFI_BAD_ABI; fn = (unsigned long) ffi_closure_v8; tramp[0] = 0x03000000 | fn >> 10; /* sethi %hi(fn), %g1 */ tramp[1] = 0x05000000 | ctx >> 10; /* sethi %hi(ctx), %g2 */ --- libffi/src/sh/ffi.c.dist 2009-08-09 16:16:19.664507713 +0100 +++ libffi/src/sh/ffi.c 2009-08-09 16:23:07.992004879 +0100 @@ -463,7 +463,9 @@ unsigned int *tramp; unsigned int insn; - FFI_ASSERT (cif->abi == FFI_GCC_SYSV); + /* Reject if bad ABI */ + if (cif == NULL || cif->abi != FFI_GCC_SYSV) + return FFI_BAD_ABI; tramp = (unsigned int *) &closure->tramp[0]; /* Set T bit if the function returns a struct pointed with R2. */ --- libffi/src/pa/ffi.c.dist 2009-08-09 16:16:18.848526920 +0100 +++ libffi/src/pa/ffi.c 2009-08-09 16:17:03.912006032 +0100 @@ -626,7 +626,9 @@ UINT32 *tmp; #endif - FFI_ASSERT (cif->abi == FFI_PA32); + /* Reject if bad ABI */ + if (cif == NULL || cif->abi != FPI_PA32) + return FFI_BAD_ABI; /* Make a small trampoline that will branch to our handler function. Use PC-relative addressing. */ --- libffi/src/s390/ffi.c.dist 2009-08-09 16:16:18.784508669 +0100 +++ libffi/src/s390/ffi.c 2009-08-09 16:21:26.772005463 +0100 @@ -750,7 +750,9 @@ void *user_data, void *codeloc) { - FFI_ASSERT (cif->abi == FFI_SYSV); + /* Reject if bad ABI */ + if (cif == NULL || cif->abi != FFI_SYSV) + return FFI_BAD_ABI; #ifndef __s390x__ *(short *)&closure->tramp [0] = 0x0d10; /* basr %r1,0 */ --- libffi/src/alpha/ffi.c.dist 2009-08-09 16:16:18.724509984 +0100 +++ libffi/src/alpha/ffi.c 2009-08-09 16:17:03.908010391 +0100 @@ -178,6 +178,12 @@ { unsigned int *tramp; + /* Reject if bad ABI */ + if (cif == NULL) + return FFI_BAD_ABI; + if (cif->abi < FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI) + return FFI_BAD_ABI; + tramp = (unsigned int *) &closure->tramp[0]; tramp[0] = 0x47fb0401; /* mov $27,$1 */ tramp[1] = 0xa77b0010; /* ldq $27,16($27) */ --- libffi/src/frv/ffi.c.dist 2009-08-09 16:16:18.752505382 +0100 +++ libffi/src/frv/ffi.c 2009-08-09 16:17:03.912006032 +0100 @@ -260,6 +260,12 @@ #endif int i; + /* Reject if bad ABI */ + if (cif == NULL) + return FFI_BAD_ABI; + if (cif->abi < FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI) + return FFI_BAD_ABI; + fn = (unsigned long) ffi_closure_eabi; #ifdef __FRV_FDPIC__ --- libffi/src/prep_cif.c.dist 2009-08-09 16:16:19.668507512 +0100 +++ libffi/src/prep_cif.c 2009-08-09 16:17:03.908010391 +0100 @@ -93,7 +93,8 @@ ffi_type **ptr; FFI_ASSERT(cif != NULL); - FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI)); + if (abi<FFI_FIRST_ABI || abi>=FFI_LAST_ABI) + return FFI_BAD_ABI; cif->abi = abi; cif->arg_types = atypes; --- libffi/src/powerpc/ffi.c.dist 2009-08-09 16:16:18.268505941 +0100 +++ libffi/src/powerpc/ffi.c 2009-08-09 16:17:03.916005633 +0100 @@ -948,7 +948,10 @@ #ifdef POWERPC64 void **tramp = (void **) &closure->tramp[0]; - FFI_ASSERT (cif->abi == FFI_LINUX64); + /* Reject if bad ABI */ + if (cif == NULL || cif->abi != FFI_LINUX64) + return FFI_BAD_ABI; + /* Copy function address and TOC from ffi_closure_LINUX64. */ memcpy (tramp, (char *) ffi_closure_LINUX64, 16); tramp[2] = codeloc; --- libffi/src/powerpc/ffi_darwin.c.dist 2009-08-09 16:16:18.272507501 +0100 +++ libffi/src/powerpc/ffi_darwin.c 2009-08-09 16:17:03.916005633 +0100 @@ -580,9 +580,7 @@ closure->user_data = user_data; default: - - FFI_ASSERT(0); - break; + return FFI_BAD_ABI; } return FFI_OK; } --- libffi/src/sh64/ffi.c.dist 2009-08-09 16:16:18.340005195 +0100 +++ libffi/src/sh64/ffi.c 2009-08-09 16:22:13.148004794 +0100 @@ -302,7 +302,9 @@ { unsigned int *tramp; - FFI_ASSERT (cif->abi == FFI_GCC_SYSV); + /* Reject if bad ABI */ + if (cif == NULL || cif->abi != FFI_GCC_SYSV) + return FFI_BAD_ABI; tramp = (unsigned int *) &closure->tramp[0]; /* Since ffi_closure is an aligned object, the ffi trampoline is --- libffi/src/arm/ffi.c.dist 2009-08-09 16:16:17.625740271 +0100 +++ libffi/src/arm/ffi.c 2009-08-09 16:17:03.908010391 +0100 @@ -295,7 +295,9 @@ void *user_data, void *codeloc) { - FFI_ASSERT (cif->abi == FFI_SYSV); + /* Reject if bad ABI */ + if (cif == NULL || cif->abi != FFI_SYSV) + return FFI_BAD_ABI; FFI_INIT_TRAMPOLINE (&closure->tramp[0], \ &ffi_closure_SYSV, \ --- libffi/src/m68k/ffi.c.dist 2009-08-09 16:16:18.736505821 +0100 +++ libffi/src/m68k/ffi.c 2009-08-09 16:17:03.912006032 +0100 @@ -255,7 +255,9 @@ void *user_data, void *codeloc) { - FFI_ASSERT (cif->abi == FFI_SYSV); + /* Reject if bad ABI */ + if (cif == NULL || cif->abi != FFI_SYSV) + return FFI_BAD_ABI; *(unsigned short *)closure->tramp = 0x207c; *(void **)(closure->tramp + 2) = codeloc; --- libffi/src/x86/ffi.c.dist 2009-08-09 16:16:18.700005669 +0100 +++ libffi/src/x86/ffi.c 2009-08-09 16:17:03.920005594 +0100 @@ -538,6 +538,12 @@ void *user_data, void *codeloc) { + /* Reject if bad ABI */ + if (cif == NULL) + return FFI_BAD_ABI; + if (cif->abi < FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI) + return FFI_BAD_ABI; + #ifdef X86_WIN64 #define ISFLOAT(IDX) (cif->arg_types[IDX]->type == FFI_TYPE_FLOAT || cif->arg_types[IDX]->type == FFI_TYPE_DOUBLE) #define FLAG(IDX) (cif->nargs>(IDX)&&ISFLOAT(IDX)?(1<<(IDX)):0) --- libffi/src/x86/ffi64.c.dist 2009-08-09 16:16:18.700005669 +0100 +++ libffi/src/x86/ffi64.c 2009-08-09 16:17:03.916005633 +0100 @@ -443,6 +443,12 @@ { volatile unsigned short *tramp; + /* Reject if bad ABI */ + if (cif == NULL) + return FFI_BAD_ABI; + if (cif->abi < FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI) + return FFI_BAD_ABI; + tramp = (volatile unsigned short *) &closure->tramp[0]; tramp[0] = 0xbb49; /* mov <code>, %r11 */ --- libffi/src/ia64/ffi.c.dist 2009-08-09 16:16:18.936507927 +0100 +++ libffi/src/ia64/ffi.c 2009-08-09 16:17:03.912006032 +0100 @@ -425,7 +425,9 @@ struct ffi_ia64_trampoline_struct *tramp; struct ia64_fd *fd; - FFI_ASSERT (cif->abi == FFI_UNIX); + /* Reject if bad ABI */ + if (cif == NULL || cif->abi != FFI_UNIX) + return FFI_BAD_ABI; tramp = (struct ffi_ia64_trampoline_struct *)closure->tramp; fd = (struct ia64_fd *)(void *)ffi_closure_unix; --- libffi/src/cris/ffi.c.dist 2009-08-09 16:16:18.804505313 +0100 +++ libffi/src/cris/ffi.c 2009-08-09 16:17:03.908010391 +0100 @@ -368,7 +368,10 @@ void *codeloc) { void *innerfn = ffi_prep_closure_inner; - FFI_ASSERT (cif->abi == FFI_SYSV); + /* Reject if bad ABI */ + if (cif == NULL || cif->abi != FFI_SYSV) + return FFI_BAD_ABI; + closure->cif = cif; closure->user_data = user_data; closure->fun = fun; -- Summary: Fix for libffi err_bad_abi test failure Product: gcc Version: 4.5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libffi AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: dps at simpson dot demon dot co dot uk GCC build triplet: x86_64-unknown-linux-gnu GCC host triplet: x86_64-unknown-linux-gnu GCC target triplet: x86_64-unknown-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41014