|
From: Jeremy F. <je...@go...> - 2003-11-19 17:44:47
|
On Wed, 2003-11-19 at 09:11, Dirk Mueller wrote: > It works when I use --assume-2.4=yes, but I don't consider this switch to be a > good idea. can't we detect whatever weird kernel feature we now need at > runtime? The intent is that the valgrind wrapper script use --assume-2.4=yes when it detects a SuSE kernel - I hadn't got around to it. Perhaps I should rename the option to --broken-suse-kernel=yes. J |
|
From: Nicholas N. <nj...@ca...> - 2003-11-19 20:07:06
|
On Wed, 19 Nov 2003, Jeremy Fitzhardinge wrote: > Perhaps I should rename the option to --broken-suse-kernel=yes. Much better, I find --assume-2.4 confusing. Or, to be consistent with --workaround-gcc296-bugs, --workaround-suse81-bugs (or whatever the version is)? N |
|
From: Dirk M. <dm...@gm...> - 2003-11-19 20:20:10
|
On Wednesday 19 November 2003 21:07, Nicholas Nethercote wrote: > Much better, I find --assume-2.4 confusing. Or, to be consistent with > --workaround-gcc296-bugs, --workaround-suse81-bugs (or whatever the > version is)? I agree, but can we first investigate if this is really a bug in the SuSE kernel? If I'd have a test app I could pass it to the kernel developers or verify it against the spec. I might try building one myself, just in case somebody has already done this work.. |
|
From: Dirk M. <mu...@kd...> - 2003-11-19 17:47:44
|
On Wednesday 19 November 2003 18:44, Jeremy Fitzhardinge wrote: > The intent is that the valgrind wrapper script use --assume-2.4=yes when > it detects a SuSE kernel - I hadn't got around to it. Perhaps I should > rename the option to --broken-suse-kernel=yes. Maybe you can elaborate in more detail what is broken? |
|
From: Jeremy F. <je...@go...> - 2003-11-19 18:44:45
|
On Wed, 2003-11-19 at 09:47, Dirk Mueller wrote: > On Wednesday 19 November 2003 18:44, Jeremy Fitzhardinge wrote: > > > The intent is that the valgrind wrapper script use --assume-2.4=yes when > > it detects a SuSE kernel - I hadn't got around to it. Perhaps I should > > rename the option to --broken-suse-kernel=yes. > > Maybe you can elaborate in more detail what is broken? V does a feature test to see if its running on a 2.6-like kernel, which is what it would prefer. SuSE passes those feature tests because they've extended their 2.4 kernel to include the new NPTL syscalls (like RH). Unfortunately they seem subtly broken, and even though the syscalls works and take the new args, they behave differently. The message you posted suggests that at least one proxy LWP just evaporated without notifying anyone of its death. On standard 2.4 kernels and RH 2.4 kernels it works OK without --assume-2.4=yes - it really is just for SuSE kernels (and perhaps other vendors with hacked up 2.4 kernels). J |
|
From: Dirk M. <mu...@kd...> - 2003-11-19 00:46:26
|
CVS commit by mueller:
raise sanity limit to pass coreutils testsuite
MERGE TO STABLE
M +2 -2 vg_main.c 1.123
--- valgrind/coregrind/vg_main.c #1.122:1.123
@@ -904,7 +904,7 @@ static void process_cmd_line_options ( v
sp --;
if (*sp == 0) break;
- if (++ctr >= 1000)
+ if (++ctr >= 2000)
args_grok_error(
- "suspiciously many (1000) env[] entries; giving up");
+ "suspiciously many (2000) env[] entries; giving up");
}
|
|
From: Dirk M. <mu...@kd...> - 2003-11-19 00:47:30
|
CVS commit by mueller:
be less verbose by default
M +4 -3 vg_symtab2.c 1.58
--- valgrind/coregrind/vg_symtab2.c #1.57:1.58
@@ -1184,4 +1184,5 @@ void VG_(unload_symbols) ( Addr start, U
}
+ if (VG_(clo_verbosity) > 1)
VG_(message)(Vg_UserMsg,
"discard syms in %s due to munmap()",
|
|
From: Dirk M. <mu...@kd...> - 2003-11-19 08:57:21
|
CVS commit by mueller:
make use of statfs64 and make code blocks adjacent
M +6 -6 vg_syscalls.c 1.58
--- valgrind/coregrind/vg_syscalls.c #1.57:1.58
@@ -4057,4 +4057,9 @@ PRE(statfs)
}
+POST(statfs)
+{
+ VG_TRACK( post_mem_write, arg2, sizeof(struct statfs) );
+}
+
PRE(statfs64)
{
@@ -4063,10 +4068,5 @@ PRE(statfs64)
SYSCALL_TRACK( pre_mem_read_asciiz, tid, "statfs64(path)", arg1 );
SYSCALL_TRACK( pre_mem_write, tid, "statfs64(buf)",
- arg2, sizeof(struct statfs) );
-}
-
-POST(statfs)
-{
- VG_TRACK( post_mem_write, arg2, sizeof(struct statfs) );
+ arg2, sizeof(struct statfs64) );
}
|
|
From: Dirk M. <mu...@kd...> - 2003-11-19 17:01:28
|
CVS commit by mueller:
add CVTPD2PS support, based on patch by Josef Weidendorfer
MERGE TO STABLE
M +8 -0 vg_to_ucode.c 1.108
--- valgrind/coregrind/vg_to_ucode.c #1.107:1.108
@@ -4761,4 +4761,12 @@ static Addr disInstr ( UCodeBlock* cb, A
}
+ /* CVTPD2PS -- convert two doubles to two floats. */
+ if (sz == 2 &&
+ insn[0] == 0x0F && insn[1] == 0x5A) {
+ eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, "cvtpd2ps",
+ 0x66, insn[0], insn[1] );
+ goto decode_success;
+ }
+
/* SQRTPD: square root of packed double. */
if (sz == 2
|
|
From: Dirk M. <mu...@kd...> - 2003-11-19 22:02:38
|
CVS commit by mueller:
SHUFPD support
MERGE TO STABLE
CCMAIL: 685...@bu...
M +7 -0 vg_to_ucode.c 1.109
--- valgrind/coregrind/vg_to_ucode.c #1.108:1.109
@@ -3927,4 +3927,11 @@ static Addr disInstr ( UCodeBlock* cb, A
}
+ /* SHUFPD */
+ if (sz == 2 && insn[0] == 0x0F && insn[1] == 0xC6) {
+ eip = dis_SSE3_reg_or_mem_Imm8 ( cb, sorb, eip+2, 16, "shufpd",
+ 0x66, insn[0], insn[1] );
+ goto decode_success;
+ }
+
/* SHUFPS */
if (insn[0] == 0x0F && insn[1] == 0xC6) {
|
|
From: Dirk M. <mu...@kd...> - 2003-11-19 22:07:17
|
CVS commit by mueller:
make it compile on non-C90 compilers. Thanks for the patch.
CCMAIL: 685...@bu...
M +5 -3 vg_symtab2.c 1.59
--- valgrind/coregrind/vg_symtab2.c #1.58:1.59
@@ -673,4 +673,6 @@ void read_symtab( SegInfo* si, Char* tab
Addr sym_addr;
RiSym risym;
+ Char* t0;
+ Char* name;
if (o_strtab == NULL || o_symtab == NULL) {
@@ -785,8 +787,8 @@ void read_symtab( SegInfo* si, Char* tab
/* If we reach here, it's an interesting symbol; record it. */
- Char* t0 = sym->st_name
+ t0 = sym->st_name
? (Char*)(o_strtab+sym->st_name)
: (Char*)"NONAME";
- Char *name = VG_(addStr) ( si, t0, -1 );
+ name = VG_(addStr) ( si, t0, -1 );
vg_assert(name != NULL
/* && 0==VG_(strcmp)(t0,&vg_strtab[nmoff]) */ );
|
|
From: Nicholas N. <nj...@ca...> - 2003-11-20 10:39:14
|
CVS commit by nethercote:
Printing usage message to stdout instead of stderr, which seems to be the
standard thing to do.
M +8 -5 vg_main.c 1.124
--- valgrind/coregrind/vg_main.c #1.123:1.124
@@ -536,7 +536,9 @@ Bool VG_(clo_demangle) = True;
Bool VG_(clo_trace_children) = False;
-/* See big comment in vg_include.h for meaning of these three. */
+/* See big comment in vg_include.h for meaning of these three.
+ fd is initially stdout, for --help, but gets moved to stderr by default
+ immediately afterwards. */
VgLogTo VG_(clo_log_to) = VgLogTo_Fd;
-Int VG_(clo_logfile_fd) = 2;
+Int VG_(clo_logfile_fd) = 1;
Char* VG_(clo_logfile_name) = NULL;
@@ -770,5 +772,6 @@ static void process_cmd_line_options ( v
# define ISSPACE(cc) ((cc) == ' ' || (cc) == '\t' || (cc) == '\n')
- eventually_logfile_fd = VG_(clo_logfile_fd);
+ /* log to stderr by default, but usage message goes to stdout */
+ eventually_logfile_fd = 2;
/* Once logging is started, we can safely send messages pertaining
@@ -1177,8 +1180,8 @@ static void process_cmd_line_options ( v
nature of it is. Oh the wonder of Unix streams. */
- /* So far we should be still attached to stderr, so we can show on
+ /* So far we should be still attached to stdout, so we can show on
the terminal any problems to do with processing command line
opts. */
- vg_assert(VG_(clo_logfile_fd) == 2 /* stderr */);
+ vg_assert(VG_(clo_logfile_fd) == 1 /* stdout */);
vg_assert(VG_(logging_to_filedes) == True);
|
|
From: Dirk M. <mu...@kd...> - 2003-11-20 20:46:24
|
CVS commit by mueller:
add prefetch(w) support - the 3dnow! version of it. doesn't hurt
supporting and its very easy.
MERGE TO STABLE
M +17 -6 vg_to_ucode.c 1.110
--- valgrind/coregrind/vg_to_ucode.c #1.109:1.110
@@ -6364,5 +6364,7 @@ static Addr disInstr ( UCodeBlock* cb, A
/* =-=-=-=-=-=-=-=-=- MMXery =-=-=-=-=-=-=-=-=-=-= */
+ case 0x0D: /* PREFETCH / PREFETCHW - 3Dnow!ery*/
case 0x18: /* PREFETCHT0/PREFETCHT1/PREFETCHT2/PREFETCHNTA */
+
vg_assert(sz == 4);
modrm = getUChar(eip);
@@ -6376,4 +6378,12 @@ static Addr disInstr ( UCodeBlock* cb, A
if (dis) {
UChar* hintstr;
+ if(opc == 0x0D) {
+ switch (gregOfRM(modrm)) {
+ case 0: hintstr = ""; break;
+ case 1: hintstr = "w"; break;
+ default: goto decode_failure;
+ }
+ }
+ else {
switch (gregOfRM(modrm)) {
case 0: hintstr = "nta"; break;
@@ -6382,4 +6392,5 @@ static Addr disInstr ( UCodeBlock* cb, A
case 3: hintstr = "t2"; break;
default: goto decode_failure;
+ }
}
VG_(printf)("prefetch%s ...\n", hintstr);
|
|
From: Dirk M. <mu...@kd...> - 2003-11-27 02:17:16
|
CVS commit by mueller:
test for PARENT_SETTID support in clone() of the kernel instead
of testing for presence of NPTL by assuming that sys_futex is only
implemented when its a NPTL patched kernel.
M +0 -2 vg_include.h 1.157
M +0 -9 vg_main.c 1.126
M +20 -21 vg_proxylwp.c 1.6
--- valgrind/coregrind/vg_include.h #1.156:1.157
@@ -244,6 +244,4 @@ extern Char* VG_(clo_weird_hacks);
signals. */
extern Int VG_(clo_signal_polltime);
-/* Assume we're running on a plain 2.4 kernel */
-extern Bool VG_(clo_assume_24);
/* Low latency syscalls and signals */
--- valgrind/coregrind/vg_main.c #1.125:1.126
@@ -570,7 +570,4 @@ static Bool VG_(clo_wait_for_gdb) =
Int VG_(clo_signal_polltime) = 50;
-/* If true, assume we're running on a plain 2.4 kernel */
-Bool VG_(clo_assume_24) = False;
-
/* These flags reduce thread wakeup latency on syscall completion and
signal delivery, respectively. The downside is possible unfairness. */
@@ -678,5 +675,4 @@ static void usage ( void )
" --lowlat-syscalls=no|yes improve wake-up latency when a thread's\n"
" syscall completes [no]\n"
-" --assume-2.4=no|yes assume we're running on a 2.4 kernel [no]\n"
"\n"
" %s tool user options:\n";
@@ -1126,9 +1122,4 @@ static void process_cmd_line_options ( v
else if (VG_CLO_STREQ(argv[i], "--lowlat-syscalls=no"))
VG_(clo_lowlat_syscalls) = False;
-
- else if (VG_CLO_STREQ(argv[i], "--assume-2.4=yes"))
- VG_(clo_assume_24) = True;
- else if (VG_CLO_STREQ(argv[i], "--assume-2.4=no"))
- VG_(clo_assume_24) = False;
else if (VG_CLO_STREQN(13, argv[i], "--stop-after="))
--- valgrind/coregrind/vg_proxylwp.c #1.5:1.6
@@ -883,5 +883,5 @@ static Int do_futex(void *addr, Int op,
#define VKI_FUTEX_REQUEUE 3
-static Int have_futex = -1; /* -1 -> unknown */
+static Int have_settid = -1; /* -1 -> unknown */
/*
@@ -895,19 +895,15 @@ static Int proxy_clone(ProxyLWP *proxy)
Int ret;
- if (VG_(clo_assume_24))
- have_futex = 0;
-
- if (have_futex == -1)
- have_futex = do_futex(NULL, VKI_FUTEX_WAKE, 0, NULL, NULL) != -VKI_ENOSYS;
-
- if (have_futex) {
+ if (have_settid != 0) {
ret = VG_(clone)(proxylwp,
LWP_stack(proxy),
VKI_CLONE_FS | VKI_CLONE_FILES | VKI_CLONE_VM |
- VKI_CLONE_SIGHAND | VKI_CLONE_THREAD |
- VKI_CLONE_PARENT_SETTID |
- VKI_CLONE_CHILD_CLEARTID | VKI_CLONE_DETACHED,
+ VKI_CLONE_SIGHAND | VKI_CLONE_THREAD /*|
+ VKI_CLONE_PARENT_SETTID
+ VKI_CLONE_CHILD_CLEARTID | VKI_CLONE_DETACHED*/,
proxy, &proxy->lwp, &proxy->lwp);
- } else {
+ if ( have_settid < 0 && !proxy->lwp ) {
+ have_settid = 0;
+ proxy->lwp = ret;
VG_(do_signal_routing) = True; /* XXX True, it seems kernels
which have futex also have
@@ -915,5 +911,6 @@ static Int proxy_clone(ProxyLWP *proxy)
it would be nice to test it
directly. */
-
+ }
+ } else {
ret = VG_(clone)(proxylwp,
LWP_stack(proxy),
@@ -932,12 +929,12 @@ static Bool proxy_wait(ProxyLWP *proxy,
Bool ret = False;
- if (have_futex == -1)
+ if (have_settid == -1)
return False;
- if (have_futex) {
+ if (have_settid) {
if (block) {
Int lwp = proxy->lwp;
- while(proxy->lwp != 0)
+ if(proxy->lwp != 0)
do_futex(&proxy->lwp, VKI_FUTEX_WAIT, lwp, NULL, NULL);
@@ -985,4 +982,6 @@ void VG_(proxy_create)(ThreadId tid)
proxy->tid = tid;
proxy->tst = tst;
+ proxy->exitcode = 0;
+ proxy->lwp = 0;
proxy->siginfo.si_signo = 0;
proxy->frommain = VG_(safe_fd)(p[0]);
@@ -1313,5 +1312,5 @@ void VG_(proxy_sanity)(void)
ThreadState *tst = &VG_(threads)[tid];
ProxyLWP *px;
- Int status;
+ Int status = 0;
Int ret;
|
|
From: Jeremy F. <je...@go...> - 2003-11-27 08:11:49
|
CVS commit by fitzhardinge:
Fix up the have_settid test so it works on both plain 2.4 and 2.6 kernels.
I think this will also work on SuSE kernels.
M +26 -12 vg_proxylwp.c 1.7
--- valgrind/coregrind/vg_proxylwp.c #1.6:1.7
@@ -893,5 +893,7 @@ static Int have_settid = -1; /* -1 -> un
static Int proxy_clone(ProxyLWP *proxy)
{
- Int ret;
+ Int ret = -1;
+
+ proxy->lwp = -1;
if (have_settid != 0) {
@@ -899,18 +901,30 @@ static Int proxy_clone(ProxyLWP *proxy)
LWP_stack(proxy),
VKI_CLONE_FS | VKI_CLONE_FILES | VKI_CLONE_VM |
- VKI_CLONE_SIGHAND | VKI_CLONE_THREAD /*|
- VKI_CLONE_PARENT_SETTID
- VKI_CLONE_CHILD_CLEARTID | VKI_CLONE_DETACHED*/,
+ VKI_CLONE_SIGHAND | VKI_CLONE_THREAD |
+ VKI_CLONE_PARENT_SETTID |
+ VKI_CLONE_CHILD_CLEARTID | VKI_CLONE_DETACHED,
proxy, &proxy->lwp, &proxy->lwp);
- if ( have_settid < 0 && !proxy->lwp ) {
+
+ if ( have_settid == -1 && (ret < 0 || proxy->lwp == 0) ) {
have_settid = 0;
+
+ /* Assume that not having parent_settid also means that we've
+ got 2.4-style signal handling, which means we need to do
+ more work. */
+ VG_(do_signal_routing) = True;
+
+ if (ret > 0) {
+ /* If clone actually succeeded and just ignored the
+ CLONE_PARENT_SETTID flag, then use the LWP it created
+ for us. */
proxy->lwp = ret;
- VG_(do_signal_routing) = True; /* XXX True, it seems kernels
- which have futex also have
- sensible signal handling, but
- it would be nice to test it
- directly. */
}
- } else {
+ }
+ }
+
+ if (ret < 0) {
+ vg_assert(have_settid == 0);
+ vg_assert(proxy->lwp == -1);
+
ret = VG_(clone)(proxylwp,
LWP_stack(proxy),
|
|
From: Dirk M. <mu...@kd...> - 2003-11-27 09:08:21
|
CVS commit by mueller:
reverting last commit, which broke all of valgrind.
M +4 -3 vg_proxylwp.c 1.8
--- valgrind/coregrind/vg_proxylwp.c #1.7:1.8
@@ -895,6 +895,4 @@ static Int proxy_clone(ProxyLWP *proxy)
Int ret = -1;
- proxy->lwp = -1;
-
if (have_settid != 0) {
ret = VG_(clone)(proxylwp,
@@ -921,9 +919,11 @@ static Int proxy_clone(ProxyLWP *proxy)
}
}
+ else
+ have_settid = 1;
}
if (ret < 0) {
vg_assert(have_settid == 0);
- vg_assert(proxy->lwp == -1);
+ vg_assert(proxy->lwp == 0);
ret = VG_(clone)(proxylwp,
|
|
From: Nicholas N. <nj...@ca...> - 2003-11-27 09:36:22
|
On Thu, 27 Nov 2003, Dirk Mueller wrote: > CVS commit by mueller: > > reverting last commit, which broke all of valgrind. Once you guys have worked this out (the current HEAD looks ok on my RH9/2.4.19 box, BTW), can one of you please remove references to the --assume-2.4 option from the docs? Thanks. N |
|
From: Nicholas N. <nj...@ca...> - 2003-11-27 09:30:58
|
CVS commit by nethercote: Fix comment M +1 -1 vg_to_ucode.c 1.111 --- valgrind/coregrind/vg_to_ucode.c #1.110:1.111 @@ -2209,5 +2209,5 @@ void codegen_LODS ( UCodeBlock* cb, Int -/* Template for REPNE SCAS<sz>, _not_ preceded by a REP prefix. */ +/* Template for SCAS<sz>, _not_ preceded by a REP prefix. */ static void codegen_SCAS ( UCodeBlock* cb, Int sz ) |
|
From: Nicholas N. <nj...@ca...> - 2003-11-27 16:15:58
|
CVS commit by nethercote:
Fixed up REP-prefix handling majorly. Factored out *lots* of repetitive code,
so much so that the file is now 280 lines shorter. This despite me also adding
support for LOOP{E,NE} (thanks to Abhijit Menon-Sen). Also added support for
CMPS[lw], which was missing. Adding more REP-prefix instructions in the future
will now be much easier.
As part of this, I moved the D-flag fetch outside of the REP loops. This might
make programs that use REP prefixes a lot go faster.
M +139 -415 vg_to_ucode.c 1.112
--- valgrind/coregrind/vg_to_ucode.c #1.111:1.112
@@ -1807,182 +1807,55 @@ Addr dis_Grp5 ( UCodeBlock* cb,
}
-
-/* Template for REPE CMPS<sz>. Assumes this insn is the last one in
- the basic block, and so emits a jump to the next insn. */
-static
-void codegen_REPE_CMPS ( UCodeBlock* cb, Int sz, Addr eip, Addr eip_next )
+static __inline__
+void dis_JMP_d32( UCodeBlock* cb, Addr d32 )
{
- Int tc, /* ECX */
- td, /* EDI */ ts, /* ESI */
- tdv, /* (EDI) */ tsv /* (ESI) */;
-
- tdv = newTemp(cb);
- tsv = newTemp(cb);
- td = newTemp(cb);
- ts = newTemp(cb);
- tc = newTemp(cb);
-
- uInstr2(cb, GET, 4, ArchReg, R_ECX, TempReg, tc);
- uInstr2(cb, JIFZ, 4, TempReg, tc, Literal, 0);
- uLiteral(cb, eip_next);
- uInstr1(cb, DEC, 4, TempReg, tc);
- uInstr2(cb, PUT, 4, TempReg, tc, ArchReg, R_ECX);
-
- uInstr2(cb, GET, 4, ArchReg, R_EDI, TempReg, td);
- uInstr2(cb, GET, 4, ArchReg, R_ESI, TempReg, ts);
-
- uInstr2(cb, LOAD, sz, TempReg, td, TempReg, tdv);
- uInstr2(cb, LOAD, sz, TempReg, ts, TempReg, tsv);
-
- uInstr2(cb, SUB, sz, TempReg, tdv, TempReg, tsv);
- setFlagsFromUOpcode(cb, SUB);
-
- uInstr0(cb, CALLM_S, 0);
- uInstr2(cb, MOV, 4, Literal, 0, TempReg, tdv);
- uLiteral(cb, 0);
- uInstr1(cb, PUSH, 4, TempReg, tdv);
-
- uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_get_dirflag));
- uFlagsRWU(cb, FlagD, FlagsEmpty, FlagsEmpty);
-
- uInstr1(cb, POP, 4, TempReg, tdv);
- uInstr0(cb, CALLM_E, 0);
- if (sz == 4 || sz == 2) {
- uInstr2(cb, SHL, 4, Literal, 0, TempReg, tdv);
- uLiteral(cb, sz/2);
- }
- uInstr2(cb, ADD, 4, TempReg, tdv, TempReg, td);
- uInstr2(cb, ADD, 4, TempReg, tdv, TempReg, ts);
-
- uInstr2(cb, PUT, 4, TempReg, td, ArchReg, R_EDI);
- uInstr2(cb, PUT, 4, TempReg, ts, ArchReg, R_ESI);
-
- uInstr1(cb, JMP, 0, Literal, 0);
- uLiteral(cb, eip);
- uCond(cb, CondZ);
- uFlagsRWU(cb, FlagsOSZACP, FlagsEmpty, FlagsEmpty);
uInstr1(cb, JMP, 0, Literal, 0);
- uLiteral(cb, eip_next);
+ uLiteral(cb, d32);
uCond(cb, CondAlways);
}
+/*------------------------------------------------------------*/
+/*--- Disassembling string ops (including REP prefixes) ---*/
+/*------------------------------------------------------------*/
-/* Template for REPNE SCAS<sz>. Assumes this insn is the last one in
- the basic block, and so emits a jump to the next insn. */
+/* Code shared by all the string ops */
static
-void codegen_REPNE_SCAS ( UCodeBlock* cb, Int sz, Addr eip, Addr eip_next )
+void dis_string_op_increment(UCodeBlock* cb, Int sz, Int t_inc)
{
- Int ta /* EAX */, tc /* ECX */, td /* EDI */, tv;
- ta = newTemp(cb);
- tc = newTemp(cb);
- tv = newTemp(cb);
- td = newTemp(cb);
-
- uInstr2(cb, GET, 4, ArchReg, R_ECX, TempReg, tc);
- uInstr2(cb, JIFZ, 4, TempReg, tc, Literal, 0);
- uLiteral(cb, eip_next);
- uInstr1(cb, DEC, 4, TempReg, tc);
- uInstr2(cb, PUT, 4, TempReg, tc, ArchReg, R_ECX);
-
- uInstr2(cb, GET, sz, ArchReg, R_EAX, TempReg, ta);
- uInstr2(cb, GET, 4, ArchReg, R_EDI, TempReg, td);
- uInstr2(cb, LOAD, sz, TempReg, td, TempReg, tv);
- /* next uinstr kills ta, but that's ok -- don't need it again */
- uInstr2(cb, SUB, sz, TempReg, tv, TempReg, ta);
- setFlagsFromUOpcode(cb, SUB);
-
- uInstr0(cb, CALLM_S, 0);
- uInstr2(cb, MOV, 4, Literal, 0, TempReg, tv);
+ uInstr0 (cb, CALLM_S, 0);
+ uInstr2 (cb, MOV, 4, Literal, 0, TempReg, t_inc);
uLiteral(cb, 0);
- uInstr1(cb, PUSH, 4, TempReg, tv);
+ uInstr1 (cb, PUSH, 4, TempReg, t_inc);
- uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_get_dirflag));
+ uInstr1 (cb, CALLM, 0, Lit16, VGOFF_(helper_get_dirflag));
uFlagsRWU(cb, FlagD, FlagsEmpty, FlagsEmpty);
- uInstr1(cb, POP, 4, TempReg, tv);
+ uInstr1(cb, POP, 4, TempReg, t_inc);
uInstr0(cb, CALLM_E, 0);
if (sz == 4 || sz == 2) {
- uInstr2(cb, SHL, 4, Literal, 0, TempReg, tv);
+ uInstr2(cb, SHL, 4, Literal, 0, TempReg, t_inc);
uLiteral(cb, sz/2);
}
- uInstr2(cb, ADD, 4, TempReg, tv, TempReg, td);
- uInstr2(cb, PUT, 4, TempReg, td, ArchReg, R_EDI);
- uInstr1(cb, JMP, 0, Literal, 0);
- uLiteral(cb, eip);
- uCond(cb, CondNZ);
- uFlagsRWU(cb, FlagsOSZACP, FlagsEmpty, FlagsEmpty);
- uInstr1(cb, JMP, 0, Literal, 0);
- uLiteral(cb, eip_next);
- uCond(cb, CondAlways);
}
-/* Template for REPE SCAS<sz>. Assumes this insn is the last one in
- the basic block, and so emits a jump to the next insn. */
static
-void codegen_REPE_SCAS ( UCodeBlock* cb, Int sz, Addr eip, Addr eip_next )
+void dis_string_op( UCodeBlock* cb, void (*dis_OP)( UCodeBlock*, Int, Int ),
+ Int sz, Char* name, UChar sorb )
{
- Int ta /* EAX */, tc /* ECX */, td /* EDI */, tv;
- ta = newTemp(cb);
- tc = newTemp(cb);
- tv = newTemp(cb);
- td = newTemp(cb);
-
- uInstr2(cb, GET, 4, ArchReg, R_ECX, TempReg, tc);
- uInstr2(cb, JIFZ, 4, TempReg, tc, Literal, 0);
- uLiteral(cb, eip_next);
- uInstr1(cb, DEC, 4, TempReg, tc);
- uInstr2(cb, PUT, 4, TempReg, tc, ArchReg, R_ECX);
-
- uInstr2(cb, GET, sz, ArchReg, R_EAX, TempReg, ta);
- uInstr2(cb, GET, 4, ArchReg, R_EDI, TempReg, td);
- uInstr2(cb, LOAD, sz, TempReg, td, TempReg, tv);
- /* next uinstr kills ta, but that's ok -- don't need it again */
- uInstr2(cb, SUB, sz, TempReg, tv, TempReg, ta);
- setFlagsFromUOpcode(cb, SUB);
-
- uInstr0(cb, CALLM_S, 0);
- uInstr2(cb, MOV, 4, Literal, 0, TempReg, tv);
- uLiteral(cb, 0);
- uInstr1(cb, PUSH, 4, TempReg, tv);
-
- uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_get_dirflag));
- uFlagsRWU(cb, FlagD, FlagsEmpty, FlagsEmpty);
-
- uInstr1(cb, POP, 4, TempReg, tv);
- uInstr0(cb, CALLM_E, 0);
-
- if (sz == 4 || sz == 2) {
- uInstr2(cb, SHL, 4, Literal, 0, TempReg, tv);
- uLiteral(cb, sz/2);
- }
- uInstr2(cb, ADD, 4, TempReg, tv, TempReg, td);
- uInstr2(cb, PUT, 4, TempReg, td, ArchReg, R_EDI);
- uInstr1(cb, JMP, 0, Literal, 0);
- uLiteral(cb, eip);
- uCond(cb, CondZ);
- uFlagsRWU(cb, FlagsOSZACP, FlagsEmpty, FlagsEmpty);
- uInstr1(cb, JMP, 0, Literal, 0);
- uLiteral(cb, eip_next);
- uCond(cb, CondAlways);
+ Int t_inc = newTemp(cb);
+ vg_assert(sorb == 0);
+ dis_string_op_increment(cb, sz, t_inc);
+ dis_OP( cb, sz, t_inc );
+ if (dis) VG_(printf)("%s%c\n", name, nameISize(sz));
}
-/* Template for REPE MOVS<sz>. Assumes this insn is the last one in
- the basic block, and so emits a jump to the next insn. */
static
-void codegen_REPE_MOVS ( UCodeBlock* cb, Int sz, Addr eip, Addr eip_next )
+void dis_MOVS ( UCodeBlock* cb, Int sz, Int t_inc )
{
- Int ts /* ESI */, tc /* ECX */, td /* EDI */, tv;
- tc = newTemp(cb);
- td = newTemp(cb);
- ts = newTemp(cb);
- tv = newTemp(cb);
-
- uInstr2(cb, GET, 4, ArchReg, R_ECX, TempReg, tc);
- uInstr2(cb, JIFZ, 4, TempReg, tc, Literal, 0);
- uLiteral(cb, eip_next);
- uInstr1(cb, DEC, 4, TempReg, tc);
- uInstr2(cb, PUT, 4, TempReg, tc, ArchReg, R_ECX);
+ Int tv = newTemp(cb); /* value being copied */
+ Int td = newTemp(cb); /* EDI */
+ Int ts = newTemp(cb); /* ESI */
uInstr2(cb, GET, 4, ArchReg, R_EDI, TempReg, td);
@@ -1990,48 +1863,32 @@ void codegen_REPE_MOVS ( UCodeBlock* cb,
uInstr2(cb, LOAD, sz, TempReg, ts, TempReg, tv);
- uInstr2(cb, STORE, sz, TempReg, tv, TempReg, td);
+ uInstr2(cb, STORE,sz, TempReg, tv, TempReg, td);
- uInstr0(cb, CALLM_S, 0);
- uInstr2(cb, MOV, 4, Literal, 0, TempReg, tv);
- uLiteral(cb, 0);
- uInstr1(cb, PUSH, 4, TempReg, tv);
+ uInstr2(cb, ADD, 4, TempReg, t_inc, TempReg, td);
+ uInstr2(cb, ADD, 4, TempReg, t_inc, TempReg, ts);
- uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_get_dirflag));
- uFlagsRWU(cb, FlagD, FlagsEmpty, FlagsEmpty);
+ uInstr2(cb, PUT, 4, TempReg, td, ArchReg, R_EDI);
+ uInstr2(cb, PUT, 4, TempReg, ts, ArchReg, R_ESI);
+}
- uInstr1(cb, POP, 4, TempReg, tv);
- uInstr0(cb, CALLM_E, 0);
+static
+void dis_LODS ( UCodeBlock* cb, Int sz, Int t_inc )
+{
+ Int ta = newTemp(cb); /* EAX */
+ Int ts = newTemp(cb); /* ESI */
- if (sz == 4 || sz == 2) {
- uInstr2(cb, SHL, 4, Literal, 0, TempReg, tv);
- uLiteral(cb, sz/2);
- }
- uInstr2(cb, ADD, 4, TempReg, tv, TempReg, td);
- uInstr2(cb, ADD, 4, TempReg, tv, TempReg, ts);
+ uInstr2(cb, GET, 4, ArchReg, R_ESI, TempReg, ts);
+ uInstr2(cb, LOAD, sz, TempReg, ts, TempReg, ta);
+ uInstr2(cb, PUT, sz, TempReg, ta, ArchReg, R_EAX);
- uInstr2(cb, PUT, 4, TempReg, td, ArchReg, R_EDI);
+ uInstr2(cb, ADD, 4, TempReg, t_inc, TempReg, ts);
uInstr2(cb, PUT, 4, TempReg, ts, ArchReg, R_ESI);
-
- uInstr1(cb, JMP, 0, Literal, 0);
- uLiteral(cb, eip);
- uCond(cb, CondAlways);
}
-
-/* Template for REPE STOS<sz>. Assumes this insn is the last one in
- the basic block, and so emits a jump to the next insn. */
static
-void codegen_REPE_STOS ( UCodeBlock* cb, Int sz, Addr eip, Addr eip_next )
+void dis_STOS ( UCodeBlock* cb, Int sz, Int t_inc )
{
- Int ta /* EAX */, tc /* ECX */, td /* EDI */;
- ta = newTemp(cb);
- tc = newTemp(cb);
- td = newTemp(cb);
-
- uInstr2(cb, GET, 4, ArchReg, R_ECX, TempReg, tc);
- uInstr2(cb, JIFZ, 4, TempReg, tc, Literal, 0);
- uLiteral(cb, eip_next);
- uInstr1(cb, DEC, 4, TempReg, tc);
- uInstr2(cb, PUT, 4, TempReg, tc, ArchReg, R_ECX);
+ Int ta = newTemp(cb); /* EAX */
+ Int td = newTemp(cb); /* EDI */
uInstr2(cb, GET, sz, ArchReg, R_EAX, TempReg, ta);
@@ -2039,38 +1896,15 @@ void codegen_REPE_STOS ( UCodeBlock* cb,
uInstr2(cb, STORE, sz, TempReg, ta, TempReg, td);
- uInstr0(cb, CALLM_S, 0);
- uInstr2(cb, MOV, 4, Literal, 0, TempReg, ta);
- uLiteral(cb, 0);
- uInstr1(cb, PUSH, 4, TempReg, ta);
-
- uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_get_dirflag));
- uFlagsRWU(cb, FlagD, FlagsEmpty, FlagsEmpty);
-
- uInstr1(cb, POP, 4, TempReg, ta);
- uInstr0(cb, CALLM_E, 0);
-
- if (sz == 4 || sz == 2) {
- uInstr2(cb, SHL, 4, Literal, 0, TempReg, ta);
- uLiteral(cb, sz/2);
- }
- uInstr2(cb, ADD, 4, TempReg, ta, TempReg, td);
+ uInstr2(cb, ADD, 4, TempReg, t_inc, TempReg, td);
uInstr2(cb, PUT, 4, TempReg, td, ArchReg, R_EDI);
-
- uInstr1(cb, JMP, 0, Literal, 0);
- uLiteral(cb, eip);
- uCond(cb, CondAlways);
}
-
-/* Template for CMPS<sz>, _not_ preceded by a REP prefix. */
static
-void codegen_CMPS ( UCodeBlock* cb, Int sz )
+void dis_CMPS ( UCodeBlock* cb, Int sz, Int t_inc )
{
- Int td, /* EDI */ ts, /* ESI */
- tdv, /* (EDI) */ tsv /* (ESI) */;
- tdv = newTemp(cb);
- tsv = newTemp(cb);
- td = newTemp(cb);
- ts = newTemp(cb);
+ Int tdv = newTemp(cb); /* (EDI) */
+ Int tsv = newTemp(cb); /* (ESI) */
+ Int td = newTemp(cb); /* EDI */
+ Int ts = newTemp(cb); /* ESI */
uInstr2(cb, GET, 4, ArchReg, R_EDI, TempReg, td);
@@ -2083,60 +1917,6 @@ void codegen_CMPS ( UCodeBlock* cb, Int
setFlagsFromUOpcode(cb, SUB);
- uInstr0(cb, CALLM_S, 0);
- uInstr2(cb, MOV, 4, Literal, 0, TempReg, tdv);
- uLiteral(cb, 0);
- uInstr1(cb, PUSH, 4, TempReg, tdv);
-
- uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_get_dirflag));
- uFlagsRWU(cb, FlagD, FlagsEmpty, FlagsEmpty);
-
- uInstr1(cb, POP, 4, TempReg, tdv);
- uInstr0(cb, CALLM_E, 0);
-
- if (sz == 4 || sz == 2) {
- uInstr2(cb, SHL, 4, Literal, 0, TempReg, tdv);
- uLiteral(cb, sz/2);
- }
- uInstr2(cb, ADD, 4, TempReg, tdv, TempReg, td);
- uInstr2(cb, ADD, 4, TempReg, tdv, TempReg, ts);
-
- uInstr2(cb, PUT, 4, TempReg, td, ArchReg, R_EDI);
- uInstr2(cb, PUT, 4, TempReg, ts, ArchReg, R_ESI);
-}
-
-
-/* Template for MOVS<sz>, _not_ preceded by a REP prefix. */
-static
-void codegen_MOVS ( UCodeBlock* cb, Int sz )
-{
- Int tv, /* the value being copied */
- td, /* EDI */ ts /* ESI */;
- tv = newTemp(cb);
- td = newTemp(cb);
- ts = newTemp(cb);
-
- uInstr2(cb, GET, 4, ArchReg, R_EDI, TempReg, td);
- uInstr2(cb, GET, 4, ArchReg, R_ESI, TempReg, ts);
-
- uInstr2(cb, LOAD, sz, TempReg, ts, TempReg, tv);
- uInstr2(cb, STORE, sz, TempReg, tv, TempReg, td);
-
- uInstr0(cb, CALLM_S, 0);
- uInstr2(cb, MOV, 4, Literal, 0, TempReg, tv);
- uLiteral(cb, 0);
- uInstr1(cb, PUSH, 4, TempReg, tv);
-
- uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_get_dirflag));
- uFlagsRWU(cb, FlagD, FlagsEmpty, FlagsEmpty);
-
- uInstr1(cb, POP, 4, TempReg, tv);
- uInstr0(cb, CALLM_E, 0);
-
- if (sz == 4 || sz == 2) {
- uInstr2(cb, SHL, 4, Literal, 0, TempReg, tv);
- uLiteral(cb, sz/2);
- }
- uInstr2(cb, ADD, 4, TempReg, tv, TempReg, td);
- uInstr2(cb, ADD, 4, TempReg, tv, TempReg, ts);
+ uInstr2(cb, ADD, 4, TempReg, t_inc, TempReg, td);
+ uInstr2(cb, ADD, 4, TempReg, t_inc, TempReg, ts);
uInstr2(cb, PUT, 4, TempReg, td, ArchReg, R_EDI);
@@ -2144,104 +1924,60 @@ void codegen_MOVS ( UCodeBlock* cb, Int
}
-
-/* Template for STOS<sz>, _not_ preceded by a REP prefix. */
static
-void codegen_STOS ( UCodeBlock* cb, Int sz )
+void dis_SCAS ( UCodeBlock* cb, Int sz, Int t_inc )
{
- Int ta /* EAX */, td /* EDI */;
- ta = newTemp(cb);
- td = newTemp(cb);
+ Int ta = newTemp(cb); /* EAX */
+ Int td = newTemp(cb); /* EDI */
+ Int tdv = newTemp(cb); /* (EDI) */
uInstr2(cb, GET, sz, ArchReg, R_EAX, TempReg, ta);
uInstr2(cb, GET, 4, ArchReg, R_EDI, TempReg, td);
- uInstr2(cb, STORE, sz, TempReg, ta, TempReg, td);
-
- uInstr0(cb, CALLM_S, 0);
- uInstr2(cb, MOV, 4, Literal, 0, TempReg, ta);
- uLiteral(cb, 0);
- uInstr1(cb, PUSH, 4, TempReg, ta);
-
- uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_get_dirflag));
- uFlagsRWU(cb, FlagD, FlagsEmpty, FlagsEmpty);
-
- uInstr1(cb, POP, 4, TempReg, ta);
- uInstr0(cb, CALLM_E, 0);
+ uInstr2(cb, LOAD, sz, TempReg, td, TempReg, tdv);
+ /* next uinstr kills ta, but that's ok -- don't need it again */
+ uInstr2(cb, SUB, sz, TempReg, tdv, TempReg, ta);
+ setFlagsFromUOpcode(cb, SUB);
- if (sz == 4 || sz == 2) {
- uInstr2(cb, SHL, 4, Literal, 0, TempReg, ta);
- uLiteral(cb, sz/2);
- }
- uInstr2(cb, ADD, 4, TempReg, ta, TempReg, td);
+ uInstr2(cb, ADD, 4, TempReg, t_inc, TempReg, td);
uInstr2(cb, PUT, 4, TempReg, td, ArchReg, R_EDI);
}
-/* Template for LODS<sz>, _not_ preceded by a REP prefix. */
-static
-void codegen_LODS ( UCodeBlock* cb, Int sz )
-{
- Int ta /* EAX */, ts /* ESI */;
- ta = newTemp(cb);
- ts = newTemp(cb);
-
- uInstr2(cb, GET, 4, ArchReg, R_ESI, TempReg, ts);
- uInstr2(cb, LOAD, sz, TempReg, ts, TempReg, ta);
- uInstr2(cb, PUT, sz, TempReg, ta, ArchReg, R_EAX);
-
- uInstr0(cb, CALLM_S, 0);
- uInstr2(cb, MOV, 4, Literal, 0, TempReg, ta);
- uLiteral(cb, 0);
- uInstr1(cb, PUSH, 4, TempReg, ta);
-
- uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_get_dirflag));
- uFlagsRWU(cb, FlagD, FlagsEmpty, FlagsEmpty);
-
- uInstr1(cb, POP, 4, TempReg, ta);
- uInstr0(cb, CALLM_E, 0);
-
- if (sz == 4 || sz == 2) {
- uInstr2(cb, SHL, 4, Literal, 0, TempReg, ta);
- uLiteral(cb, sz/2);
- }
- uInstr2(cb, ADD, 4, TempReg, ta, TempReg, ts);
- uInstr2(cb, PUT, 4, TempReg, ts, ArchReg, R_ESI);
-}
-
-
-/* Template for SCAS<sz>, _not_ preceded by a REP prefix. */
+/* Wrap the appropriate string op inside a REP/REPE/REPNE.
+ We assume the insn is the last one in the basic block, and so emit a jump
+ to the next insn, rather than just falling through. */
static
-void codegen_SCAS ( UCodeBlock* cb, Int sz )
+void dis_REP_op ( UCodeBlock* cb, Int cond,
+ void (*dis_OP)(UCodeBlock*, Int, Int),
+ Int sz, Addr eip, Addr eip_next, Char* name )
{
- Int ta /* EAX */, td /* EDI */, tv;
- ta = newTemp(cb);
- tv = newTemp(cb);
- td = newTemp(cb);
+ Int t_inc = newTemp(cb);
+ Int tc = newTemp(cb); /* ECX */
- uInstr2(cb, GET, sz, ArchReg, R_EAX, TempReg, ta);
- uInstr2(cb, GET, 4, ArchReg, R_EDI, TempReg, td);
- uInstr2(cb, LOAD, sz, TempReg, td, TempReg, tv);
- /* next uinstr kills ta, but that's ok -- don't need it again */
- uInstr2(cb, SUB, sz, TempReg, tv, TempReg, ta);
- setFlagsFromUOpcode(cb, SUB);
+ dis_string_op_increment(cb, sz, t_inc);
- uInstr0(cb, CALLM_S, 0);
- uInstr2(cb, MOV, 4, Literal, 0, TempReg, tv);
- uLiteral(cb, 0);
- uInstr1(cb, PUSH, 4, TempReg, tv);
+ uInstr2 (cb, GET, 4, ArchReg, R_ECX, TempReg, tc);
+ uInstr2 (cb, JIFZ, 4, TempReg, tc, Literal, 0);
+ uLiteral(cb, eip_next);
+ uInstr1 (cb, DEC, 4, TempReg, tc);
+ uInstr2 (cb, PUT, 4, TempReg, tc, ArchReg, R_ECX);
- uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_get_dirflag));
- uFlagsRWU(cb, FlagD, FlagsEmpty, FlagsEmpty);
+ dis_OP (cb, sz, t_inc);
- uInstr1(cb, POP, 4, TempReg, tv);
- uInstr0(cb, CALLM_E, 0);
+ if (cond == CondAlways) {
+ dis_JMP_d32 (cb, eip);
+ } else {
+ uInstr1 (cb, JMP, 0, Literal, 0);
+ uLiteral (cb, eip);
+ uCond (cb, cond);
+ uFlagsRWU (cb, FlagsOSZACP, FlagsEmpty, FlagsEmpty);
- if (sz == 4 || sz == 2) {
- uInstr2(cb, SHL, 4, Literal, 0, TempReg, tv);
- uLiteral(cb, sz/2);
+ dis_JMP_d32 (cb, eip_next);
}
- uInstr2(cb, ADD, 4, TempReg, tv, TempReg, td);
- uInstr2(cb, PUT, 4, TempReg, td, ArchReg, R_EDI);
+ if (dis) VG_(printf)("%s%c\n", name, nameISize(sz));
}
+/*------------------------------------------------------------*/
+/*--- Arithmetic, etc. ---*/
+/*------------------------------------------------------------*/
/* (I)MUL E, G. Supplied eip points to the modR/M byte. */
@@ -5111,4 +4847,6 @@ static Addr disInstr ( UCodeBlock* cb, A
break;
+ case 0xE0: /* LOOPNE disp8 */
+ case 0xE1: /* LOOPE disp8 */
case 0xE2: /* LOOP disp8 */
/* Again, the docs say this uses ECX/CX as a count depending on
@@ -5123,7 +4861,19 @@ static Addr disInstr ( UCodeBlock* cb, A
uInstr2(cb, JIFZ, 4, TempReg, t1, Literal, 0);
uLiteral(cb, eip);
+
+ if (opc == 0xE2) { /* LOOP */
uInstr1(cb, JMP, 0, Literal, 0);
uLiteral(cb, d32);
uCond(cb, CondAlways);
+ } else { /* LOOPE/LOOPNE */
+ uInstr1(cb, JMP, 0, Literal, 0);
+ uLiteral(cb, eip);
+ uCond(cb, (opc == 0xE1 ? CondNZ : CondZ));
+ uFlagsRWU(cb, FlagsOSZACP, FlagsEmpty, FlagsEmpty);
+
+ uInstr1(cb, JMP, 0, Literal, 0);
+ uLiteral(cb, d32);
+ uCond(cb, CondAlways);
+ }
*isEnd = True;
if (dis)
@@ -5700,54 +5450,29 @@ static Addr disInstr ( UCodeBlock* cb, A
/* ------------------------ SCAS et al ----------------- */
- case 0xA4: /* MOVSb, no REP prefix */
- vg_assert(sorb == 0);
- codegen_MOVS ( cb, 1 );
- if (dis) VG_(printf)("movsb\n");
- break;
- case 0xA5: /* MOVSv, no REP prefix */
- vg_assert(sorb == 0);
- codegen_MOVS ( cb, sz );
- if (dis) VG_(printf)("movs%c\n", nameISize(sz));
+ case 0xA4: /* MOVS, no REP prefix */
+ case 0xA5:
+ dis_string_op( cb, dis_MOVS, ( opc == 0xA4 ? 1 : sz ), "movs", sorb );
break;
case 0xA6: /* CMPSb, no REP prefix */
- vg_assert(sorb == 0);
- codegen_CMPS ( cb, 1 );
- if (dis) VG_(printf)("cmpsb\n");
+ case 0xA7:
+ dis_string_op( cb, dis_CMPS, ( opc == 0xA6 ? 1 : sz ), "cmps", sorb );
break;
- case 0xAA: /* STOSb, no REP prefix */
- vg_assert(sorb == 0);
- codegen_STOS ( cb, 1 );
- if (dis) VG_(printf)("stosb\n");
- break;
- case 0xAB: /* STOSv, no REP prefix */
- vg_assert(sorb == 0);
- codegen_STOS ( cb, sz );
- if (dis) VG_(printf)("stos%c\n", nameISize(sz));
+ case 0xAA: /* STOS, no REP prefix */
+ case 0xAB:
+ dis_string_op( cb, dis_STOS, ( opc == 0xAA ? 1 : sz ), "stos", sorb );
break;
- case 0xAC: /* LODSb, no REP prefix */
- vg_assert(sorb == 0);
- codegen_LODS ( cb, 1 );
- if (dis) VG_(printf)("lodsb\n");
- break;
- case 0xAD: /* LODSv, no REP prefix */
- vg_assert(sorb == 0);
- codegen_LODS ( cb, sz );
- if (dis) VG_(printf)("lods%c\n", nameISize(sz));
+ case 0xAC: /* LODS, no REP prefix */
+ case 0xAD:
+ dis_string_op( cb, dis_LODS, ( opc == 0xAC ? 1 : sz ), "lods", sorb );
break;
- case 0xAE: /* SCASb, no REP prefix */
- vg_assert(sorb == 0);
- codegen_SCAS ( cb, 1 );
- if (dis) VG_(printf)("scasb\n");
+ case 0xAE: /* SCAS, no REP prefix */
+ case 0xAF:
+ dis_string_op( cb, dis_SCAS, ( opc == 0xAE ? 1 : sz ), "scas", sorb );
break;
- case 0xAF: /* SCASl, no REP prefix */
- vg_assert(sorb == 0);
- codegen_SCAS ( cb, sz );
- if (dis) VG_(printf)("scas;\n");
- break;
case 0xFC: /* CLD */
@@ -5791,7 +5516,6 @@ static Addr disInstr ( UCodeBlock* cb, A
if (abyte == 0xAE || abyte == 0xAF) { /* REPNE SCAS<sz> */
if (abyte == 0xAE) sz = 1;
- codegen_REPNE_SCAS ( cb, sz, eip_orig, eip );
+ dis_REP_op ( cb, CondNZ, dis_SCAS, sz, eip_orig, eip, "repne scas" );
*isEnd = True;
- if (dis) VG_(printf)("repne scas%c\n", nameISize(sz));
}
else {
@@ -5801,5 +5525,7 @@ static Addr disInstr ( UCodeBlock* cb, A
}
- case 0xF3: { /* REPE prefix insn */
+ /* REP/REPE prefix insn (for SCAS and CMPS, 0xF3 means REPE,
+ for the rest, it means REP) */
+ case 0xF3: {
Addr eip_orig = eip - 1;
vg_assert(sorb == 0);
@@ -5807,36 +5534,33 @@ static Addr disInstr ( UCodeBlock* cb, A
if (abyte == 0x66) { sz = 2; abyte = getUChar(eip); eip++; }
- if (abyte == 0xA4 || abyte == 0xA5) { /* REPE MOV<sz> */
+ if (abyte == 0xA4 || abyte == 0xA5) { /* REP MOV<sz> */
if (abyte == 0xA4) sz = 1;
- codegen_REPE_MOVS ( cb, sz, eip_orig, eip );
+ dis_REP_op ( cb, CondAlways, dis_MOVS, sz, eip_orig, eip, "rep movs" );
*isEnd = True;
- if (dis) VG_(printf)("repe mov%c\n", nameISize(sz));
}
else
if (abyte == 0xA6 || abyte == 0xA7) { /* REPE CMP<sz> */
if (abyte == 0xA6) sz = 1;
- codegen_REPE_CMPS ( cb, sz, eip_orig, eip );
+ dis_REP_op ( cb, CondZ, dis_CMPS, sz, eip_orig, eip, "repe cmps" );
*isEnd = True;
- if (dis) VG_(printf)("repe cmps%c\n", nameISize(sz));
}
else
- if (abyte == 0xAA || abyte == 0xAB) { /* REPE STOS<sz> */
+ if (abyte == 0xAA || abyte == 0xAB) { /* REP STOS<sz> */
if (abyte == 0xAA) sz = 1;
- codegen_REPE_STOS ( cb, sz, eip_orig, eip );
+ dis_REP_op ( cb, CondAlways, dis_STOS, sz, eip_orig, eip, "rep stos" );
*isEnd = True;
- if (dis) VG_(printf)("repe stos%c\n", nameISize(sz));
}
else
if (abyte == 0xAE || abyte == 0xAF) { /* REPE SCAS<sz> */
if (abyte == 0xAE) sz = 1;
- codegen_REPE_SCAS ( cb, sz, eip_orig, eip );
+ dis_REP_op ( cb, CondZ, dis_SCAS, sz, eip_orig, eip, "repe scas" );
*isEnd = True;
- if (dis) VG_(printf)("repe scas%c\n", nameISize(sz));
}
else
- if (abyte == 0x90) { /* REPE NOP (PAUSE) */
- if (dis) VG_(printf)("repe nop (P4 pause)\n");
+ if (abyte == 0x90) { /* REP NOP (PAUSE) */
+ if (dis) VG_(printf)("rep nop (P4 pause)\n");
/* do nothing; apparently a hint to the P4 re spin-wait loop */
- } else {
+ }
+ else {
goto decode_failure;
}
|
|
From: Dirk M. <mu...@kd...> - 2003-11-28 00:16:31
|
CVS commit by mueller:
fix alignment checking of __posix_memalign. merging to stable.
M +2 -2 vg_replace_malloc.c 1.15
--- valgrind/coregrind/vg_replace_malloc.c #1.14:1.15
@@ -276,7 +276,7 @@ int __posix_memalign ( void **memptr, UI
void *mem;
- /* Test whether the SIZE argument is valid. It must be a power of
+ /* Test whether the alignment argument is valid. It must be a power of
two multiple of sizeof (void *). */
- if (size % sizeof (void *) != 0 || (size & (size - 1)) != 0)
+ if (alignment % sizeof (void *) != 0 || (alignment & (alignment - 1)) != 0)
return VKI_EINVAL /*22*/ /*EINVAL*/;
|
|
From: Nicholas N. <nj...@ca...> - 2003-11-28 09:44:52
|
CVS commit by nethercote:
Factor out repeated code for LOOP{E,NE}
M +4 -10 vg_to_ucode.c 1.113
--- valgrind/coregrind/vg_to_ucode.c #1.112:1.113
@@ -4861,19 +4861,13 @@ static Addr disInstr ( UCodeBlock* cb, A
uInstr2(cb, JIFZ, 4, TempReg, t1, Literal, 0);
uLiteral(cb, eip);
-
- if (opc == 0xE2) { /* LOOP */
- uInstr1(cb, JMP, 0, Literal, 0);
- uLiteral(cb, d32);
- uCond(cb, CondAlways);
- } else { /* LOOPE/LOOPNE */
+ if (opc == 0xE0 || opc == 0xE1) { /* LOOPE/LOOPNE */
uInstr1(cb, JMP, 0, Literal, 0);
uLiteral(cb, eip);
uCond(cb, (opc == 0xE1 ? CondNZ : CondZ));
uFlagsRWU(cb, FlagsOSZACP, FlagsEmpty, FlagsEmpty);
-
+ }
uInstr1(cb, JMP, 0, Literal, 0);
uLiteral(cb, d32);
uCond(cb, CondAlways);
- }
*isEnd = True;
if (dis)
|
|
From: Nicholas N. <nj...@ca...> - 2003-12-01 11:54:48
|
CVS commit by nethercote:
Fixed test in section finding code that was broken for .plt and .got sections.
Thanks to Tom Hughes for the patch.
M +4 -7 vg_symtab2.c 1.60
--- valgrind/coregrind/vg_symtab2.c #1.59:1.60
@@ -983,15 +983,12 @@ Bool vg_read_lib_symbols ( SegInfo* si )
if (0 != sec_data) \
VG_(core_panic)("repeated section!\n"); \
- if (in_exec) { \
+ if (in_exec) \
sec_data = (type)(si->offset + shdr[i].sh_addr); \
- sec_size = shdr[i].sh_size; \
- } else { \
+ else \
sec_data = (type)(oimage + shdr[i].sh_offset); \
sec_size = shdr[i].sh_size; \
- } \
TRACE_SYMTAB( "%18s: %p .. %p\n", \
sec_name, sec_data, sec_data + sec_size - 1); \
- if ( sec_size + (UChar*)sec_data > n_oimage + (UChar*)oimage) \
- { \
+ if ( shdr[i].sh_offset + sec_size > n_oimage ) { \
VG_(symerr)(" section beyond image end?!"); \
goto out; \
|
|
From: Nicholas N. <nj...@ca...> - 2003-12-01 14:00:43
|
CVS commit by nethercote:
Add gettid() syscall.
M +7 -0 vg_syscalls.c 1.60
--- valgrind/coregrind/vg_syscalls.c #1.59:1.60
@@ -1937,4 +1937,10 @@ PRE(getpid)
}
+PRE(gettid)
+{
+ /* pid_t gettid(void); */
+ MAYBE_PRINTF("gettid ()\n");
+}
+
PRE(getpgid)
{
@@ -4636,4 +4642,5 @@ static const struct sys_info sys_info[]
SYSB_(getgid32, False),
SYSB_(getpid, False),
+ SYSB_(gettid, False),
SYSB_(getpgid, False),
SYSB_(getpgrp, False),
|
|
From: Tom H. <th...@cy...> - 2003-12-01 14:16:18
|
In message <200...@of...>
Nicholas Nethercote <nj...@ca...> wrote:
> +PRE(gettid)
> +{
> + /* pid_t gettid(void); */
> + MAYBE_PRINTF("gettid ()\n");
> +}
That may stop valgrind complaining, but it doesn't really do what
anybody expects as it will return the same value in all threads. In
particular a signal sent to the returned value will not go to the
right thread.
The way I've done it in my NPTL patch, which is just about complete
now, is to mark it as a blocking system call so that it is executed
in the proxy LWP which means that it will get a unique ID for each
thread, and that signals sent to that ID will get routed to the right
thread in valgrind.
Jeremy wasn't entirely sure that my solution was a good idea, or even
that it was worth trying to implement it at all at the moment. He had
some concerns about people managing to kill a proxy LWP with nasty
consequences.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Nicholas N. <nj...@ca...> - 2003-12-01 14:24:02
|
On Mon, 1 Dec 2003, Tom Hughes wrote:
> > +PRE(gettid)
> > +{
> > + /* pid_t gettid(void); */
> > + MAYBE_PRINTF("gettid ()\n");
> > +}
>
> That may stop valgrind complaining, but it doesn't really do what
> anybody expects as it will return the same value in all threads. In
> particular a signal sent to the returned value will not go to the
> right thread.
>
> The way I've done it in my NPTL patch, which is just about complete
> now, is to mark it as a blocking system call so that it is executed
> in the proxy LWP which means that it will get a unique ID for each
> thread, and that signals sent to that ID will get routed to the right
> thread in valgrind.
>
> Jeremy wasn't entirely sure that my solution was a good idea, or even
> that it was worth trying to implement it at all at the moment. He had
> some concerns about people managing to kill a proxy LWP with nasty
> consequences.
Ah. Should I back out the changes? In HEAD and stable branch?
N
|