/* A concatenation of varinfo1 .. varinfo4 in a shared object. This is to check for correct functionality in a non-zero-biased ELF executable. */ /* Relevant compile flags are: -Wall -g -I$prefix/include/valgrind eg -Wall -g -I`pwd`/Inst/include/valgrind */ #include #include #include #include "memcheck/memcheck.h" /* Cause memcheck to complain about the address "a" and so to print its best guess as to what "a" actually is. a must be addressible. */ __attribute__((noinline)) void croak ( void* aV ) { char* a = (char*)aV; char* undefp = malloc(1); char saved = *a; assert(undefp); *a = *undefp; (void) VALGRIND_CHECK_MEM_IS_DEFINED(a, 1); *a = saved; free(undefp); } #include /* ------------ varinfo1 ------------ */ int global_u1; int global_i1 = 17; char global_u2[10]; char global_i2[10] = { 1,2,3,4,5,6,7,8,9,10 }; __attribute__((noinline)) static int varinfo1_main ( void ) { int local; char* onheap = malloc(3); assert(onheap); croak(onheap+1); free(onheap); croak( &global_u1 ); croak( &global_i1 ); croak( &global_u2[3] ); croak( &global_i2[7] ); croak( &local ); return 0; } /* ------------ varinfo2 ------------ */ __attribute__((noinline)) static void foo2 ( void ) { int var; var = 1; { char var[10]; var[6] = 4; croak( &var[7] ); { struct { double foo; float bar; } var; croak ( 2 + (char*)&var.bar ); } } croak( 1 + (char*)&var ); } __attribute__((noinline)) static int varinfo2_main ( void ) { foo2(); return 0; } /* ------------ varinfo3 ------------ */ static char static_global_def[10] = {0,0,0,0,0, 0,0,0,0,0}; char nonstatic_global_def[10] = {0,0,0,0,0, 0,0,0,0,0}; static char static_global_undef[10]; char nonstatic_global_undef[10]; __attribute__((noinline)) static void bar3 ( char* p1, char* p2, char* p3, char* p4 ) { croak(p1); croak(p2); croak(p3); croak(p4); } __attribute__((noinline)) static void foo3 ( void ) { static char static_local_def[10] = {0,0,0,0,0, 0,0,0,0,0}; char nonstatic_local_def[10] = {0,0,0,0,0, 0,0,0,0,0}; static char static_local_undef[10]; char nonstatic_local_undef[10]; croak ( 1 + (char*)&static_global_def ); croak ( 2 + (char*)&nonstatic_global_def ); croak ( 3 + (char*)&static_global_undef ); croak ( 4 + (char*)&nonstatic_global_undef ); bar3( 5 + (char*)&static_local_def, 6 + (char*)&nonstatic_local_def, 7 + (char*)&static_local_undef, 8 + (char*)&nonstatic_local_undef ); } __attribute__((noinline)) static int varinfo3_main ( void ) { foo3(); return 0; } /* ------------ varinfo4 ------------ */ #include typedef struct { short c1; char* c2[3]; } XX; typedef struct _str { int bing; int bong; XX xyzzy[77]; } Str; __attribute__((noinline)) static int blah4 ( int x, int y ) { Str a[10]; memset(a, 0, sizeof(a)); croak(1 + (char*)(&a[3].xyzzy[x*y].c1)); croak( (char*)(&a[5].bong) ); croak( 1 + (char*)(&a[3].xyzzy[x*y].c2[2]) ); memset(a, 0, sizeof(a)); return a[3].xyzzy[x*y].c1; } __attribute__((noinline)) static int varinfo4_main ( void ) { fprintf(stderr, "answer is %d\n", blah4(3,7) ); return 0; } static void inlinetest(void); /* ------------ varinfo5 ------------ */ void varinfo5_main ( void ) { varinfo1_main(); varinfo2_main(); varinfo3_main(); varinfo4_main(); inlinetest(); } #define INLINE inline __attribute__((always_inline)) INLINE void fun_c(int argc) { croak(&argc); } INLINE void fun_b(int argb) { fun_c(argb); } INLINE void fun_a(int *arga) { fun_b(*arga); } void inlinetest(void) { int i = 1; fun_a(&i); }