1 #include <unistd.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include "valgrind.h" 5 6 /* This is the same as wrap5.c, except that the recursion depth is 16. 7 This is intended to check that on ppc64-linux, which uses a 8 16-entry per-thread stack, the resulting stack overflow is caught. 9 (Undetected overflows in redirection stacks are very bad news; they 10 cause guest code to fail in all sorts of strange ways.) 11 12 Hence this test has two expected outcomes: 13 - on ppc64-linux, a stack overflow is caught, and V aborts. 14 - on everything else, it runs successfully to completion. 15 Note, pre() and post() used so as to avoid printf, which messes 16 up the call stacks on ppc64-linux due to intercept of mempcpy. 17 */ 18 typedef 19 struct _Lard { 20 struct _Lard* next; 21 char stuff[999]; 22 } 23 Lard; 24 Lard* lard = NULL; 25 static int ctr = 0; 26 27 void addMoreLard ( void ) 28 { 29 Lard* p; 30 ctr++; 31 if ((ctr % 3) == 1) { 32 p = malloc(sizeof(Lard)); 33 p->next = lard; 34 lard = p; 35 } 36 } 37 static void post ( char* s, int n, int r ); 38 static void pre ( char* s, int n ); 39 static int fact1 ( int n ); 40 static int fact2 ( int n ); 41 42 /* This is needed to stop gcc4 turning 'fact' into a loop */ 43 __attribute__((noinline)) 44 int mul ( int x, int y ) { return x * y; } 45 46 int fact1 ( int n ) 47 { 48 addMoreLard(); 49 if (n == 0) return 1; else return mul(n, fact2(n-1)); 50 } 51 int fact2 ( int n ) 52 { 53 addMoreLard(); 54 if (n == 0) return 1; else return mul(n, fact1(n-1)); 55 } 56 57 58 int I_WRAP_SONAME_FNNAME_ZU(NONE,fact1) ( int n ) 59 { 60 int r; 61 OrigFn fn; 62 VALGRIND_GET_ORIG_FN(fn); 63 pre("wrapper1", n); 64 addMoreLard(); 65 CALL_FN_W_W(r, fn, n); 66 addMoreLard(); 67 post("wrapper1", n, r); 68 if (n >= 3) r += fact2(2); 69 return r; 70 } 71 72 int I_WRAP_SONAME_FNNAME_ZU(NONE,fact2) ( int n ) 73 { 74 int r; 75 OrigFn fn; 76 VALGRIND_GET_ORIG_FN(fn); 77 pre("wrapper2", n); 78 addMoreLard(); 79 CALL_FN_W_W(r, fn, n); 80 addMoreLard(); 81 post("wrapper2", n, r); 82 return r; 83 } 84 85 /* --------------- */ 86 87 int main ( void ) 88 { 89 int r, n = 15; /* 14 succeeds on ppc64-linux, >= 15 fails */ 90 Lard *p, *p_next; 91 printf("computing fact1(%d)\n", n); fflush(stdout); 92 r = fact1(n); 93 printf("fact1(%d) = %d\n", n, r); fflush(stdout); 94 95 printf("allocated %d Lards\n", ctr); fflush(stdout); 96 for (p = lard; p; p = p_next) { 97 p_next = p->next; 98 free(p); 99 } 100 101 return 0; 102 } 103 104 static void send ( char* s ) 105 { 106 while (*s) { 107 write(1, s, 1); 108 s++; 109 } 110 } 111 112 static void pre ( char* s, int n ) 113 { 114 char buf[50]; 115 fflush(stdout); 116 sprintf(buf,"%d", n); 117 send("in "); 118 send(s); 119 send("-pre: fact("); 120 send(buf); 121 send(")\n"); 122 fflush(stdout); 123 } 124 125 static void post ( char* s, int n, int r ) 126 { 127 char buf[50]; 128 fflush(stdout); 129 sprintf(buf,"%d", n); 130 send("in "); 131 send(s); 132 send("-post: fact("); 133 send(buf); 134 send(") = "); 135 sprintf(buf,"%d", r); 136 send(buf); 137 send("\n"); 138 fflush(stdout); 139 } 140