summaryrefslogtreecommitdiffstats
path: root/courgette/disassembler_win32_x64.cc
diff options
context:
space:
mode:
authorwfh <wfh@chromium.org>2015-03-12 21:24:19 -0700
committerCommit bot <commit-bot@chromium.org>2015-03-13 04:24:53 +0000
commitfde55c795a759d11099415c3a2a1f8918b09269a (patch)
tree32f6046678316635b4f1a20780248960d421ac59 /courgette/disassembler_win32_x64.cc
parenta6073a32b9923b1d21406b96ce56b279364c63a0 (diff)
downloadchromium_src-fde55c795a759d11099415c3a2a1f8918b09269a.zip
chromium_src-fde55c795a759d11099415c3a2a1f8918b09269a.tar.gz
chromium_src-fde55c795a759d11099415c3a2a1f8918b09269a.tar.bz2
Add 64-bit absolute address support to courgette.
Turns out, courgette never really understood 64-bit addresses, and they were all being truncated to 32-bit values. This worked fine, as the high 32-bit part was just serialized as byte data, but would have broken for a 64-bit PE image that straddled the 32-bit boundary. This CL adds a new op code for ABS64 to ensure that 64-bit math is used when assembling them, but re-uses the existing abs32 streams (since RVA are always 32-bit). This always reduces the size of the patch, but only by a tiny amount, since the four bytes in the absolute addresses no longer need to be stored separately. This also fixes static cast by reading the 8-byte absolute address from 64-bit binaries. This change is virtually size neutral. Against test binaries (64-bit chrome.dll 40.0.2214.115->43.0.2317.0) the uncompressed patch sizes were: before: 10,948,152 after: 10,925,425 (0.2% reduction) BUG=419996 TEST=courgette_unittests Review URL: https://codereview.chromium.org/629643002 Cr-Commit-Position: refs/heads/master@{#320449}
Diffstat (limited to 'courgette/disassembler_win32_x64.cc')
-rw-r--r--courgette/disassembler_win32_x64.cc11
1 files changed, 5 insertions, 6 deletions
diff --git a/courgette/disassembler_win32_x64.cc b/courgette/disassembler_win32_x64.cc
index 626bd35..73ad0b4 100644
--- a/courgette/disassembler_win32_x64.cc
+++ b/courgette/disassembler_win32_x64.cc
@@ -10,6 +10,7 @@
#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/numerics/safe_conversions.h"
#include "courgette/assembly_program.h"
#include "courgette/courgette.h"
@@ -568,15 +569,13 @@ CheckBool DisassemblerWin32X64::ParseFileRegion(
++abs32_pos;
if (abs32_pos != abs32_locations_.end() && *abs32_pos == current_rva) {
- uint32 target_address = Read32LittleEndian(p);
- // TODO(wfh): image_base() can be larger than 32 bits, so this math can
- // underflow. Figure out the right solution here.
- RVA target_rva = target_address - static_cast<uint32>(image_base());
+ uint64 target_address = Read64LittleEndian(p);
+ RVA target_rva = base::checked_cast<RVA>(target_address - image_base());
// TODO(sra): target could be Label+offset. It is not clear how to guess
// which it might be. We assume offset==0.
- if (!program->EmitAbs32(program->FindOrMakeAbs32Label(target_rva)))
+ if (!program->EmitAbs64(program->FindOrMakeAbs32Label(target_rva)))
return false;
- p += 4;
+ p += 8;
continue;
}