|
From: <sv...@va...> - 2005-12-07 17:37:14
|
Author: sewardj
Date: 2005-12-07 17:36:55 +0000 (Wed, 07 Dec 2005)
New Revision: 5310
Log:
- Track changes in redir support in vex r1485. =20
- start to add some macros to valgrind.h to be used for end-users to
write wrappers conveniently
Modified:
branches/FNWRAP/coregrind/m_scheduler/scheduler.c
branches/FNWRAP/include/pub_tool_redir.h
branches/FNWRAP/include/valgrind.h
Modified: branches/FNWRAP/coregrind/m_scheduler/scheduler.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/coregrind/m_scheduler/scheduler.c 2005-12-07 00:55:14=
UTC (rev 5309)
+++ branches/FNWRAP/coregrind/m_scheduler/scheduler.c 2005-12-07 17:36:55=
UTC (rev 5310)
@@ -1033,14 +1033,23 @@
zztid, O_CLREQ_RET, sizeof(UWord), f); \
} while (0)
=20
-#define SET_CLIENT_NOREDIR(zztid, zzval) \
- do { VG_(threads)[zztid].arch.vex.guest_NOREDIR =3D 1; \
+#define SET_CLIENT_NRADDR(zztid, zzaddr) \
+ do { VG_(threads)[zztid].arch.vex.guest_NRFLAG =3D 1; \
+ VG_(threads)[zztid].arch.vex.guest_NRADDR =3D (zzaddr); \
VG_TRACK( post_reg_write, \
Vg_CoreClientReq, zztid, \
- offsetof(VexGuestArchState,guest_NOREDIR), \
+ offsetof(VexGuestArchState,guest_NRFLAG), \
sizeof(UWord) ); \
+ VG_TRACK( post_reg_write, \
+ Vg_CoreClientReq, zztid, \
+ offsetof(VexGuestArchState,guest_NRADDR), \
+ sizeof(UWord) ); \
} while (0)
=20
+#define GET_CLIENT_NRFLAG(zztid) \
+ VG_(threads)[zztid].arch.vex.guest_NRFLAG
+
+
/* ---------------------------------------------------------------------
Handle client requests.
------------------------------------------------------------------ */
@@ -1085,10 +1094,17 @@
VG_(printf)("req no =3D 0x%llx, arg =3D %p\n", (ULong)req_no, arg)=
;
switch (req_no) {
=20
- case VG_USERREQ__SET_NOREDIR:
- SET_CLIENT_NOREDIR(tid, 1);
- SET_CLREQ_RETVAL(tid, 0);
+ case VG_USERREQ__PUSH_NRADDR: {
+ Addr noredir =3D arg[1];
+ if (GET_CLIENT_NRFLAG(tid) !=3D 0) {
+ /* The 1-entry stack is full, so we must fail (return 1). */
+ SET_CLREQ_RETVAL(tid, 1);
+ } else {
+ SET_CLIENT_NRADDR(tid, noredir); /* also sets _NRFLAG */
+ SET_CLREQ_RETVAL(tid, 0);
+ }
break;
+ }
=20
case VG_USERREQ__CLIENT_CALL0: {
UWord (*f)(ThreadId) =3D (void*)arg[1];
Modified: branches/FNWRAP/include/pub_tool_redir.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/include/pub_tool_redir.h 2005-12-07 00:55:14 UTC (rev=
5309)
+++ branches/FNWRAP/include/pub_tool_redir.h 2005-12-07 17:36:55 UTC (rev=
5310)
@@ -110,8 +110,9 @@
Everything else is left unchanged.
*/
=20
-/* If you change these, the code in VG_(maybe_Z_demangle) needs to
- be changed accordingly. */
+/* If you change these, the code in VG_(maybe_Z_demangle) needs to be
+ changed accordingly. NOTE: duplicates
+ I_REPLACE_SONAME_FNNAME_Z{U,Z} in valgrind.h. */
#define VG_REDIRECT_FUNCTION_ZU(soname,fnname) _vgrZU_##soname##_##fnnam=
e
#define VG_REDIRECT_FUNCTION_ZZ(soname,fnname) _vgrZZ_##soname##_##fnnam=
e
=20
Modified: branches/FNWRAP/include/valgrind.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/include/valgrind.h 2005-12-07 00:55:14 UTC (rev 5309)
+++ branches/FNWRAP/include/valgrind.h 2005-12-07 17:36:55 UTC (rev 5310)
@@ -248,7 +248,7 @@
typedef
enum { VG_USERREQ__RUNNING_ON_VALGRIND =3D 0x1001,
VG_USERREQ__DISCARD_TRANSLATIONS =3D 0x1002,
- VG_USERREQ__SET_NOREDIR =3D 0x1003,
+ VG_USERREQ__PUSH_NRADDR =3D 0x1003,
=20
/* These allow any function to be called from the
simulated CPU but run on the real CPU.
@@ -311,19 +311,30 @@
_qzz_addr, _qzz_len, 0, 0); \
}
=20
-/* Sets this thread's guest_NOREDIR register to 1, so that the next
- entry by this thread into a redirected translation will cause it
- instead to jump to the non-redirected version. */
-#define VALGRIND_SET_NOREDIR __extension__ \
- ({unsigned int _qzz_res; \
- VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \
- VG_USERREQ__SET_NOREDIR, \
- 0, 0, 0, 0); \
- _qzz_res; \
+/* Push an address onto this thread's stack of noredir addresses, so
+ that the next entry by this thread into a redirected translation
+ whose address is on top of the stack will instead to jump to the
+ non-redirected version. Returns 0 if success, 1 if failure. */
+#define VALGRIND_PUSH_NRADDR(_qzz_addr) __extension__ \
+ ({unsigned long _qzz_res; \
+ VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0/*native result*/, \
+ VG_USERREQ__PUSH_NRADDR, \
+ _qzz_addr, 0, 0, 0); \
+ _qzz_res; \
})
+#define VALGRIND_PUSH_NRADDR_AND_CHECK(_addr) \
+ do { \
+ extern void exit(int); \
+ long _r =3D VALGRIND_PUSH_NRADDR(_addr); \
+ if (_r) { \
+ VALGRIND_PRINTF_BACKTRACE( \
+ "Valgrind: function wrapping: " \
+ "redirect stack is full. Program halted."); \
+ exit(1); \
+ } \
+ } while (0)
=20
=20
-
#ifdef NVALGRIND
=20
#define VALGRIND_PRINTF(...)
@@ -509,4 +520,41 @@
id, start, end, 0); \
}
=20
+
+/* --- End-user functions for writing function wrappers. --- */
+
+/* Use these to write the name of your wrapper. NOTE: duplicates
+ VG_REDIRECT_FUNCTION_Z{U,Z} in pub_tool_redir.h. */
+
+#define I_REPLACE_SONAME_FNNAME_ZU(soname,fnname) \
+ _vgrZU_##soname##_##fnname
+
+#define I_REPLACE_SONAME_FNNAME_ZZ(soname,fnname) \
+ _vgrZZ_##soname##_##fnname
+
+/* Use these inside the wrapper, to make calls to the function you are
+ wrapping. You must use these - calling originals directly will get
+ you a redirect-stack overflow in short order. Also, these force
+ evaluation of all args before pushing the noredir-address, which is
+ needed to make things work reliably.*/
+
+/* returns void, takes zero args */
+#define CALL_ORIG_VOIDFN_0(fn) \
+ do { \
+ __typeof__(&(fn)) _fn =3D &(fn); \
+ VALGRIND_PUSH_NRADDR_AND_CHECK(_fn); \
+ (*_fn)(); \
+ } while (0)
+
+/* returns an arg, takes one arg */
+#define CALL_ORIG_FN_1(lval,fn,arg1) \
+ do { \
+ __typeof__(&(fn)) _fn =3D &(fn); \
+ __typeof__(lval) _lval; \
+ __typeof__(arg1) _arg1 =3D (arg1); \
+ VALGRIND_PUSH_NRADDR_AND_CHECK(_fn); \
+ _lval =3D (*_fn)(_arg1); \
+ lval =3D _lval; \
+ } while (0)
+
#endif /* __VALGRIND_H */
|