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*/ 18typedef 19 struct _Lard { 20 struct _Lard* next; 21 char stuff[999]; 22 } 23 Lard; 24Lard* lard = NULL; 25static int ctr = 0; 26 27void 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} 37static void post ( char* s, int n, int r ); 38static void pre ( char* s, int n ); 39static int fact1 ( int n ); 40static int fact2 ( int n ); 41 42/* This is needed to stop gcc4 turning 'fact' into a loop */ 43__attribute__((noinline)) 44int mul ( int x, int y ) { return x * y; } 45 46int fact1 ( int n ) 47{ 48 addMoreLard(); 49 if (n == 0) return 1; else return mul(n, fact2(n-1)); 50} 51int fact2 ( int n ) 52{ 53 addMoreLard(); 54 if (n == 0) return 1; else return mul(n, fact1(n-1)); 55} 56 57 58int 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 72int 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 87int 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 104static void send ( char* s ) 105{ 106 while (*s) { 107 write(1, s, 1); 108 s++; 109 } 110} 111 112static 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 125static 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