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. 4 5 #include "courgette/base_test_unittest.h" 6 #include "courgette/disassembler_elf_32_arm.h" 7 #include "courgette/disassembler_elf_32_x86.h" 8 9 class TypedRVATest : public BaseTest { 10 public: 11 void TestRelativeTargetX86(courgette::RVA word, courgette::RVA expected) 12 const; 13 14 void TestRelativeTargetARM(courgette::ARM_RVA arm_rva, 15 courgette::RVA rva, 16 uint32 op, 17 courgette::RVA expected) const; 18 19 void TestARMOPEncode(courgette::ARM_RVA arm_rva, 20 courgette::RVA rva, 21 uint32 op, 22 courgette::RVA expected) const; 23 }; 24 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); 30 31 EXPECT_TRUE(typed_rva->ComputeRelativeTarget(op_pointer)); 32 EXPECT_EQ(typed_rva->relative_target(), expected); 33 34 delete typed_rva; 35 } 36 37 uint32 Read32LittleEndian(const void* address) { 38 return *reinterpret_cast<const uint32*>(address); 39 } 40 41 void TypedRVATest::TestRelativeTargetARM(courgette::ARM_RVA arm_rva, 42 courgette::RVA rva, 43 uint32 op, 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); 48 49 EXPECT_TRUE(typed_rva->ComputeRelativeTarget(op_pointer)); 50 EXPECT_EQ(rva + typed_rva->relative_target(), expected); 51 52 delete typed_rva; 53 } 54 55 void TypedRVATest::TestARMOPEncode(courgette::ARM_RVA arm_rva, 56 courgette::RVA rva, 57 uint32 op, 58 courgette::RVA expected) const { 59 uint16 c_op; 60 uint32 addr; 61 EXPECT_TRUE(courgette::DisassemblerElf32ARM::Compress(arm_rva, op, rva, 62 &c_op, &addr)); 63 EXPECT_EQ(rva + addr, expected); 64 65 uint32 new_op; 66 EXPECT_TRUE(courgette::DisassemblerElf32ARM::Decompress(arm_rva, c_op, addr, 67 &new_op)); 68 EXPECT_EQ(new_op, op); 69 } 70 71 TEST_F(TypedRVATest, TestX86) { 72 TestRelativeTargetX86(0x0, 0x4); 73 } 74 75 // ARM opcodes taken from and tested against the output of 76 // "arm-linux-gnueabi-objdump -d daisy_3701.98.0/bin/ls" 77 78 TEST_F(TypedRVATest, TestARM_OFF8_PREFETCH) { 79 TestRelativeTargetARM(courgette::ARM_OFF8, 0x0, 0x0, 0x4); 80 } 81 82 TEST_F(TypedRVATest, TestARM_OFF8_FORWARDS) { 83 TestRelativeTargetARM(courgette::ARM_OFF8, 0x2bcc, 0xd00e, 0x2bec); 84 TestRelativeTargetARM(courgette::ARM_OFF8, 0x3752, 0xd910, 0x3776); 85 } 86 87 TEST_F(TypedRVATest, TestARM_OFF8_BACKWARDS) { 88 TestRelativeTargetARM(courgette::ARM_OFF8, 0x3774, 0xd1f6, 0x3764); 89 } 90 91 TEST_F(TypedRVATest, TestARM_OFF11_PREFETCH) { 92 TestRelativeTargetARM(courgette::ARM_OFF11, 0x0, 0x0, 0x4); 93 } 94 95 TEST_F(TypedRVATest, TestARM_OFF11_FORWARDS) { 96 TestRelativeTargetARM(courgette::ARM_OFF11, 0x2bea, 0xe005, 0x2bf8); 97 } 98 99 TEST_F(TypedRVATest, TestARM_OFF11_BACKWARDS) { 100 TestRelativeTargetARM(courgette::ARM_OFF11, 0x2f80, 0xe6cd, 0x2d1e); 101 TestRelativeTargetARM(courgette::ARM_OFF11, 0x3610, 0xe56a, 0x30e8); 102 } 103 104 TEST_F(TypedRVATest, TestARM_OFF24_PREFETCH) { 105 TestRelativeTargetARM(courgette::ARM_OFF24, 0x0, 0x0, 0x8); 106 } 107 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); 112 } 113 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. 117 } 118 119 TEST_F(TypedRVATest, TestARM_OFF25_FORWARDS) { 120 TestRelativeTargetARM(courgette::ARM_OFF25, 0x2bf4, 0xfe06f008, 0xb804); 121 TestRelativeTargetARM(courgette::ARM_OFF25, 0x2c58, 0xfeacf005, 0x89b4); 122 } 123 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); 128 } 129 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); 134 } 135 136 TEST_F(TypedRVATest, TestARM_OFF21_BACKWARDS) { 137 TestRelativeTargetARM(courgette::ARM_OFF21, 0x67e4, 0xaee9f43f, 0x65ba); 138 TestRelativeTargetARM(courgette::ARM_OFF21, 0x67ee, 0xaee4f47f, 0x65ba); 139 } 140 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); 163 } 164