github.com/prattmic/llgo-embedded@v0.0.0-20150820070356-41cfecea0e1e/third_party/gofrontend/libffi/testsuite/libffi.call/cls_pointer_stack.c (about)

     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  
    10  static	long dummyVar;
    11  
    12  long 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  
    21  void* 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  
    46  void* 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  
    73  static void
    74  cls_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  
    95  int 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  }