wrap4.vgtest wrap4.stdout.exp wrap4.stderr.exp \
wrap5.vgtest wrap5.stdout.exp wrap5.stderr.exp \
wrap6.vgtest wrap6.stdout.exp wrap6.stderr.exp \
+ wrap7.vgtest wrap7.stdout.exp wrap7.stderr.exp \
+ wrap8.vgtest wrap8.stdout.exp wrap8.stderr.exp \
writev.stderr.exp writev.stderr.exp2 writev.stderr.exp3 writev.vgtest \
xml1.stderr.exp xml1.stderr.exp2 xml1.stderr.exp3 \
xml1.stderr.exp64 xml1.stderr.exp64_2 xml1.stdout.exp \
trivialleak \
mismatches new_override metadata \
xml1 \
- wrap1 wrap2 wrap3 wrap4 wrap5 wrap6 \
+ wrap1 wrap2 wrap3 wrap4 wrap5 wrap6 wrap7 wrap7so.so wrap8 \
writev zeropage
oset_test_CFLAGS = $(AM_FLAG_M3264_PRI) \
-DVGA_$(VG_ARCH)=1 -DVGO_$(VG_OS)=1 \
-DVGP_$(VG_ARCH)_$(VG_OS)=1
+
# Don't allow GCC to inline memcpy(), because then we can't intercept it
overlap_CFLAGS = $(AM_CFLAGS) -fno-builtin-memcpy
stack_switch_LDADD = -lpthread
new_nothrow_SOURCES = new_nothrow.cpp
new_override_SOURCES = new_override.cpp
+# Build shared object for wrap7
+wrap7_SOURCES = wrap7.c
+wrap7_DEPENDENCIES = wrap7so.so
+wrap7_LDFLAGS = $(AM_FLAG_M3264_PRI) \
+ -Wl,-rpath,$(top_builddir)/memcheck/tests
+wrap7_LDADD = wrap7so.so
+wrap7so_so_SOURCES = wrap7so.c
+wrap7so_so_LDADD =
+wrap7so_so_DEPENDENCIES =
+wrap7so_so_LDFLAGS = -fpic $(AM_FLAG_M3264_PRI) \
+ -Wl,-soname -Wl,wrap7so.so -shared
+wrap7so_so_CFLAGS = -fpic $(AM_FLAG_M3264_PRI)
+
# Valgrind unit self-tests
#hello_LDFLAGS = -Wl,-defsym,valt_load_address=0x50000000 \
# -Wl,-T,$(top_builddir)/valt_load_address.lds
--- /dev/null
+
+#include <stdio.h>
+#include "valgrind.h"
+
+/* The simplest possible wrapping test: just call a wrapped function
+ and check we run the wrapper instead. Except: the wrapped
+ function is in a different shared object. This causes some
+ additional complications on ppc64-linux, hence another test. */
+
+extern void actual ( void );
+
+/* The wrapper. The function being wrapped is in a .so with soname
+ "wrap7so.so". */
+void I_WRAP_SONAME_FNNAME_ZU(wrap7soZdso,actual) ( void )
+{
+ OrigFn orig;
+ VALGRIND_GET_ORIG_FN(orig);
+ printf("wrapper-pre\n");
+ CALL_FN_v_v(orig);
+ printf("wrapper-post\n");
+}
+
+/* --------------- */
+
+int main ( void )
+{
+ printf("starting\n");
+ actual();
+ return 0;
+}
--- /dev/null
+starting
+wrapper-pre
+in actual-so
+wrapper-post
--- /dev/null
+prog: wrap7
+vgopts: -q
--- /dev/null
+
+#include <stdio.h>
+#include <unistd.h>
+/* The "original" function */
+
+void actual ( void )
+{
+ printf("in actual-so\n");
+}
+
--- /dev/null
+
+#include <stdio.h>
+#include <malloc.h>
+#include "valgrind.h"
+
+/* This is the same as wrap5.c, except that the recursion depth is 16.
+ This is intended to check that on ppc64-linux, which uses a
+ 16-entry per-thread stack, the resulting stack overflow is caught.
+ (Undetected overflows in redirection stacks are very bad news; they
+ cause guest code to fail in all sorts of strange ways.)
+
+ Hence this test has two expected outcomes:
+ - on ppc64-linux, a stack overflow is caught, and V aborts.
+ - on everything else, it runs successfully to completion.
+*/
+
+typedef
+ struct _Lard {
+ struct _Lard* next;
+ char stuff[999];
+ }
+ Lard;
+
+Lard* lard = NULL;
+static int ctr = 0;
+
+void addMoreLard ( void )
+{
+ Lard* p;
+ ctr++;
+ if ((ctr % 3) == 1) {
+ p = malloc(sizeof(Lard));
+ p->next = lard;
+ lard = p;
+ }
+}
+
+
+static int fact1 ( int n );
+static int fact2 ( int n );
+
+/* This is needed to stop gcc4 turning 'fact' into a loop */
+__attribute__((noinline))
+int mul ( int x, int y ) { return x * y; }
+
+int fact1 ( int n )
+{
+ addMoreLard();
+ if (n == 0) return 1; else return mul(n, fact2(n-1));
+}
+int fact2 ( int n )
+{
+ addMoreLard();
+ if (n == 0) return 1; else return mul(n, fact1(n-1));
+}
+
+
+int I_WRAP_SONAME_FNNAME_ZU(NONE,fact1) ( int n )
+{
+ int r;
+ OrigFn fn;
+ VALGRIND_GET_ORIG_FN(fn);
+ printf("in wrapper1-pre: fact(%d)\n", n); fflush(stdout);
+ addMoreLard();
+ CALL_FN_W_W(r, fn, n);
+ addMoreLard();
+ printf("in wrapper1-post: fact(%d) = %d\n", n, r); fflush(stdout);
+ if (n >= 3) r += fact2(2);
+ return r;
+}
+
+int I_WRAP_SONAME_FNNAME_ZU(NONE,fact2) ( int n )
+{
+ int r;
+ OrigFn fn;
+ VALGRIND_GET_ORIG_FN(fn);
+ printf("in wrapper2-pre: fact(%d)\n", n); fflush(stdout);
+ addMoreLard();
+ CALL_FN_W_W(r, fn, n);
+ addMoreLard();
+ printf("in wrapper2-post: fact(%d) = %d\n", n, r); fflush(stdout);
+ return r;
+}
+
+/* --------------- */
+
+int main ( void )
+{
+ int r, n = 15; /* 14 succeeds on ppc64-linux, >= 15 fails */
+ Lard *p, *p_next;
+ printf("computing fact1(%d)\n", n); fflush(stdout);
+ r = fact1(n);
+ printf("fact1(%d) = %d\n", n, r); fflush(stdout);
+
+ printf("allocated %d Lards\n", ctr); fflush(stdout);
+ for (p = lard; p; p = p_next) {
+ p_next = p->next;
+ free(p);
+ }
+
+ return 0;
+}
--- /dev/null
+Emulation fatal error -- Valgrind cannot continue:
+ PPC64 function redirection stack overflow
+ at 0x........: ???
+ by 0x........: fact2 (wrap8.c:78)
+ by 0x........: ...
+ by 0x........: fact1 (wrap8.c:65)
+ by 0x........: ...
+ by 0x........: fact2 (wrap8.c:79)
+ by 0x........: ...
+ by 0x........: fact1 (wrap8.c:65)
+ by 0x........: ...
+ by 0x........: fact2 (wrap8.c:79)
+ by 0x........: ...
+ by 0x........: fact1 (wrap8.c:65)
+
+Valgrind has to exit now. Sorry.
+
--- /dev/null
+computing fact1(15)
+in wrapper1-pre: fact(15)
+in wrapper2-pre: fact(14)
+in wrapper1-pre: fact(13)
+in wrapper2-pre: fact(12)
+in wrapper1-pre: fact(11)
+in wrapper2-pre: fact(10)
+in wrapper1-pre: fact(9)
+in wrapper2-pre: fact(8)
+in wrapper1-pre: fact(7)
+in wrapper2-pre: fact(6)
+in wrapper1-pre: fact(5)
+in wrapper2-pre: fact(4)
+in wrapper1-pre: fact(3)
+in wrapper2-pre: fact(2)
+in wrapper1-pre: fact(1)
+in wrapper2-pre: fact(0)
--- /dev/null
+prog: wrap8
+vgopts: -q