1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "courgette/base_test_unittest.h"
6 #include "courgette/disassembler_elf_32_arm.h"
7 #include "courgette/disassembler_elf_32_x86.h"
9 class TypedRVATest
: public BaseTest
{
11 void TestRelativeTargetX86(courgette::RVA word
, courgette::RVA expected
)
14 void TestRelativeTargetARM(courgette::ARM_RVA arm_rva
,
17 courgette::RVA expected
) const;
19 void TestARMOPEncode(courgette::ARM_RVA arm_rva
,
22 courgette::RVA expected
) const;
25 void TypedRVATest::TestRelativeTargetX86(courgette::RVA word
,
26 courgette::RVA expected
) const {
27 courgette::DisassemblerElf32X86::TypedRVAX86
* typed_rva
28 = new courgette::DisassemblerElf32X86::TypedRVAX86(0);
29 const uint8
* op_pointer
= reinterpret_cast<const uint8
*>(&word
);
31 EXPECT_TRUE(typed_rva
->ComputeRelativeTarget(op_pointer
));
32 EXPECT_EQ(typed_rva
->relative_target(), expected
);
37 uint32
Read32LittleEndian(const void* address
) {
38 return *reinterpret_cast<const uint32
*>(address
);
41 void TypedRVATest::TestRelativeTargetARM(courgette::ARM_RVA arm_rva
,
44 courgette::RVA expected
) const {
45 courgette::DisassemblerElf32ARM::TypedRVAARM
* typed_rva
46 = new courgette::DisassemblerElf32ARM::TypedRVAARM(arm_rva
, rva
);
47 uint8
* op_pointer
= reinterpret_cast<uint8
*>(&op
);
49 EXPECT_TRUE(typed_rva
->ComputeRelativeTarget(op_pointer
));
50 EXPECT_EQ(rva
+ typed_rva
->relative_target(), expected
);
55 void TypedRVATest::TestARMOPEncode(courgette::ARM_RVA arm_rva
,
58 courgette::RVA expected
) const {
61 EXPECT_TRUE(courgette::DisassemblerElf32ARM::Compress(arm_rva
, op
, rva
,
63 EXPECT_EQ(rva
+ addr
, expected
);
66 EXPECT_TRUE(courgette::DisassemblerElf32ARM::Decompress(arm_rva
, c_op
, addr
,
68 EXPECT_EQ(new_op
, op
);
71 TEST_F(TypedRVATest
, TestX86
) {
72 TestRelativeTargetX86(0x0, 0x4);
75 // ARM opcodes taken from and tested against the output of
76 // "arm-linux-gnueabi-objdump -d daisy_3701.98.0/bin/ls"
78 TEST_F(TypedRVATest
, TestARM_OFF8_PREFETCH
) {
79 TestRelativeTargetARM(courgette::ARM_OFF8
, 0x0, 0x0, 0x4);
82 TEST_F(TypedRVATest
, TestARM_OFF8_FORWARDS
) {
83 TestRelativeTargetARM(courgette::ARM_OFF8
, 0x2bcc, 0xd00e, 0x2bec);
84 TestRelativeTargetARM(courgette::ARM_OFF8
, 0x3752, 0xd910, 0x3776);
87 TEST_F(TypedRVATest
, TestARM_OFF8_BACKWARDS
) {
88 TestRelativeTargetARM(courgette::ARM_OFF8
, 0x3774, 0xd1f6, 0x3764);
91 TEST_F(TypedRVATest
, TestARM_OFF11_PREFETCH
) {
92 TestRelativeTargetARM(courgette::ARM_OFF11
, 0x0, 0x0, 0x4);
95 TEST_F(TypedRVATest
, TestARM_OFF11_FORWARDS
) {
96 TestRelativeTargetARM(courgette::ARM_OFF11
, 0x2bea, 0xe005, 0x2bf8);
99 TEST_F(TypedRVATest
, TestARM_OFF11_BACKWARDS
) {
100 TestRelativeTargetARM(courgette::ARM_OFF11
, 0x2f80, 0xe6cd, 0x2d1e);
101 TestRelativeTargetARM(courgette::ARM_OFF11
, 0x3610, 0xe56a, 0x30e8);
104 TEST_F(TypedRVATest
, TestARM_OFF24_PREFETCH
) {
105 TestRelativeTargetARM(courgette::ARM_OFF24
, 0x0, 0x0, 0x8);
108 TEST_F(TypedRVATest
, TestARM_OFF24_FORWARDS
) {
109 TestRelativeTargetARM(courgette::ARM_OFF24
, 0x2384, 0x4af3613a, 0xffcda874);
110 TestRelativeTargetARM(courgette::ARM_OFF24
, 0x23bc, 0x6af961b9, 0xffe5aaa8);
111 TestRelativeTargetARM(courgette::ARM_OFF24
, 0x23d4, 0x2b006823, 0x1c468);
114 TEST_F(TypedRVATest
, TestARM_OFF24_BACKWARDS
) {
115 // TODO(paulgazz): find a real-world example of an non-thumb ARM
116 // branch op that jumps backwards.
119 TEST_F(TypedRVATest
, TestARM_OFF25_FORWARDS
) {
120 TestRelativeTargetARM(courgette::ARM_OFF25
, 0x2bf4, 0xfe06f008, 0xb804);
121 TestRelativeTargetARM(courgette::ARM_OFF25
, 0x2c58, 0xfeacf005, 0x89b4);
124 TEST_F(TypedRVATest
, TestARM_OFF25_BACKWARDS
) {
125 TestRelativeTargetARM(courgette::ARM_OFF25
, 0x2bd2, 0xeb9ef7ff, 0x2310);
126 TestRelativeTargetARM(courgette::ARM_OFF25
, 0x2bd8, 0xeb8ef7ff, 0x22f8);
127 TestRelativeTargetARM(courgette::ARM_OFF25
, 0x2c3e, 0xea2ef7ff, 0x209c);
130 TEST_F(TypedRVATest
, TestARM_OFF21_FORWARDS
) {
131 TestRelativeTargetARM(courgette::ARM_OFF21
, 0x2bc6, 0x84c7f000, 0x3558);
132 TestRelativeTargetARM(courgette::ARM_OFF21
, 0x2bde, 0x871df000, 0x3a1c);
133 TestRelativeTargetARM(courgette::ARM_OFF21
, 0x2c5e, 0x86c1f2c0, 0x39e4);
136 TEST_F(TypedRVATest
, TestARM_OFF21_BACKWARDS
) {
137 TestRelativeTargetARM(courgette::ARM_OFF21
, 0x67e4, 0xaee9f43f, 0x65ba);
138 TestRelativeTargetARM(courgette::ARM_OFF21
, 0x67ee, 0xaee4f47f, 0x65ba);
141 TEST_F(TypedRVATest
, TestARMOPEncode
) {
142 TestARMOPEncode(courgette::ARM_OFF8
, 0x2bcc, 0xd00e, 0x2bec);
143 TestARMOPEncode(courgette::ARM_OFF8
, 0x3752, 0xd910, 0x3776);
144 TestARMOPEncode(courgette::ARM_OFF8
, 0x3774, 0xd1f6, 0x3764);
145 TestARMOPEncode(courgette::ARM_OFF11
, 0x0, 0x0, 0x4);
146 TestARMOPEncode(courgette::ARM_OFF11
, 0x2bea, 0xe005, 0x2bf8);
147 TestARMOPEncode(courgette::ARM_OFF11
, 0x2f80, 0xe6cd, 0x2d1e);
148 TestARMOPEncode(courgette::ARM_OFF11
, 0x3610, 0xe56a, 0x30e8);
149 TestARMOPEncode(courgette::ARM_OFF24
, 0x0, 0x0, 0x8);
150 TestARMOPEncode(courgette::ARM_OFF24
, 0x2384, 0x4af3613a, 0xffcda874);
151 TestARMOPEncode(courgette::ARM_OFF24
, 0x23bc, 0x6af961b9, 0xffe5aaa8);
152 TestARMOPEncode(courgette::ARM_OFF24
, 0x23d4, 0x2b006823, 0x1c468);
153 TestARMOPEncode(courgette::ARM_OFF25
, 0x2bf4, 0xf008fe06, 0xb804);
154 TestARMOPEncode(courgette::ARM_OFF25
, 0x2c58, 0xf005feac, 0x89b4);
155 TestARMOPEncode(courgette::ARM_OFF25
, 0x2bd2, 0xf7ffeb9e, 0x2310);
156 TestARMOPEncode(courgette::ARM_OFF25
, 0x2bd8, 0xf7ffeb8e, 0x22f8);
157 TestARMOPEncode(courgette::ARM_OFF25
, 0x2c3e, 0xf7ffea2e, 0x209c);
158 TestARMOPEncode(courgette::ARM_OFF21
, 0x2bc6, 0xf00084c7, 0x3558);
159 TestARMOPEncode(courgette::ARM_OFF21
, 0x2bde, 0xf000871d, 0x3a1c);
160 TestARMOPEncode(courgette::ARM_OFF21
, 0x2c5e, 0xf2c086c1, 0x39e4);
161 TestARMOPEncode(courgette::ARM_OFF21
, 0x67e4, 0xf43faee9, 0x65ba);
162 TestARMOPEncode(courgette::ARM_OFF21
, 0x67ee, 0xf47faee4, 0x65ba);