1/* Area: ffi_call, closure_call 2 Purpose: Check pointer arguments across multiple hideous stack frames. 3 Limitations: none. 4 PR: none. 5 Originator: Blake Chaffin 6/7/2007 */ 6 7/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ 8#include "ffitest.h" 9 10static long dummyVar; 11 12long dummy_func( 13 long double a1, char b1, 14 long double a2, char b2, 15 long double a3, char b3, 16 long double a4, char b4) 17{ 18 return a1 + b1 + a2 + b2 + a3 + b3 + a4 + b4; 19} 20 21void* cls_pointer_fn2(void* a1, void* a2) 22{ 23 long double trample1 = (intptr_t)a1 + (intptr_t)a2; 24 char trample2 = ((char*)&a1)[0] + ((char*)&a2)[0]; 25 long double trample3 = (intptr_t)trample1 + (intptr_t)a1; 26 char trample4 = trample2 + ((char*)&a1)[1]; 27 long double trample5 = (intptr_t)trample3 + (intptr_t)a2; 28 char trample6 = trample4 + ((char*)&a2)[1]; 29 long double trample7 = (intptr_t)trample5 + (intptr_t)trample1; 30 char trample8 = trample6 + trample2; 31 void* result; 32 33 dummyVar = dummy_func(trample1, trample2, trample3, trample4, 34 trample5, trample6, trample7, trample8); 35 36 result = (void*)((intptr_t)a1 + (intptr_t)a2); 37 38 printf("0x%08x 0x%08x: 0x%08x\n", 39 (unsigned int)(uintptr_t) a1, 40 (unsigned int)(uintptr_t) a2, 41 (unsigned int)(uintptr_t) result); 42 43 return result; 44} 45 46void* cls_pointer_fn1(void* a1, void* a2) 47{ 48 long double trample1 = (intptr_t)a1 + (intptr_t)a2; 49 char trample2 = ((char*)&a1)[0] + ((char*)&a2)[0]; 50 long double trample3 = (intptr_t)trample1 + (intptr_t)a1; 51 char trample4 = trample2 + ((char*)&a1)[1]; 52 long double trample5 = (intptr_t)trample3 + (intptr_t)a2; 53 char trample6 = trample4 + ((char*)&a2)[1]; 54 long double trample7 = (intptr_t)trample5 + (intptr_t)trample1; 55 char trample8 = trample6 + trample2; 56 void* result; 57 58 dummyVar = dummy_func(trample1, trample2, trample3, trample4, 59 trample5, trample6, trample7, trample8); 60 61 result = (void*)((intptr_t)a1 + (intptr_t)a2); 62 63 printf("0x%08x 0x%08x: 0x%08x\n", 64 (unsigned int)(intptr_t) a1, 65 (unsigned int)(intptr_t) a2, 66 (unsigned int)(intptr_t) result); 67 68 result = cls_pointer_fn2(result, a1); 69 70 return result; 71} 72 73static void 74cls_pointer_gn(ffi_cif* cif __UNUSED__, void* resp, 75 void** args, void* userdata __UNUSED__) 76{ 77 void* a1 = *(void**)(args[0]); 78 void* a2 = *(void**)(args[1]); 79 80 long double trample1 = (intptr_t)a1 + (intptr_t)a2; 81 char trample2 = ((char*)&a1)[0] + ((char*)&a2)[0]; 82 long double trample3 = (intptr_t)trample1 + (intptr_t)a1; 83 char trample4 = trample2 + ((char*)&a1)[1]; 84 long double trample5 = (intptr_t)trample3 + (intptr_t)a2; 85 char trample6 = trample4 + ((char*)&a2)[1]; 86 long double trample7 = (intptr_t)trample5 + (intptr_t)trample1; 87 char trample8 = trample6 + trample2; 88 89 dummyVar = dummy_func(trample1, trample2, trample3, trample4, 90 trample5, trample6, trample7, trample8); 91 92 *(void**)resp = cls_pointer_fn1(a1, a2); 93} 94 95int main (void) 96{ 97 ffi_cif cif; 98 void *code; 99 ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 100 void* args[3]; 101 /* ffi_type cls_pointer_type; */ 102 ffi_type* arg_types[3]; 103 104/* cls_pointer_type.size = sizeof(void*); 105 cls_pointer_type.alignment = 0; 106 cls_pointer_type.type = FFI_TYPE_POINTER; 107 cls_pointer_type.elements = NULL;*/ 108 109 void* arg1 = (void*)0x01234567; 110 void* arg2 = (void*)0x89abcdef; 111 ffi_arg res = 0; 112 113 arg_types[0] = &ffi_type_pointer; 114 arg_types[1] = &ffi_type_pointer; 115 arg_types[2] = NULL; 116 117 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_pointer, 118 arg_types) == FFI_OK); 119 120 args[0] = &arg1; 121 args[1] = &arg2; 122 args[2] = NULL; 123 124 printf("\n"); 125 ffi_call(&cif, FFI_FN(cls_pointer_fn1), &res, args); 126 127 printf("res: 0x%08x\n", (unsigned int) res); 128 /* { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" } */ 129 /* { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" } */ 130 /* { dg-output "\nres: 0x8bf258bd" } */ 131 132 CHECK(ffi_prep_closure_loc(pcl, &cif, cls_pointer_gn, NULL, code) == FFI_OK); 133 134 res = (ffi_arg)(uintptr_t)((void*(*)(void*, void*))(code))(arg1, arg2); 135 136 printf("res: 0x%08x\n", (unsigned int) res); 137 /* { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" } */ 138 /* { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" } */ 139 /* { dg-output "\nres: 0x8bf258bd" } */ 140 141 exit(0); 142} 143