summaryrefslogtreecommitdiffstats
path: root/courgette/disassembler_elf_32_arm.cc
diff options
context:
space:
mode:
authorpaulgazz@chromium.org <paulgazz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-23 21:18:19 +0000
committerpaulgazz@chromium.org <paulgazz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-23 21:18:19 +0000
commit144c8e950add26b44467784568d0ca5387a1047d (patch)
tree74c55e162f2128d67552a654d1cc57fb21b91afe /courgette/disassembler_elf_32_arm.cc
parent63d353f9d7a70dc827bad25e0932967711d595f3 (diff)
downloadchromium_src-144c8e950add26b44467784568d0ca5387a1047d.zip
chromium_src-144c8e950add26b44467784568d0ca5387a1047d.tar.gz
chromium_src-144c8e950add26b44467784568d0ca5387a1047d.tar.bz2
Added a TypedRVA to track what kind of branch instruction is used for
the jump and compute the target RVA accordingly. Also updated the unit test to use TypedRVA and check that only X86 RVAs are found by the X86 "disassembler". BUG=258645 Review URL: https://chromiumcodereview.appspot.com/18055007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@213220 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'courgette/disassembler_elf_32_arm.cc')
-rw-r--r--courgette/disassembler_elf_32_arm.cc39
1 files changed, 39 insertions, 0 deletions
diff --git a/courgette/disassembler_elf_32_arm.cc b/courgette/disassembler_elf_32_arm.cc
index f271020..6270c64 100644
--- a/courgette/disassembler_elf_32_arm.cc
+++ b/courgette/disassembler_elf_32_arm.cc
@@ -17,6 +17,45 @@
namespace courgette {
+CheckBool DisassemblerElf32ARM::TypedRVAARM::ComputeRelativeTarget(
+ const uint8* op_pointer) {
+ uint32 temp = 0;
+
+ switch (type_) {
+ case ARM_OFF24:
+ // The offset is given by the lower 24-bits of the op, shifted
+ // left 2 bits, and sign extended.
+ temp = Read32LittleEndian(op_pointer);
+ temp = (temp & 0x00FFFFFF) << 2;
+ if (temp & 0x02000000)
+ temp |= 0xFC000000;
+ temp += 8;
+ break;
+ case ARM_OFF8:
+ // The offset is given by lower 8 bits of the op. It is a 9-bit
+ // offset, shifted right one bit and signed extended.
+ temp = (Read16LittleEndian(op_pointer) & 0x00FF) << 1;
+ if (temp & 0x0100)
+ temp |= 0xFFFFFE00;
+ temp += 4; // Offset from _next_ PC.
+ break;
+ case ARM_OFF11:
+ // The offset is given by lower 11 bits of the op, and is a
+ // 12-bit offset, shifted right one bit and sign extended.
+ temp = (Read16LittleEndian(op_pointer) & 0x07FF) << 1;
+ if (temp & 0x00000800)
+ temp |= 0xFFFFF000;
+ temp += 4; // Offset from _next_ PC.
+ break;
+ default:
+ return false;
+ }
+
+ set_relative_target(temp);
+
+ return true;
+}
+
DisassemblerElf32ARM::DisassemblerElf32ARM(const void* start, size_t length)
: DisassemblerElf32(start, length) {
}