You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
|
|
1
(16) |
2
(23) |
3
(15) |
|
4
(19) |
5
(21) |
6
(27) |
7
(18) |
8
(17) |
9
(15) |
10
(11) |
|
11
(9) |
12
(18) |
13
(26) |
14
(28) |
15
(26) |
16
(20) |
17
(27) |
|
18
(16) |
19
(40) |
20
(2) |
21
(11) |
22
(27) |
23
(24) |
24
(16) |
|
25
(10) |
26
(12) |
27
(16) |
28
(7) |
29
(6) |
30
(15) |
31
(5) |
|
From: <sv...@va...> - 2005-12-28 15:19:43
|
Author: sewardj
Date: 2005-12-28 15:19:39 +0000 (Wed, 28 Dec 2005)
New Revision: 5456
Log:
Tentative fix for #117332: No line numbers printed by Valgrind 3.1.0
for programs compiled with Intel compiler.
Modified:
trunk/coregrind/m_debuginfo/symtab.c
Modified: trunk/coregrind/m_debuginfo/symtab.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
--- trunk/coregrind/m_debuginfo/symtab.c 2005-12-28 04:18:20 UTC (rev 545=
5)
+++ trunk/coregrind/m_debuginfo/symtab.c 2005-12-28 15:19:39 UTC (rev 545=
6)
@@ -127,6 +127,15 @@
symbols from the rwx segment -- which overlaps the r-x segment in the
file -- causes the redirection mechanism to redirect to addresses in
that third segment, which is wrong and causes crashes.
+
+ ------
+ JRS 28 Dec 05: unfortunately icc 8.1 on x86 has been seen to
+ produce executables with a single rwx segment rather than a
+ (r-x,rw-) pair. That means the rules have to be modified thusly:
+
+ x86-linux: consider if r and x
+ all others: consider if r and x and NOT w
+
*/
=20
static void nuke_syms_in_range ( Addr start, SizeT length )
@@ -144,7 +153,8 @@
curr =3D segInfo_list;
while (True) {
if (curr =3D=3D NULL) break;
- if (start+length-1 < curr->start || curr->start+curr->size-1 < =
start) {
+ if (start+length-1 < curr->start=20
+ || curr->start+curr->size-1 < start) {
/* no overlap */
} else {
found =3D True;
@@ -155,7 +165,6 @@
=20
if (!found) break;
unload_symbols( curr->start, curr->size );
-
}
}
=20
@@ -172,6 +181,14 @@
HChar* filename;
Bool ok;
=20
+ /* See comment at start of section for explanation of this do/don't
+ logic. */
+# if defined(VGP_x86_linux)
+ Bool require_no_W =3D False;
+# else
+ Bool require_no_W =3D True;
+# endif
+
seg =3D VG_(am_find_nsegment)(a);
vg_assert(seg);
=20
@@ -186,7 +203,7 @@
&& seg->fnIdx !=3D -1
&& seg->hasR
&& seg->hasX
- && !seg->hasW
+ && (require_no_W ? (!seg->hasW) : True)
&& is_elf_object_file( (const void*)seg->start );
=20
if (!ok) {
|
|
From: <sv...@va...> - 2005-12-28 04:18:25
|
Author: sewardj
Date: 2005-12-28 04:18:20 +0000 (Wed, 28 Dec 2005)
New Revision: 5455
Log:
In fbench, compute sin/cos/sqrt from "first principles", so that the
program more uniformly measures the speed of FP +/-/* load/store
across different architectures.
Modified:
trunk/perf/Makefile.am
trunk/perf/fbench.c
Modified: trunk/perf/Makefile.am
=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
--- trunk/perf/Makefile.am 2005-12-28 00:57:48 UTC (rev 5454)
+++ trunk/perf/Makefile.am 2005-12-28 04:18:20 UTC (rev 5455)
@@ -21,6 +21,6 @@
AM_CXXFLAGS =3D $(AM_CFLAGS)
=20
# Extra stuff
-fbench_LDADD =3D -lm
+fbench_CFLAGS =3D -g -O2
+fbench_LDADD =3D=20
ffbench_LDADD =3D -lm
-
Modified: trunk/perf/fbench.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
--- trunk/perf/fbench.c 2005-12-28 00:57:48 UTC (rev 5454)
+++ trunk/perf/fbench.c 2005-12-28 04:18:20 UTC (rev 5455)
@@ -8,7 +8,17 @@
// site is in the public domain and may be used in any manner without
// permission, restriction, attribution, or compensation."
=20
+/* This program can be used in two ways. If INTRIG is undefined, sin,
+ cos, tan, etc, will be used as supplied by <math.h>. If it is
+ defined, then the program calculates all this stuff from first
+ principles (so to speak) and does not use the libc facilities. For
+ benchmarking purposes it seems better to avoid the libc stuff, so
+ that the inner loops (sin, sqrt) present a workload independent of
+ libc implementations on different platforms. Hence: */
=20
+#define INTRIG 1
+
+
/*
=20
John Walker's Floating Point Benchmark, derived from...
@@ -238,6 +248,7 @@
=20
*/
=20
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -289,7 +300,7 @@
tracing code. */
=20
#ifndef ITERATIONS
-#define ITERATIONS /*1000*/ /*500000*/ 125000
+#define ITERATIONS /*1000*/ /*500000*/ 80000
#endif
int niter =3D ITERATIONS; /* Iteration counter */
=20
|
|
From: <js...@ac...> - 2005-12-28 04:14:28
|
Nightly build on phoenix ( SuSE 10.0 ) started at 2005-12-28 03:30:02 GMT Checking out vex source tree ... done Building vex ... done Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 208 tests, 5 stderr failures, 2 stdout failures ================= memcheck/tests/leak-tree (stderr) memcheck/tests/stack_switch (stderr) memcheck/tests/x86/scalar (stderr) none/tests/mremap2 (stdout) none/tests/tls (stdout) none/tests/x86/faultstatus (stderr) none/tests/x86/int (stderr) ================================================= == Results from 24 hours ago == ================================================= Checking out vex source tree ... done Building vex ... done Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 208 tests, 5 stderr failures, 1 stdout failure ================= memcheck/tests/leak-tree (stderr) memcheck/tests/stack_switch (stderr) memcheck/tests/x86/scalar (stderr) none/tests/mremap2 (stdout) none/tests/x86/faultstatus (stderr) none/tests/x86/int (stderr) ================================================= == Difference between 24 hours ago and now == ================================================= *** old.short Wed Dec 28 03:45:30 2005 --- new.short Wed Dec 28 04:14:38 2005 *************** *** 10,12 **** ! == 208 tests, 5 stderr failures, 1 stdout failure ================= memcheck/tests/leak-tree (stderr) --- 10,12 ---- ! == 208 tests, 5 stderr failures, 2 stdout failures ================= memcheck/tests/leak-tree (stderr) *************** *** 15,16 **** --- 15,17 ---- none/tests/mremap2 (stdout) + none/tests/tls (stdout) none/tests/x86/faultstatus (stderr) |
|
From: <js...@ac...> - 2005-12-28 03:54:36
|
Nightly build on g5 ( YDL 4.0, ppc970 ) started at 2005-12-28 04:40:01 CET Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 176 tests, 15 stderr failures, 1 stdout failure ================= memcheck/tests/badjump (stderr) memcheck/tests/badjump2 (stderr) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/leakotron (stdout) memcheck/tests/mempool (stderr) memcheck/tests/partiallydefinedeq (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/supp1 (stderr) memcheck/tests/supp_unknown (stderr) memcheck/tests/toobig-allocs (stderr) memcheck/tests/xml1 (stderr) massif/tests/toobig-allocs (stderr) none/tests/faultstatus (stderr) none/tests/fdleak_cmsg (stderr) none/tests/mremap (stderr) |
|
From: Tom H. <to...@co...> - 2005-12-28 03:43:24
|
Nightly build on dunsmere ( athlon, Fedora Core 4 ) started at 2005-12-28 03:30:06 GMT Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 210 tests, 7 stderr failures, 1 stdout failure ================= memcheck/tests/leak-tree (stderr) memcheck/tests/mempool (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/stack_switch (stderr) memcheck/tests/x86/scalar (stderr) none/tests/mremap2 (stdout) none/tests/x86/faultstatus (stderr) none/tests/x86/int (stderr) |
|
From: <sv...@va...> - 2005-12-28 00:57:52
|
Author: sewardj
Date: 2005-12-28 00:57:48 +0000 (Wed, 28 Dec 2005)
New Revision: 5454
Log:
Use new "Special" instruction support in vex to provide a fast
implementation of function wrapping, that does not require any client
requests. The dynamic net overhead of a function wrap is now two
extra basic blocks (of client code), which means we should be able to
do wrapping of frequently-called functions (eg pthread_mutex_lock)
without excessive (baseline) overheads.
Massively tidy up/restructure valgrind.h as a side effect.
Modified:
branches/FNWRAP/coregrind/coregrind.h
branches/FNWRAP/coregrind/m_replacemalloc/vg_replace_malloc.c
branches/FNWRAP/coregrind/m_scheduler/scheduler.c
branches/FNWRAP/coregrind/vg_preloaded.c
branches/FNWRAP/include/valgrind.h
branches/FNWRAP/memcheck/mac_replace_strmem.c
branches/FNWRAP/memcheck/memcheck.h
Modified: branches/FNWRAP/coregrind/coregrind.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/coregrind/coregrind.h 2005-12-27 16:40:35 UTC (rev 54=
53)
+++ branches/FNWRAP/coregrind/coregrind.h 2005-12-28 00:57:48 UTC (rev 54=
54)
@@ -66,8 +66,10 @@
unsigned long _qzz_res =3D 0;
va_list vargs;
va_start(vargs, format);
- VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, VG_USERREQ__INTERNAL_PRINTF,
- (unsigned long)format, (unsigned long)vargs, =
0, 0);
+ VALGRIND_DO_CLIENT_REQUEST(
+ _qzz_res, 0, VG_USERREQ__INTERNAL_PRINTF,
+ (unsigned long)format, (unsigned long)vargs, 0, 0
+ );
va_end(vargs);
return _qzz_res;
}
Modified: branches/FNWRAP/coregrind/m_replacemalloc/vg_replace_malloc.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_replacemalloc/vg_replace_malloc.c 2005-12=
-27 16:40:35 UTC (rev 5453)
+++ branches/FNWRAP/coregrind/m_replacemalloc/vg_replace_malloc.c 2005-12=
-28 00:57:48 UTC (rev 5454)
@@ -461,8 +461,8 @@
=20
init_done =3D 1;
=20
- VALGRIND_MAGIC_SEQUENCE(res, -1, VG_USERREQ__GET_MALLOCFUNCS, &info,
- 0, 0, 0);
+ VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__GET_MALLOCFUNCS, &inf=
o,
+ 0, 0, 0);
}
=20
/*--------------------------------------------------------------------*/
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-27 16:40:35=
UTC (rev 5453)
+++ branches/FNWRAP/coregrind/m_scheduler/scheduler.c 2005-12-28 00:57:48=
UTC (rev 5454)
@@ -1033,28 +1033,7 @@
zztid, O_CLREQ_RET, sizeof(UWord), f); \
} while (0)
=20
-#define SET_CLIENT_NRFLAG(zztid, zzflag) \
- do { VG_(threads)[zztid].arch.vex.guest_NRFLAG =3D (zzflag); \
- VG_TRACK( post_reg_write, \
- Vg_CoreClientReq, zztid, \
- offsetof(VexGuestArchState,guest_NRFLAG), \
- sizeof(UWord) ); \
- } while (0)
=20
-#define SET_CLIENT_NRADDR(zztid, zzaddr) \
- do { VG_(threads)[zztid].arch.vex.guest_NRADDR =3D (zzaddr); \
- VG_TRACK( post_reg_write, \
- Vg_CoreClientReq, zztid, \
- offsetof(VexGuestArchState,guest_NRADDR), \
- sizeof(UWord) ); \
- } while (0)
-
-#define GET_CLIENT_NRFLAG(zztid) \
- VG_(threads)[zztid].arch.vex.guest_NRFLAG
-#define GET_CLIENT_NRADDR(zztid) \
- VG_(threads)[zztid].arch.vex.guest_NRADDR
-
-
/* ---------------------------------------------------------------------
Handle client requests.
------------------------------------------------------------------ */
@@ -1099,10 +1078,6 @@
VG_(printf)("req no =3D 0x%llx, arg =3D %p\n", (ULong)req_no, arg)=
;
switch (req_no) {
=20
- case VG_USERREQ__GET_NRADDR:
- SET_CLREQ_RETVAL(tid, VG_(threads)[tid].arch.vex.guest_NRADDR);
- break;
-
case VG_USERREQ__CLIENT_CALL0: {
UWord (*f)(ThreadId) =3D (void*)arg[1];
if (f =3D=3D NULL)
Modified: branches/FNWRAP/coregrind/vg_preloaded.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/vg_preloaded.c 2005-12-27 16:40:35 UTC (rev=
5453)
+++ branches/FNWRAP/coregrind/vg_preloaded.c 2005-12-28 00:57:48 UTC (rev=
5454)
@@ -61,8 +61,8 @@
extern void __libc_freeres(void);
__libc_freeres();
#endif
- VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */,
- VG_USERREQ__LIBC_FREERES_DONE, 0, 0, 0, 0);
+ VALGRIND_DO_CLIENT_REQUEST(res, 0 /* default */,
+ VG_USERREQ__LIBC_FREERES_DONE, 0, 0, 0, 0)=
;
/*NOTREACHED*/
*(int *)0 =3D 'x';
}
@@ -71,25 +71,26 @@
/*--- end ---*/
/*--------------------------------------------------------------------*/
=20
-#if 0
+#if 1
=20
#define PTH_FUNC(ret_ty, f, args...) \
- ret_ty VG_REDIRECT_FUNCTION_ZZ(libpthreadZdsoZd0,f)(args); \
- ret_ty VG_REDIRECT_FUNCTION_ZZ(libpthreadZdsoZd0,f)(args)
+ ret_ty VG_WRAP_FUNCTION_ZZ(libpthreadZdsoZd0,f)(args); \
+ ret_ty VG_WRAP_FUNCTION_ZZ(libpthreadZdsoZd0,f)(args)
=20
#include <stdio.h>
#include <pthread.h>
=20
-// pthread_create@GLIBC_2.0 - making it match this too causes loops.??
-// pthread_create@@GLIBC_2.1
-PTH_FUNC(int, pthreadZucreateZAZAGLIBCZu2Zd1, // pthread_create@@GLIBC_2=
.1
+// pthread_create
+PTH_FUNC(int, pthreadZucreateZAZa, // pthread_create@*
pthread_t *thread, const pthread_attr_t *attr,
void *(*start) (void *), void *arg)
{
- int ret;
+ int ret;
+ void* fn;
+ VALGRIND_GET_NRADDR(fn);
fprintf(stderr, "<< pthread_create wrapper"); fflush(stderr);
=20
- CALL_ORIG_FN_4_UNCHECKED(ret, pthread_create, thread,attr,start,arg);
+ CALL_FN_W_WWWW(ret, fn, thread,attr,start,arg);
=20
fprintf(stderr, " -> %d >>\n", ret);
return ret;
@@ -99,10 +100,12 @@
PTH_FUNC(int, pthreadZumutexZulock, // pthread_mutex_lock
pthread_mutex_t *mutex)
{
- int ret;
+ int ret;
+ void* fn;
+ VALGRIND_GET_ORIG_FN(fn);
fprintf(stderr, "<< pthread_mxlock %p", mutex); fflush(stderr);
=20
- CALL_ORIG_FN_1_UNCHECKED(ret, pthread_mutex_lock, mutex);
+ CALL_FN_W_W(ret, fn, mutex);
=20
fprintf(stderr, " -> %d >>\n", ret);
return ret;
@@ -113,9 +116,12 @@
pthread_mutex_t *mutex)
{
int ret;
+ void* fn;
+ VALGRIND_GET_ORIG_FN(fn);
+
fprintf(stderr, "<< pthread_mxunlk %p", mutex); fflush(stderr);
=20
- CALL_ORIG_FN_1_UNCHECKED(ret, pthread_mutex_unlock, mutex);
+ CALL_FN_W_W(ret, fn, mutex);
=20
fprintf(stderr, " -> %d >>\n", ret);
return ret;
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-27 16:40:35 UTC (rev 5453)
+++ branches/FNWRAP/include/valgrind.h 2005-12-28 00:57:48 UTC (rev 5454)
@@ -63,7 +63,7 @@
The resulting executables will still run without Valgrind, just a
little bit more slowly than they otherwise would, but otherwise
unchanged. When not running on valgrind, each client request
- consumes very few (eg. < 10) instructions, so the resulting performan=
ce
+ consumes very few (eg. 7) instructions, so the resulting performance
loss is negligible unless you plan to execute client requests
millions of times per second. Nevertheless, if that is still a
problem, you can compile with the NVALGRIND symbol defined (gcc
@@ -78,41 +78,69 @@
we can't use C++ style "//" comments nor the "asm" keyword (instead
use "__asm__"). */
=20
+/* Derive some tags indicating what the target architecture is. Note
+ that in this file we're using the compiler's CPP symbols for
+ identifying architectures, which are different to the ones we use
+ within the rest of Valgrind. Note, __powerpc__ is active for both
+ 32 and 64-bit PPC, whereas __powerpc64__ is only active for the
+ latter. */
+#undef ARCH_x86
+#undef ARCH_amd64
+#undef ARCH_ppc32
+#undef ARCH_ppc64
+
+#if defined(__i386__)
+# define ARCH_x86 1
+#elif defined(__x86_64__)
+# define ARCH_amd64 1
+#elif defined(__powerpc__) && !defined(__powerpc64__)
+# define ARCH_ppc32 1
+#elif defined(__powerpc__) && defined(__powerpc64__)
+# define ARCH_ppc64 1
+#endif
+
/* If we're not compiling for our target architecture, don't generate
- any inline asms. Note that in this file we're using the compiler's
- CPP symbols for identifying architectures, which are different to
- the ones we use within the rest of Valgrind. Note, __powerpc__ is
- active for both 32 and 64-bit PPC, whereas __powerpc64__ is only
- active for the latter. */
-#if !defined(__i386__) && !defined(__x86_64__) && !defined(__powerpc__)
-# ifndef NVALGRIND
-# define NVALGRIND 1
-# endif /* NVALGRIND */
+ any inline asms. */
+#if !defined(ARCH_x86) && !defined(ARCH_amd64) \
+ && !defined(ARCH_ppc32) && !defined(ARCH_ppc64)
+# if !defined(NVALGRIND)
+# define NVALGRIND 1
+# endif
#endif
=20
+
/* ------------------------------------------------------------------ */
-/* The architecture-specific part */
+/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS. There is nothing */
+/* in here of use to end-users -- skip to the next section. */
/* ------------------------------------------------------------------ */
=20
-#ifdef NVALGRIND
+#if defined(NVALGRIND)
=20
/* Define NVALGRIND to completely remove the Valgrind magic sequence
- from the compiled code (analogous to NDEBUG's effects on assert()) */
-#define VALGRIND_MAGIC_SEQUENCE( \
- _zzq_rlval, _zzq_default, _zzq_request, =
\
- _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4) =
\
- { \
- (_zzq_rlval) =3D (_zzq_default); \
+ from the compiled code (analogous to NDEBUG's effects on
+ assert()) */
+#define VALGRIND_DO_CLIENT_REQUEST( \
+ _zzq_rlval, _zzq_default, _zzq_request, \
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4) \
+ { \
+ (_zzq_rlval) =3D (_zzq_default); \
}
=20
-#else /* NVALGRIND */
+#else /* ! NVALGRIND */
=20
-/* The following defines the magic code sequences which the JITter spots=
and
- handles magically. Don't look too closely at them; they will rot
- your brain. We must ensure that the default value gets put in the re=
turn
- slot, so that everything works when this is executed not under Valgri=
nd.
- Args are passed in a memory block, and so there's no intrinsic limit =
to
- the number that could be passed, but it's currently four.
+/* The following defines the magic code sequences which the JITter
+ spots and handles magically. Don't look too closely at them as
+ they will rot your brain.
+
+ The assembly code sequences for all architectures is in this one
+ file. This is because this file must be stand-alone, and we don't
+ want to have multiple files.
+
+ For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default
+ value gets put in the return slot, so that everything works when
+ this is executed not under Valgrind. Args are passed in a memory
+ block, and so there's no intrinsic limit to the number that could
+ be passed, but it's currently four.
=20
The macro args are:=20
_zzq_rlval result lvalue
@@ -120,126 +148,359 @@
_zzq_request request code
_zzq_arg1..4 request params
=20
- Nb: we put the assembly code sequences for all architectures in this =
one
- file. This is because this file must be stand-alone, and we don't wa=
nt
- to have multiple files.
+ The other two macros are used to support function wrapping, and are
+ a lot simpler. VALGRIND_GET_NRADDR returns the value of the
+ guest's NRADDR pseudo-register. VALGRIND_CALL_NOREDIR_* behaves
+ the same as the following on the guest, but guarantees that the
+ branch instruction will not be redirected: x86: call *%eax, amd64:
+ call *%rax, ppc32/ppc64: bctrl. VALGRIND_CALL_NOREDIR is just
+ text, not a complete inline asm, since it needs to be combined with
+ more magic inline asm stuff to be useful.
*/
=20
-#ifdef __x86_64__
-#define VALGRIND_MAGIC_SEQUENCE( \
- _zzq_rlval, _zzq_default, _zzq_request, \
- _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4) \
- \
- { volatile unsigned long long _zzq_args[5]; \
- _zzq_args[0] =3D (volatile unsigned long long)(_zzq_request); \
- _zzq_args[1] =3D (volatile unsigned long long)(_zzq_arg1); \
- _zzq_args[2] =3D (volatile unsigned long long)(_zzq_arg2); \
- _zzq_args[3] =3D (volatile unsigned long long)(_zzq_arg3); \
- _zzq_args[4] =3D (volatile unsigned long long)(_zzq_arg4); \
- __asm__ volatile("roll $29, %%eax ; roll $3, %%eax\n\t" \
- "rorl $27, %%eax ; rorl $5, %%eax\n\t" \
- "roll $13, %%eax ; roll $19, %%eax" \
- : "=3Dd" (_zzq_rlval) \
- : "a" (&_zzq_args[0]), "0" (_zzq_default) \
- : "cc", "memory" \
- ); \
+/* ---------------------------- x86 ---------------------------- */
+
+#if defined(ARCH_x86)
+#define VALGRIND_DO_CLIENT_REQUEST( \
+ _zzq_rlval, _zzq_default, _zzq_request, \
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4) \
+ { unsigned int _zzq_args[5]; \
+ _zzq_args[0] =3D (unsigned int)(_zzq_request); \
+ _zzq_args[1] =3D (unsigned int)(_zzq_arg1); \
+ _zzq_args[2] =3D (unsigned int)(_zzq_arg2); \
+ _zzq_args[3] =3D (unsigned int)(_zzq_arg3); \
+ _zzq_args[4] =3D (unsigned int)(_zzq_arg4); \
+ __asm__ volatile(/* "Special" instruction preamble */ \
+ "roll $3, %%edi ; roll $13, %%edi\n\t" \
+ "roll $29, %%edi ; roll $19, %%edi\n\t" \
+ /* %EDX =3D client_request ( %EAX ) */ \
+ "xchgl %%ebx,%%ebx" \
+ : "=3Dd" (_zzq_rlval) \
+ : "a" (&_zzq_args[0]), "0" (_zzq_default) \
+ : "cc", "memory" \
+ ); \
}
-#endif /* __x86_64__ */
=20
-#ifdef __i386__
-#define VALGRIND_MAGIC_SEQUENCE( \
- _zzq_rlval, _zzq_default, _zzq_request, \
- _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4) \
- \
- { unsigned int _zzq_args[5]; \
- _zzq_args[0] =3D (unsigned int)(_zzq_request); \
- _zzq_args[1] =3D (unsigned int)(_zzq_arg1); \
- _zzq_args[2] =3D (unsigned int)(_zzq_arg2); \
- _zzq_args[3] =3D (unsigned int)(_zzq_arg3); \
- _zzq_args[4] =3D (unsigned int)(_zzq_arg4); \
- __asm__ volatile("roll $29, %%eax ; roll $3, %%eax\n\t" \
- "rorl $27, %%eax ; rorl $5, %%eax\n\t" \
- "roll $13, %%eax ; roll $19, %%eax" \
- : "=3Dd" (_zzq_rlval) \
- : "a" (&_zzq_args[0]), "0" (_zzq_default) \
- : "cc", "memory" \
- ); \
+#define VALGRIND_GET_NRADDR(_zzq_rlval) \
+ { unsigned int __addr; \
+ __asm__ volatile("movl $0, %%eax\n\t" \
+ /* "Special" instruction preamble */ \
+ "roll $3, %%edi ; roll $13, %%edi\n\t" \
+ "roll $29, %%edi ; roll $19, %%edi\n\t" \
+ /* %EAX =3D guest_NRADDR */ \
+ "xchgl %%ecx,%%ecx" \
+ : "=3Da" (__addr) \
+ : \
+ : "cc", "memory" \
+ ); \
+ _zzq_rlval =3D (void*)__addr; \
}
-#endif /* __i386__ */
=20
-#if defined(__powerpc__) && !defined(__powerpc64__)
-#define VALGRIND_MAGIC_SEQUENCE( =
\
- _zzq_rlval, _zzq_default, _zzq_request, =
\
- _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4) =
\
- =
\
- { volatile unsigned int _zzq_args[5]; =
\
- register unsigned int _zzq_tmp __asm__("r3"); =
\
- register volatile unsigned int *_zzq_ptr __asm__("r4"); =
\
- _zzq_args[0] =3D (volatile unsigned int)(_zzq_request); =
\
- _zzq_args[1] =3D (volatile unsigned int)(_zzq_arg1); =
\
- _zzq_args[2] =3D (volatile unsigned int)(_zzq_arg2); =
\
- _zzq_args[3] =3D (volatile unsigned int)(_zzq_arg3); =
\
- _zzq_args[4] =3D (volatile unsigned int)(_zzq_arg4); =
\
- _zzq_ptr =3D _zzq_args; =
\
- __asm__ volatile("tw 0,3,27\n\t" =
\
- "rlwinm 0,0,29,0,0\n\t" =
\
- "rlwinm 0,0,3,0,0\n\t" =
\
- "rlwinm 0,0,13,0,0\n\t" =
\
- "rlwinm 0,0,19,0,0\n\t" =
\
- "nop\n\t" =
\
- : "=3Dr" (_zzq_tmp) =
\
- : "0" (_zzq_default), "r" (_zzq_ptr) =
\
- : "memory"); =
\
- _zzq_rlval =3D (__typeof__(_zzq_rlval)) _zzq_tmp; =
\
+#define VALGRIND_CALL_NOREDIR_EAX \
+ /* "Special" instruction preamble */ \
+ "roll $3, %%edi ; roll $13, %%edi\n\t" \
+ "roll $29, %%edi ; roll $19, %%edi\n\t" \
+ /* call-noredir *%EAX */ \
+ "xchgl %%edx,%%edx\n\t"
+#endif /* ARCH_x86 */
+
+/* --------------------------- amd64 --------------------------- */
+
+#if defined(ARCH_amd64)
+#define VALGRIND_DO_CLIENT_REQUEST( \
+ _zzq_rlval, _zzq_default, _zzq_request, \
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4) \
+ \
+ { volatile unsigned long long _zzq_args[5]; \
+ _zzq_args[0] =3D (volatile unsigned long long)(_zzq_request); \
+ _zzq_args[1] =3D (volatile unsigned long long)(_zzq_arg1); \
+ _zzq_args[2] =3D (volatile unsigned long long)(_zzq_arg2); \
+ _zzq_args[3] =3D (volatile unsigned long long)(_zzq_arg3); \
+ _zzq_args[4] =3D (volatile unsigned long long)(_zzq_arg4); \
+ __asm__ volatile("roll $29, %%eax ; roll $3, %%eax\n\t" \
+ "rorl $27, %%eax ; rorl $5, %%eax\n\t" \
+ "roll $13, %%eax ; roll $19, %%eax" \
+ : "=3Dd" (_zzq_rlval) \
+ : "a" (&_zzq_args[0]), "0" (_zzq_default) \
+ : "cc", "memory" \
+ ); \
}
-#endif /* __powerpc__ 32-bit only */
+#endif /* ARCH_amd64 */
=20
-#if defined(__powerpc__) && defined(__powerpc64__)
-#define VALGRIND_MAGIC_SEQUENCE( =
\
- _zzq_rlval, _zzq_default, _zzq_request, =
\
- _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4) =
\
- =
\
- { volatile unsigned long long int _zzq_args[5]; =
\
- register unsigned long long int _zzq_tmp __asm__("r3"); =
\
- register volatile unsigned long long int *_zzq_ptr __asm__("r4"); =
\
- _zzq_args[0] =3D (volatile unsigned long long int)(_zzq_request); =
\
- _zzq_args[1] =3D (volatile unsigned long long int)(_zzq_arg1); =
\
- _zzq_args[2] =3D (volatile unsigned long long int)(_zzq_arg2); =
\
- _zzq_args[3] =3D (volatile unsigned long long int)(_zzq_arg3); =
\
- _zzq_args[4] =3D (volatile unsigned long long int)(_zzq_arg4); =
\
- _zzq_ptr =3D _zzq_args; =
\
- __asm__ volatile("tw 0,3,27\n\t" =
\
- "rotldi 0,0,61\n\t" =
\
- "rotldi 0,0,3\n\t" =
\
- "rotldi 0,0,13\n\t" =
\
- "rotldi 0,0,51\n\t" =
\
- "nop\n\t" =
\
- : "=3Dr" (_zzq_tmp) =
\
- : "0" (_zzq_default), "r" (_zzq_ptr) =
\
- : "memory"); =
\
- _zzq_rlval =3D (__typeof__(_zzq_rlval)) _zzq_tmp; =
\
+/* --------------------------- ppc32 --------------------------- */
+
+#if defined(ARCH_ppc32)
+#define VALGRIND_DO_CLIENT_REQUEST( \
+ _zzq_rlval, _zzq_default, _zzq_request, \
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4) \
+ \
+ { volatile unsigned int _zzq_args[5]; \
+ register unsigned int _zzq_tmp __asm__("r3"); \
+ register volatile unsigned int *_zzq_ptr __asm__("r4"); \
+ _zzq_args[0] =3D (volatile unsigned int)(_zzq_request); \
+ _zzq_args[1] =3D (volatile unsigned int)(_zzq_arg1); \
+ _zzq_args[2] =3D (volatile unsigned int)(_zzq_arg2); \
+ _zzq_args[3] =3D (volatile unsigned int)(_zzq_arg3); \
+ _zzq_args[4] =3D (volatile unsigned int)(_zzq_arg4); \
+ _zzq_ptr =3D _zzq_args; \
+ __asm__ volatile("tw 0,3,27\n\t" \
+ "rlwinm 0,0,29,0,0\n\t" \
+ "rlwinm 0,0,3,0,0\n\t" \
+ "rlwinm 0,0,13,0,0\n\t" \
+ "rlwinm 0,0,19,0,0\n\t" \
+ "nop\n\t" \
+ : "=3Dr" (_zzq_tmp) \
+ : "0" (_zzq_default), "r" (_zzq_ptr) \
+ : "memory"); \
+ _zzq_rlval =3D (__typeof__(_zzq_rlval)) _zzq_tmp; \
}
-#endif /* __powerpc__ 64-bit only */
+#endif /* ARCH_ppc32 */
=20
+/* --------------------------- ppc64 --------------------------- */
+
+#if defined(ARCH_ppc64)
+#define VALGRIND_DO_CLIENT_REQUEST( \
+ _zzq_rlval, _zzq_default, _zzq_request, \
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4) \
+ \
+ { volatile unsigned long long int _zzq_args[5]; \
+ register unsigned long long int _zzq_tmp __asm__("r3"); \
+ register volatile unsigned long long int *_zzq_ptr __asm__("r4"); \
+ _zzq_args[0] =3D (volatile unsigned long long int)(_zzq_request); =
\
+ _zzq_args[1] =3D (volatile unsigned long long int)(_zzq_arg1); \
+ _zzq_args[2] =3D (volatile unsigned long long int)(_zzq_arg2); \
+ _zzq_args[3] =3D (volatile unsigned long long int)(_zzq_arg3); \
+ _zzq_args[4] =3D (volatile unsigned long long int)(_zzq_arg4); \
+ _zzq_ptr =3D _zzq_args; \
+ __asm__ volatile("tw 0,3,27\n\t" \
+ "rotldi 0,0,61\n\t" \
+ "rotldi 0,0,3\n\t" \
+ "rotldi 0,0,13\n\t" \
+ "rotldi 0,0,51\n\t" \
+ "nop\n\t" \
+ : "=3Dr" (_zzq_tmp) \
+ : "0" (_zzq_default), "r" (_zzq_ptr) \
+ : "memory"); \
+ _zzq_rlval =3D (__typeof__(_zzq_rlval)) _zzq_tmp; \
+ }
+#endif /* ARCH_ppc64 */
+
/* Insert assembly code for other architectures here... */
=20
#endif /* NVALGRIND */
=20
=20
/* ------------------------------------------------------------------ */
-/* The architecture-independent part */
+/* ARCHITECTURE SPECIFICS for FUNCTION WRAPPING. This is all very */
+/* ugly. It's the least-worst tradeoff I can think of. */
/* ------------------------------------------------------------------ */
=20
+/* This section defines magic (a.k.a appalling-hack) macros for doing
+ guaranteed-no-redirection macros, so as to get from function
+ wrappers to the functions they are wrapping. The whole point is to
+ construct standard call sequences, but to do the call itself with a
+ special no-redirect call pseudo-instruction that the JIT
+ understands and handles specially. This section is long and
+ repetitious, and I can't see a way to make it shorter.
+
+ The naming scheme is as follows:
+
+ CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,WWWWW,WWWWWW,etc}
+
+ 'W' stands for "word" and 'v' for "void". Hence there are
+ different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
+ and for each, the possibility of returning a word-typed result, or
+ no result.
+*/
+
+/* Use these to write the name of your wrapper. NOTE: duplicates
+ VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */
+
+#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \
+ _vgwZU_##soname##_##fnname
+
+#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \
+ _vgwZZ_##soname##_##fnname
+
+/* Use this macro from within a wrapper function to get the address of
+ the original function. Once you have that you can then use it in
+ one of the CALL_FN_ macros. */
+#define VALGRIND_GET_ORIG_FN(_lval) VALGRIND_GET_NRADDR(_lval)
+
+/* ---------------------------- x86 ---------------------------- */
+
+#if defined(ARCH_x86)
+
+/* These regs are trashed by the hidden call. No need to mention eax
+ as gcc can already see that, plus causes gcc to bomb. */
+#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx"
+
+#define CALL_FN_W_v(lval, fnptr) \
+ do { \
+ void* _fnptr =3D (fnptr); \
+ long _argvec[1]; \
+ long _res; \
+ _argvec[0] =3D (long)_fnptr; \
+ __asm__ volatile( \
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
+ VALGRIND_CALL_NOREDIR_EAX \
+ : /*out*/ "=3Da" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval =3D (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_v_v(fnptr) \
+ do { long _junk; CALL_FN_W_v(_junk,fnptr); } while (0)
+
+#define CALL_FN_W_W(lval, fnptr, arg1) \
+ do { \
+ void* _fnptr =3D (fnptr); \
+ long _argvec[2]; \
+ long _res; \
+ _argvec[0] =3D (long)_fnptr; \
+ _argvec[1] =3D (long)(arg1); \
+ __asm__ volatile( \
+ "pushl 4(%%eax)\n\t" \
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
+ VALGRIND_CALL_NOREDIR_EAX \
+ "addl $4, %%esp\n" \
+ : /*out*/ "=3Da" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval =3D (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WW(lval, fnptr, arg1,arg2) \
+ do { \
+ void* _fnptr =3D (fnptr); \
+ long _argvec[3]; \
+ long _res; \
+ _argvec[0] =3D (long)_fnptr; \
+ _argvec[1] =3D (long)(arg1); \
+ _argvec[2] =3D (long)(arg2); \
+ __asm__ volatile( \
+ "pushl 8(%%eax)\n\t" \
+ "pushl 4(%%eax)\n\t" \
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
+ VALGRIND_CALL_NOREDIR_EAX \
+ "addl $8, %%esp\n" \
+ : /*out*/ "=3Da" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval =3D (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WWWW(lval, fnptr, arg1,arg2,arg3,arg4) \
+ do { \
+ void* _fnptr =3D (fnptr); \
+ long _argvec[5]; \
+ long _res; \
+ _argvec[0] =3D (long)_fnptr; \
+ _argvec[1] =3D (long)(arg1); \
+ _argvec[2] =3D (long)(arg2); \
+ _argvec[3] =3D (long)(arg3); \
+ _argvec[4] =3D (long)(arg4); \
+ __asm__ volatile( \
+ "pushl 16(%%eax)\n\t" \
+ "pushl 12(%%eax)\n\t" \
+ "pushl 8(%%eax)\n\t" \
+ "pushl 4(%%eax)\n\t" \
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
+ VALGRIND_CALL_NOREDIR_EAX \
+ "addl $16, %%esp\n" \
+ : /*out*/ "=3Da" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval =3D (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WWWWW(lval, fnptr, arg1,arg2,arg3,arg4,arg5) \
+ do { \
+ void* _fnptr =3D (fnptr); \
+ long _argvec[6]; \
+ long _res; \
+ _argvec[0] =3D (long)_fnptr; \
+ _argvec[1] =3D (long)(arg1); \
+ _argvec[2] =3D (long)(arg2); \
+ _argvec[3] =3D (long)(arg3); \
+ _argvec[4] =3D (long)(arg4); \
+ _argvec[5] =3D (long)(arg5); \
+ __asm__ volatile( \
+ "pushl 20(%%eax)\n\t" \
+ "pushl 16(%%eax)\n\t" \
+ "pushl 12(%%eax)\n\t" \
+ "pushl 8(%%eax)\n\t" \
+ "pushl 4(%%eax)\n\t" \
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
+ VALGRIND_CALL_NOREDIR_EAX \
+ "addl $20, %%esp\n" \
+ : /*out*/ "=3Da" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval =3D (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WWWWWWW(lval, fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg=
7) \
+ do { \
+ void* _fnptr =3D (fnptr); \
+ long _argvec[8]; \
+ long _res; \
+ _argvec[0] =3D (long)_fnptr; \
+ _argvec[1] =3D (long)(arg1); \
+ _argvec[2] =3D (long)(arg2); \
+ _argvec[3] =3D (long)(arg3); \
+ _argvec[4] =3D (long)(arg4); \
+ _argvec[5] =3D (long)(arg5); \
+ _argvec[6] =3D (long)(arg6); \
+ _argvec[7] =3D (long)(arg7); \
+ __asm__ volatile( \
+ "pushl 28(%%eax)\n\t" \
+ "pushl 24(%%eax)\n\t" \
+ "pushl 20(%%eax)\n\t" \
+ "pushl 16(%%eax)\n\t" \
+ "pushl 12(%%eax)\n\t" \
+ "pushl 8(%%eax)\n\t" \
+ "pushl 4(%%eax)\n\t" \
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
+ VALGRIND_CALL_NOREDIR_EAX \
+ "addl $28, %%esp\n" \
+ : /*out*/ "=3Da" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval =3D (__typeof__(lval)) _res; \
+ } while (0)
+
+#endif /* ARCH_x86 */
+
+/* --------------------------- amd64 --------------------------- */
+
+/* --------------------------- ppc32 --------------------------- */
+
+/* --------------------------- ppc64 --------------------------- */
+
+
+/* ------------------------------------------------------------------ */
+/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS. */
+/* */
+/* ------------------------------------------------------------------ */
+
/* Some request codes. There are many more of these, but most are not
exposed to end-user view. These are the public ones, all of the
form 0x1000 + small_number.
=20
- Core ones are in the range 0x00000000--0x0000ffff. The non-public on=
es
- start at 0x2000.
+ Core ones are in the range 0x00000000--0x0000ffff. The non-public
+ ones start at 0x2000.
*/
=20
-/* These macros are used by tools -- they must be public, but don't embe=
d them
- * into other programs. */
+/* These macros are used by tools -- they must be public, but don't
+ embed them into other programs. */
#define VG_USERREQ_TOOL_BASE(a,b) \
((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
#define VG_IS_TOOL_USERREQ(a, b, v) \
@@ -248,24 +509,24 @@
typedef
enum { VG_USERREQ__RUNNING_ON_VALGRIND =3D 0x1001,
VG_USERREQ__DISCARD_TRANSLATIONS =3D 0x1002,
- VG_USERREQ__GET_NRADDR =3D 0x1003,
=20
- /* These allow any function to be called from the
- simulated CPU but run on the real CPU.
- Nb: the first arg passed to the function is always the Thre=
adId of
- the running thread! So CLIENT_CALL0 actually requires a 1 =
arg
+ /* These allow any function to be called from the simulated
+ CPU but run on the real CPU. Nb: the first arg passed to
+ the function is always the ThreadId of the running
+ thread! So CLIENT_CALL0 actually requires a 1 arg
function, etc. */
VG_USERREQ__CLIENT_CALL0 =3D 0x1101,
VG_USERREQ__CLIENT_CALL1 =3D 0x1102,
VG_USERREQ__CLIENT_CALL2 =3D 0x1103,
VG_USERREQ__CLIENT_CALL3 =3D 0x1104,
=20
- /* Can be useful in regression testing suites -- eg. can send
- Valgrind's output to /dev/null and still count errors. */
+ /* Can be useful in regression testing suites -- eg. can
+ send Valgrind's output to /dev/null and still count
+ errors. */
VG_USERREQ__COUNT_ERRORS =3D 0x1201,
=20
- /* These are useful and can be interpreted by any tool that tr=
acks
- malloc() et al, by using vg_replace_malloc.c. */
+ /* These are useful and can be interpreted by any tool that
+ tracks malloc() et al, by using vg_replace_malloc.c. */
VG_USERREQ__MALLOCLIKE_BLOCK =3D 0x1301,
VG_USERREQ__FREELIKE_BLOCK =3D 0x1302,
/* Memory pool support. */
@@ -284,19 +545,20 @@
VG_USERREQ__STACK_CHANGE =3D 0x1503,
} Vg_ClientRequest;
=20
-#ifndef __GNUC__
-#define __extension__
+#if !defined(__GNUC__)
+# define __extension__ /* */
#endif
=20
-/* Returns the number of Valgrinds this code is running under. That is,
- 0 if running natively, 1 if running under Valgrind, 2 if running unde=
r
- Valgrind which is running under another Valgrind, etc. */
-#define RUNNING_ON_VALGRIND __extension__ \
- ({unsigned int _qzz_res; \
- VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0 /* returned if not */, \
- VG_USERREQ__RUNNING_ON_VALGRIND, \
- 0, 0, 0, 0); \
- _qzz_res; \
+/* Returns the number of Valgrinds this code is running under. That
+ is, 0 if running natively, 1 if running under Valgrind, 2 if
+ running under Valgrind which is running under another Valgrind,
+ etc. */
+#define RUNNING_ON_VALGRIND __extension__ \
+ ({unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* if not */, \
+ VG_USERREQ__RUNNING_ON_VALGRIND, \
+ 0, 0, 0, 0); \
+ _qzz_res; \
})
=20
=20
@@ -304,30 +566,22 @@
_qzz_len - 1]. Useful if you are debugging a JITter or some such,
since it provides a way to make sure valgrind will retranslate the
invalidated area. Returns no value. */
-#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \
- {unsigned int _qzz_res; \
- VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \
- VG_USERREQ__DISCARD_TRANSLATIONS, \
- _qzz_addr, _qzz_len, 0, 0); \
+#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \
+ {unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__DISCARD_TRANSLATIONS, \
+ _qzz_addr, _qzz_len, 0, 0); \
}
=20
-/* 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_GET_NRADDR __extension__ \
- ({unsigned long _qzz_res; \
- VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0/*native result*/, \
- VG_USERREQ__GET_NRADDR, \
- 0, 0, 0, 0); \
- (void*)_qzz_res; \
- })
=20
-#ifdef NVALGRIND
+/* These requests are for getting Valgrind itself to print something.
+ Possibly with a backtrace. This is a really ugly hack. */
=20
-#define VALGRIND_PRINTF(...)
-#define VALGRIND_PRINTF_BACKTRACE(...)
+#if defined(NVALGRIND)
=20
+# define VALGRIND_PRINTF(...)
+# define VALGRIND_PRINTF_BACKTRACE(...)
+
#else /* NVALGRIND */
=20
int VALGRIND_PRINTF(const char *format, ...)
@@ -339,7 +593,7 @@
unsigned long _qzz_res;
va_list vargs;
va_start(vargs, format);
- VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, VG_USERREQ__PRINTF,
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF,
(unsigned long)format, (unsigned long)vargs, =
0, 0);
va_end(vargs);
return (int)_qzz_res;
@@ -354,7 +608,7 @@
unsigned long _qzz_res;
va_list vargs;
va_start(vargs, format);
- VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, VG_USERREQ__PRINTF_BACKTRACE,
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF_BACKTRACE,
(unsigned long)format, (unsigned long)vargs, =
0, 0);
va_end(vargs);
return (int)_qzz_res;
@@ -362,54 +616,55 @@
=20
#endif /* NVALGRIND */
=20
+
/* These requests allow control to move from the simulated CPU to the
real CPU, calling an arbitary function */
-#define VALGRIND_NON_SIMD_CALL0(_qyy_fn) \
- ({unsigned long _qyy_res; \
- VALGRIND_MAGIC_SEQUENCE(_qyy_res, 0 /* default return */, \
- VG_USERREQ__CLIENT_CALL0, \
- _qyy_fn, \
- 0, 0, 0); \
- _qyy_res; \
+#define VALGRIND_NON_SIMD_CALL0(_qyy_fn) \
+ ({unsigned long _qyy_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
+ VG_USERREQ__CLIENT_CALL0, \
+ _qyy_fn, \
+ 0, 0, 0); \
+ _qyy_res; \
})
=20
-#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \
- ({unsigned long _qyy_res; \
- VALGRIND_MAGIC_SEQUENCE(_qyy_res, 0 /* default return */, \
- VG_USERREQ__CLIENT_CALL1, \
- _qyy_fn, \
- _qyy_arg1, 0, 0); \
- _qyy_res; \
+#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \
+ ({unsigned long _qyy_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
+ VG_USERREQ__CLIENT_CALL1, \
+ _qyy_fn, \
+ _qyy_arg1, 0, 0); \
+ _qyy_res; \
})
=20
-#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \
- ({unsigned long _qyy_res; \
- VALGRIND_MAGIC_SEQUENCE(_qyy_res, 0 /* default return */, \
- VG_USERREQ__CLIENT_CALL2, \
- _qyy_fn, \
- _qyy_arg1, _qyy_arg2, 0); \
- _qyy_res; \
+#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \
+ ({unsigned long _qyy_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
+ VG_USERREQ__CLIENT_CALL2, \
+ _qyy_fn, \
+ _qyy_arg1, _qyy_arg2, 0); \
+ _qyy_res; \
})
=20
-#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3=
) \
- ({unsigned long _qyy_res; \
- VALGRIND_MAGIC_SEQUENCE(_qyy_res, 0 /* default return */, \
- VG_USERREQ__CLIENT_CALL3, \
- _qyy_fn, \
- _qyy_arg1, _qyy_arg2, _qyy_arg3); \
- _qyy_res; \
+#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3=
) \
+ ({unsigned long _qyy_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
+ VG_USERREQ__CLIENT_CALL3, \
+ _qyy_fn, \
+ _qyy_arg1, _qyy_arg2, _qyy_arg3); \
+ _qyy_res; \
})
=20
=20
/* Counts the number of errors that have been recorded by a tool. Nb:
the tool must record the errors with VG_(maybe_record_error)() or
VG_(unique_error)() for them to be counted. */
-#define VALGRIND_COUNT_ERRORS =
\
- ({unsigned int _qyy_res; =
\
- VALGRIND_MAGIC_SEQUENCE(_qyy_res, 0 /* default return */, =
\
- VG_USERREQ__COUNT_ERRORS, =
\
- 0, 0, 0, 0); =
\
- _qyy_res; =
\
+#define VALGRIND_COUNT_ERRORS \
+ ({unsigned int _qyy_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
+ VG_USERREQ__COUNT_ERRORS, \
+ 0, 0, 0, 0); \
+ _qyy_res; \
})
=20
/* Mark a block of memory as having been allocated by a malloc()-like
@@ -432,293 +687,86 @@
=20
Nb: block must be freed via a free()-like function specified
with VALGRIND_FREELIKE_BLOCK or mismatch errors will occur. */
-#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \
- {unsigned int _qzz_res; \
- VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \
- VG_USERREQ__MALLOCLIKE_BLOCK, \
- addr, sizeB, rzB, is_zeroed); \
+#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \
+ {unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__MALLOCLIKE_BLOCK, \
+ addr, sizeB, rzB, is_zeroed); \
}
=20
/* Mark a block of memory as having been freed by a free()-like function=
.
`rzB' is redzone size; it must match that given to
VALGRIND_MALLOCLIKE_BLOCK. Memory not freed will be detected by the =
leak
checker. Put it immediately after the point where the block is freed=
. */
-#define VALGRIND_FREELIKE_BLOCK(addr, rzB) \
- {unsigned int _qzz_res; \
- VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \
- VG_USERREQ__FREELIKE_BLOCK, \
- addr, rzB, 0, 0); \
+#define VALGRIND_FREELIKE_BLOCK(addr, rzB) \
+ {unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__FREELIKE_BLOCK, \
+ addr, rzB, 0, 0); \
}
=20
/* Create a memory pool. */
-#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \
- {unsigned int _qzz_res; \
- VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \
- VG_USERREQ__CREATE_MEMPOOL, \
- pool, rzB, is_zeroed, 0); \
+#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \
+ {unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__CREATE_MEMPOOL, \
+ pool, rzB, is_zeroed, 0); \
}
=20
/* Destroy a memory pool. */
-#define VALGRIND_DESTROY_MEMPOOL(pool) \
- {unsigned int _qzz_res; \
- VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \
- VG_USERREQ__DESTROY_MEMPOOL, \
- pool, 0, 0, 0); \
+#define VALGRIND_DESTROY_MEMPOOL(pool) \
+ {unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__DESTROY_MEMPOOL, \
+ pool, 0, 0, 0); \
}
=20
/* Associate a piece of memory with a memory pool. */
-#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \
- {unsigned int _qzz_res; \
- VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \
- VG_USERREQ__MEMPOOL_ALLOC, \
- pool, addr, size, 0); \
+#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \
+ {unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__MEMPOOL_ALLOC, \
+ pool, addr, size, 0); \
}
=20
/* Disassociate a piece of memory from a memory pool. */
-#define VALGRIND_MEMPOOL_FREE(pool, addr) \
- {unsigned int _qzz_res; \
- VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \
- VG_USERREQ__MEMPOOL_FREE, \
- pool, addr, 0, 0); \
+#define VALGRIND_MEMPOOL_FREE(pool, addr) \
+ {unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__MEMPOOL_FREE, \
+ pool, addr, 0, 0); \
}
=20
/* Mark a piece of memory as being a stack. Returns a stack id. */
-#define VALGRIND_STACK_REGISTER(start, end) \
- ({unsigned int _qzz_res; \
- VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \
- VG_USERREQ__STACK_REGISTER, \
- start, end, 0, 0); \
- _qzz_res; \
+#define VALGRIND_STACK_REGISTER(start, end) \
+ ({unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__STACK_REGISTER, \
+ start, end, 0, 0); \
+ _qzz_res; \
})
=20
/* Unmark the piece of memory associated with a stack id as being a
stack. */
-#define VALGRIND_STACK_DEREGISTER(id) \
- {unsigned int _qzz_res; \
- VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \
- VG_USERREQ__STACK_DEREGISTER, \
- id, 0, 0, 0); \
+#define VALGRIND_STACK_DEREGISTER(id) \
+ {unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__STACK_DEREGISTER, \
+ id, 0, 0, 0); \
}
=20
/* Change the start and end address of the stack id. */
-#define VALGRIND_STACK_CHANGE(id, start, end) \
- {unsigned int _qzz_res; \
- VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \
- VG_USERREQ__STACK_CHANGE, \
- id, start, end, 0); \
+#define VALGRIND_STACK_CHANGE(id, start, end) \
+ {unsigned int _qzz_res; \
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
+ VG_USERREQ__STACK_CHANGE, \
+ id, start, end, 0); \
}
=20
-/* ---------------------------------------------------------- */
-/* --- Hacky macros for writing function wrappers. --- */
-/* --- XXXXXXX DANGEROUS. DO NOT USE. XXXXXXXXXX --- */
-/* ---------------------------------------------------------- */
=20
-#define CALL_ORIG_FN_1_UNCHECKED(lval,fn,arg1) \
- do { \
- __typeof__(&(fn)) _fn =3D &(fn); \
- __typeof__(lval) _lval; \
- __typeof__(arg1) _arg1 =3D (arg1); \
- VALGRIND_PUSH_NRADDR_NO_CHECK(_fn); \
- _lval =3D (*_fn)(_arg1); \
- lval =3D _lval; \
- } while (0)
+#undef ARCH_x86
+#undef ARCH_amd64
+#undef ARCH_ppc32
+#undef ARCH_ppc64
=20
-#define CALL_ORIG_FN_4_UNCHECKED(lval,fn,arg1,arg2,arg3,arg4) \
- do { \
- __typeof__(&(fn)) _fn =3D &(fn); \
- __typeof__(lval) _lval; \
- __typeof__(arg1) _arg1 =3D (arg1); \
- __typeof__(arg2) _arg2 =3D (arg2); \
- __typeof__(arg3) _arg3 =3D (arg3); \
- __typeof__(arg4) _arg4 =3D (arg4); \
- VALGRIND_PUSH_NRADDR_NO_CHECK(_fn); \
- _lval =3D (*_fn)(_arg1,_arg2,_arg3,_arg4); \
- lval =3D _lval; \
- } while (0)
-
-/* ---------------------------------------------------------- */
-/* --- End-user functions for writing function wrappers. --- */
-/* ---------------------------------------------------------- */
-
-/* Use these to write the name of your wrapper. NOTE: duplicates
- VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */
-
-#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \
- _vgwZU_##soname##_##fnname
-
-#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \
- _vgwZZ_##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 a value, 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 =3...
[truncated message content] |
|
From: <sv...@va...> - 2005-12-28 00:55:08
|
Author: sewardj
Date: 2005-12-28 00:54:57 +0000 (Wed, 28 Dec 2005)
New Revision: 1518
Log:
x86 front end only: generalise the client-request idea so as to create
a whole family of "Special" instructions, which are no-ops when run
natively, but mean something special to the JIT.
Modified:
branches/FNWRAP/priv/guest-x86/toIR.c
Modified: branches/FNWRAP/priv/guest-x86/toIR.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/priv/guest-x86/toIR.c 2005-12-27 16:39:36 UTC (rev 15=
17)
+++ branches/FNWRAP/priv/guest-x86/toIR.c 2005-12-28 00:54:57 UTC (rev 15=
18)
@@ -122,6 +122,30 @@
way through bbs as usual.
*/
=20
+/* "Special" instructions.
+
+ This instruction decoder can decode three special instructions
+ which mean nothing natively (are no-ops as far as regs/mem are
+ concerned) but have meaning for supporting Valgrind. A special
+ instruction is flagged by the 12-byte preamble C1C703 C1C70D C1C71D
+ C1C713 (in the standard interpretation, that means: roll $3, %edi;
+ roll $13, %edi; roll $29, %edi; roll $19, %edi). Following that,
+ one of the following 3 are allowed (standard interpretation in
+ parentheses):
+
+ 87DB (xchgl %ebx,%ebx) %EDX =3D client_request ( %EAX )
+ 87C9 (xchgl %ecx,%ecx) %EAX =3D guest_NRADDR
+ 87D2 (xchgl %edx,%edx) call-noredir *%EAX
+
+ Any other bytes following the 12-byte preamble are illegal and
+ constitute a failure in instruction decoding. This all assumes
+ that the preamble will never occur except in specific code
+ fragments designed for Valgrind to catch.
+
+ No prefixes may precede a "Special" instruction.
+*/
+
+
/* Translates x86 code to IR. */
=20
#include "libvex_basictypes.h"
@@ -227,7 +251,9 @@
=20
#define OFFB_TISTART offsetof(VexGuestX86State,guest_TISTART)
#define OFFB_TILEN offsetof(VexGuestX86State,guest_TILEN)
+#define OFFB_NRADDR offsetof(VexGuestX86State,guest_NRADDR)
=20
+
/*------------------------------------------------------------*/
/*--- Helper bits and pieces for deconstructing the ---*/
/*--- x86 insn stream. ---*/
@@ -7005,68 +7031,58 @@
if (put_IP)
stmt( IRStmt_Put( OFFB_EIP, mkU32(guest_EIP_curr_instr)) );
=20
- /* Spot the client-request magic sequence. */
+ /* Spot "Special" instructions (see comment at top of file). */
{
UChar* code =3D (UChar*)(guest_code + delta);
- /* Spot this:
- C1C01D roll $29, %eax
- C1C003 roll $3, %eax
- C1C81B rorl $27, %eax
- C1C805 rorl $5, %eax
- C1C00D roll $13, %eax
- C1C013 roll $19, %eax =20
+ /* Spot the 12-byte preamble:
+ C1C703 roll $3, %edi
+ C1C70D roll $13, %edi
+ C1C71D roll $29, %edi
+ C1C713 roll $19, %edi
*/
- if (code[ 0] =3D=3D 0xC1 && code[ 1] =3D=3D 0xC0 && code[ 2] =3D=3D=
0x1D &&
- code[ 3] =3D=3D 0xC1 && code[ 4] =3D=3D 0xC0 && code[ 5] =3D=3D=
0x03 &&
- code[ 6] =3D=3D 0xC1 && code[ 7] =3D=3D 0xC8 && code[ 8] =3D=3D=
0x1B &&
- code[ 9] =3D=3D 0xC1 && code[10] =3D=3D 0xC8 && code[11] =3D=3D=
0x05 &&
- code[12] =3D=3D 0xC1 && code[13] =3D=3D 0xC0 && code[14] =3D=3D=
0x0D &&
- code[15] =3D=3D 0xC1 && code[16] =3D=3D 0xC0 && code[17] =3D=3D=
0x13
- ) {
- DIP("%%edx =3D client_request ( %%eax )\n"); =20
- delta +=3D 18;
- jmp_lit(Ijk_ClientReq, guest_EIP_bbstart+delta);
- dres.whatNext =3D Dis_StopHere;
- goto decode_success;
+ if (code[ 0] =3D=3D 0xC1 && code[ 1] =3D=3D 0xC7 && code[ 2] =3D=3D=
0x03 &&
+ code[ 3] =3D=3D 0xC1 && code[ 4] =3D=3D 0xC7 && code[ 5] =3D=3D=
0x0D &&
+ code[ 6] =3D=3D 0xC1 && code[ 7] =3D=3D 0xC7 && code[ 8] =3D=3D=
0x1D &&
+ code[ 9] =3D=3D 0xC1 && code[10] =3D=3D 0xC7 && code[11] =3D=3D=
0x13) {
+ /* Got a "Special" instruction preamble. Which one is it? */
+ if (code[12] =3D=3D 0x87 && code[13] =3D=3D 0xDB /* xchgl %ebx,=
%ebx */) {
+ /* %EDX =3D client_request ( %EAX ) */
+ DIP("%%edx =3D client_request ( %%eax )\n");
+ delta +=3D 14;
+ jmp_lit(Ijk_ClientReq, guest_EIP_bbstart+delta);
+ dres.whatNext =3D Dis_StopHere;
+ goto decode_success;
+ }
+ else
+ if (code[12] =3D=3D 0x87 && code[13] =3D=3D 0xC9 /* xchgl %ecx,=
%ecx */) {
+ /* %EAX =3D guest_NRADDR */
+ DIP("%%eax =3D guest_NRADDR\n");
+ delta +=3D 14;
+ putIReg(4, R_EAX, IRExpr_Get( OFFB_NRADDR, Ity_I32 ));
+ goto decode_success;
+ }
+ else
+ if (code[12] =3D=3D 0x87 && code[13] =3D=3D 0xD2 /* xchgl %edx,=
%edx */) {
+ /* call-noredir *%EAX */
+ DIP("call-noredir *%%eax\n");
+ delta +=3D 14;
+ t1 =3D newTemp(Ity_I32);
+ assign(t1, getIReg(4,R_EAX));
+ t2 =3D newTemp(Ity_I32);
+ assign(t2, binop(Iop_Sub32, getIReg(4,R_ESP), mkU32(4)));
+ putIReg(4, R_ESP, mkexpr(t2));
+ storeLE( mkexpr(t2), mkU32(guest_EIP_bbstart+delta));
+ jmp_treg(Ijk_NoRedir,t1);
+ dres.whatNext =3D Dis_StopHere;
+ goto decode_success;
+ }
+ /* We don't know what it is. */
+ goto decode_failure;
+ /*NOTREACHED*/
}
}
=20
- /* Spot the even-more-magical "call-noredir *%eax" sequence, and
- treat it as a normal "call *%eax", except that the jump itself
- is marked NoRedir. */
- {
- UChar* code =3D (UChar*)(guest_code + delta);
- /* Spot this:
- C1C81C rorl $28, %eax
- C1C804 rorl $4, %eax
- C1C01A roll $26, %eax
- C1C006 roll $6, %eax
- C1C80C rorl $12, %eax
- C1C814 rorl $20, %eax
- FFD0 call *%eax
- */
- if (code[ 0] =3D=3D 0xC1 && code[ 1] =3D=3D 0xC8 && code[ 2] =3D=3D=
0x1C &&
- code[ 3] =3D=3D 0xC1 && code[ 4] =3D=3D 0xC8 && code[ 5] =3D=3D=
0x04 &&
- code[ 6] =3D=3D 0xC1 && code[ 7] =3D=3D 0xC0 && code[ 8] =3D=3D=
0x1A &&
- code[ 9] =3D=3D 0xC1 && code[10] =3D=3D 0xC0 && code[11] =3D=3D=
0x06 &&
- code[12] =3D=3D 0xC1 && code[13] =3D=3D 0xC8 && code[14] =3D=3D=
0x0C &&
- code[15] =3D=3D 0xC1 && code[16] =3D=3D 0xC8 && code[17] =3D=3D=
0x14 &&
- code[18] =3D=3D 0xFF && code[19] =3D=3D 0xD0
- ) {
- DIP("call-noredir *%%eax\n");
- delta +=3D 20;
- t1 =3D newTemp(Ity_I32);
- assign(t1, getIReg(4,R_EAX));
- t2 =3D newTemp(Ity_I32);
- assign(t2, binop(Iop_Sub32, getIReg(4,R_ESP), mkU32(4)));
- putIReg(4, R_ESP, mkexpr(t2));
- storeLE( mkexpr(t2), mkU32(guest_EIP_bbstart+delta));
- jmp_treg(Ijk_NoRedir,t1);
- dres.whatNext =3D Dis_StopHere;
- goto decode_success;
- }
- }
-
+ /* Deal with prefixes. */
/* Skip a LOCK prefix. */
/* 2005 Jan 06: the following insns are observed to sometimes
have a LOCK prefix:
|