__attribute__((noreturn))
void barf ( char* str )
{
- int res;
char buf[1000];
buf[0] = 0;
strcat(buf, "\nvalgrind's libpthread.so: ");
strcat(buf, str);
strcat(buf, "\n\n");
- VALGRIND_MAGIC_SEQUENCE(res, 0, /* irrelevant default */
- VG_USERREQ__LOGMESSAGE, buf, 0, 0, 0);
+ VALGRIND_NON_SIMD_CALL2(VG_(message), Vg_UserMsg, buf);
my_exit(1);
/* We have to persuade gcc into believing this doesn't return. */
while (1) { };
static void cat_n_send ( char* pre, char* msg )
{
char buf[1000];
- int res;
if (get_pt_trace_level() >= 0) {
snprintf(buf, sizeof(buf), "%s%s", pre, msg );
buf[sizeof(buf)-1] = '\0';
- VALGRIND_MAGIC_SEQUENCE(res, 0, /* irrelevant default */
- VG_USERREQ__LOGMESSAGE, buf, 0, 0, 0);
+ VALGRIND_NON_SIMD_CALL2(VG_(message), Vg_UserMsg, buf);
}
}
request codes. A few, publically-visible, request codes are also
defined in valgrind.h, and similar headers for some skins. */
-#define VG_USERREQ__MALLOC 0x2001
-#define VG_USERREQ__FREE 0x2002
+#define VG_USERREQ__MALLOC 0x2001
+#define VG_USERREQ__FREE 0x2002
+
+/*
+In vg_skin.h, so skins can use it.
+Call an arbitrary function with ThreadState as the first arg.
+#define VG_USERREQ__CLIENT_tstCALL0 0x2101
+#define VG_USERREQ__CLIENT_tstCALL1 0x2102
+#define VG_USERREQ__CLIENT_tstCALL2 0x2103
+#define VG_USERREQ__CLIENT_tstCALL3 0x2104
+*/
/* (Fn, Arg): Create a new thread and run Fn applied to Arg in it. Fn
MUST NOT return -- ever. Eventually it will do either __QUIT or
#define VG_USERREQ__GET_PTHREAD_TRACE_LEVEL 0x3101
/* Log a pthread error from client-space. Cosmetic. */
#define VG_USERREQ__PTHREAD_ERROR 0x3102
-/*
-In vg_skin.h, so skins can use it.
-Write a string to the logging sink.
-#define VG_USERREQ__LOGMESSAGE 0x3103
-*/
/*
In vg_constants.h:
#define VG_USERREQ__SIGNAL_RETURNS 0x4001
*/
+
/* The scheduler does need to know the address of it so it can be
called at program exit. */
extern void VG_(__libc_freeres_wrapper)( void );
void cat_n_send ( char* pre, char* msg )
{
char buf[1000];
- int res;
if (get_pt_trace_level() >= 0) {
snprintf(buf, sizeof(buf), "%s%s", pre, msg );
buf[sizeof(buf)-1] = '\0';
- VALGRIND_MAGIC_SEQUENCE(res, 0, /* irrelevant default */
- VG_USERREQ__LOGMESSAGE, buf, 0, 0, 0);
+ VALGRIND_NON_SIMD_CALL2(VG_(message), Vg_UserMsg, buf);
}
}
__attribute__((noreturn))
void barf ( char* str )
{
- int res;
char buf[1000];
buf[0] = 0;
strcat(buf, "\nvalgrind's libpthread.so: ");
strcat(buf, str);
strcat(buf, "\n\n");
- VALGRIND_MAGIC_SEQUENCE(res, 0, /* irrelevant default */
- VG_USERREQ__LOGMESSAGE, buf, 0, 0, 0);
+ VALGRIND_NON_SIMD_CALL2(VG_(message), Vg_UserMsg, buf);
my_exit(1);
/* We have to persuade gcc into believing this doesn't return. */
while (1) { };
static void cat_n_send ( char* pre, char* msg )
{
char buf[1000];
- int res;
if (get_pt_trace_level() >= 0) {
snprintf(buf, sizeof(buf), "%s%s", pre, msg );
buf[sizeof(buf)-1] = '\0';
- VALGRIND_MAGIC_SEQUENCE(res, 0, /* irrelevant default */
- VG_USERREQ__LOGMESSAGE, buf, 0, 0, 0);
+ VALGRIND_NON_SIMD_CALL2(VG_(message), Vg_UserMsg, buf);
}
}
handle_signal_return(tid);
break;
- case VG_USERREQ__LOGMESSAGE:
- VG_(message)(Vg_UserMsg, "%s", (Char*)(arg[1]));
- RETURN_WITH(0); /* irrelevant */
- break;
-
/* Requests from the client program */
case VG_USERREQ__DISCARD_TRANSLATIONS:
form 0x1000 + small_number.
*/
-#define VG_USERREQ_SKIN_BASE(a,b) ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
-#define VG_IS_SKIN_USERREQ(a, b, v) (VG_USERREQ_SKIN_BASE(a,b) == ((v) & 0xffff0000))
+#define VG_USERREQ_SKIN_BASE(a,b) \
+ ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
+#define VG_IS_SKIN_USERREQ(a, b, v) \
+ (VG_USERREQ_SKIN_BASE(a,b) == ((v) & 0xffff0000))
typedef
- enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001,
- VG_USERREQ__DISCARD_TRANSLATIONS,
+ enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001,
+ VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002,
/* These allow any function of 0--3 args to be called from the
simulated CPU but run on the real CPU */
- VG_USERREQ__CLIENT_CALL0 = 0x1100,
- VG_USERREQ__CLIENT_CALL1,
- VG_USERREQ__CLIENT_CALL2,
- VG_USERREQ__CLIENT_CALL3,
-
- /* As above, but a pointer to the current ThreadState is inserted
- as the first arg. */
- VG_USERREQ__CLIENT_tstCALL0 = 0x1200,
- VG_USERREQ__CLIENT_tstCALL1,
- VG_USERREQ__CLIENT_tstCALL2,
- VG_USERREQ__CLIENT_tstCALL3,
+ VG_USERREQ__CLIENT_CALL0 = 0x1101,
+ VG_USERREQ__CLIENT_CALL1 = 0x1102,
+ VG_USERREQ__CLIENT_CALL2 = 0x1103,
+ VG_USERREQ__CLIENT_CALL3 = 0x1104,
/* Can be useful in regression testing suites -- eg. can send
Valgrind's output to /dev/null and still count errors. */
- VG_USERREQ__COUNT_ERRORS = 0x1300,
+ VG_USERREQ__COUNT_ERRORS = 0x1201,
VG_USERREQ__FINAL_DUMMY_CLIENT_REQUEST
} Vg_ClientRequest;
Useful for reading in extra skin-specific suppression lines. */
extern Bool VG_(get_line) ( Int fd, Char* buf, Int nBuf );
-/* Client request: write a string to the logging sink. */
-#define VG_USERREQ__LOGMESSAGE 0x3103
-
/*====================================================================*/
/*=== Obtaining debug information ===*/
extern VgSectKind VG_(seg_sect_kind)(Addr);
+/*====================================================================*/
+/*=== Calling functions from the sim'd CPU ===*/
+/*====================================================================*/
+
+#define VG_USERREQ__CLIENT_tstCALL0 0x2101
+#define VG_USERREQ__CLIENT_tstCALL1 0x2102
+#define VG_USERREQ__CLIENT_tstCALL2 0x2103
+#define VG_USERREQ__CLIENT_tstCALL3 0x2104
+
+/* These requests are like VALGRIND_NON_SIMD_CALL[0123] in valgrind.h,
+ except they insert the current ThreadState as the first argument to the
+ called function. */
+#define VALGRIND_NON_SIMD_tstCALL0(_qyy_fn) \
+ ({unsigned int _qyy_res; \
+ VALGRIND_MAGIC_SEQUENCE(_qyy_res, 0 /* default return */, \
+ VG_USERREQ__CLIENT_tstCALL0, \
+ _qyy_fn, \
+ 0, 0, 0); \
+ _qyy_res; \
+ })
+
+#define VALGRIND_NON_SIMD_tstCALL1(_qyy_fn, _qyy_arg1) \
+ ({unsigned int _qyy_res; \
+ VALGRIND_MAGIC_SEQUENCE(_qyy_res, 0 /* default return */, \
+ VG_USERREQ__CLIENT_tstCALL1, \
+ _qyy_fn, \
+ _qyy_arg1, 0, 0); \
+ _qyy_res; \
+ })
+
+#define VALGRIND_NON_SIMD_tstCALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \
+ ({unsigned int _qyy_res; \
+ VALGRIND_MAGIC_SEQUENCE(_qyy_res, 0 /* default return */, \
+ VG_USERREQ__CLIENT_tstCALL2, \
+ _qyy_fn, \
+ _qyy_arg1, _qyy_arg2, 0); \
+ _qyy_res; \
+ })
+
+#define VALGRIND_NON_SIMD_tstCALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
+ ({unsigned int _qyy_res; \
+ VALGRIND_MAGIC_SEQUENCE(_qyy_res, 0 /* default return */, \
+ VG_USERREQ__CLIENT_tstCALL3, \
+ _qyy_fn, \
+ _qyy_arg1, _qyy_arg2, _qyy_arg3); \
+ _qyy_res; \
+ })
+
+
/*====================================================================*/
/*=== Generic hash table ===*/
/*====================================================================*/