summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralkondratenko@gmail.com <alkondratenko@gmail.com@6b5cf1ce-ec42-a296-1ba9-69fdba395a50>2013-05-07 19:15:35 +0000
committeralkondratenko@gmail.com <alkondratenko@gmail.com@6b5cf1ce-ec42-a296-1ba9-69fdba395a50>2013-05-07 19:15:35 +0000
commit3567b1701aa55a6421aefa5f3de1ca5507cbdf79 (patch)
tree8486787d0d38f0fdd1d2b58af3d3fed22329762b
parent7fcb5ac0696e7ef7f7e7e51c18745af25de7da96 (diff)
downloadgperftools-3567b1701aa55a6421aefa5f3de1ca5507cbdf79.tar.gz
issue-511: recognise rex.w jmpq *<literal>(%rip) as iat jump
Apparently Windows Server 2012 (and presumably windows 8) now has this form of iat jump. Which is quite useless (rex.w is according to my understanding is not needed at all) but because of rex.w our code to recognize jumps like that didn't work. Fix is just skip this prefix. git-svn-id: http://gperftools.googlecode.com/svn/trunk@214 6b5cf1ce-ec42-a296-1ba9-69fdba395a50
-rw-r--r--src/windows/preamble_patcher.cc13
1 files changed, 13 insertions, 0 deletions
diff --git a/src/windows/preamble_patcher.cc b/src/windows/preamble_patcher.cc
index 4163691..51a5af7 100644
--- a/src/windows/preamble_patcher.cc
+++ b/src/windows/preamble_patcher.cc
@@ -103,6 +103,7 @@ void* PreamblePatcher::ResolveTargetImpl(unsigned char* target,
new_target = target + 2 + relative_offset;
} else if (target[0] == ASM_JMP32ABS_0 &&
target[1] == ASM_JMP32ABS_1) {
+ jmp32rel:
// Visual studio seems to sometimes do it this way instead of the
// previous way. Not sure what the rules are, but it was happening
// with operator new in some binaries.
@@ -118,6 +119,18 @@ void* PreamblePatcher::ResolveTargetImpl(unsigned char* target,
memcpy(&new_target_v, reinterpret_cast<void*>(target + 2), 4);
}
new_target = reinterpret_cast<unsigned char*>(*new_target_v);
+ } else if (kIs64BitBinary && target[0] == ASM_REXW
+ && target[1] == ASM_JMP32ABS_0
+ && target[2] == ASM_JMP32ABS_1) {
+ // in Visual Studio 2012 we're seeing jump like that:
+ // rex.W jmpq *0x11d019(%rip)
+ //
+ // according to docs I have, rex prefix is actually unneeded and
+ // can be ignored. I.e. docs say for jumps like that operand
+ // already defaults to 64-bit. But clearly it breaks abs. jump
+ // detection above and we just skip rex
+ target++;
+ goto jmp32rel;
} else {
break;
}