diff options
author | alkondratenko@gmail.com <alkondratenko@gmail.com@6b5cf1ce-ec42-a296-1ba9-69fdba395a50> | 2013-05-07 19:15:35 +0000 |
---|---|---|
committer | alkondratenko@gmail.com <alkondratenko@gmail.com@6b5cf1ce-ec42-a296-1ba9-69fdba395a50> | 2013-05-07 19:15:35 +0000 |
commit | 3567b1701aa55a6421aefa5f3de1ca5507cbdf79 (patch) | |
tree | 8486787d0d38f0fdd1d2b58af3d3fed22329762b | |
parent | 7fcb5ac0696e7ef7f7e7e51c18745af25de7da96 (diff) | |
download | gperftools-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.cc | 13 |
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; } |