1a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
2a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// found in the LICENSE file.
4a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
5a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "courgette/base_test_unittest.h"
6a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "courgette/disassembler_elf_32_arm.h"
7a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "courgette/disassembler_elf_32_x86.h"
8a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
9a3f7b4e666c476898878fa745f637129375cd889Ben Murdochclass TypedRVATest : public BaseTest {
10a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch public:
11a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  void TestRelativeTargetX86(courgette::RVA word, courgette::RVA expected)
12a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const;
13a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
14a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  void TestRelativeTargetARM(courgette::ARM_RVA arm_rva,
15a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                             courgette::RVA rva,
16a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                             uint32 op,
17a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                             courgette::RVA expected) const;
18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  void TestARMOPEncode(courgette::ARM_RVA arm_rva,
20a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                       courgette::RVA rva,
21a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                       uint32 op,
22a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                       courgette::RVA expected) const;
23a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch};
24a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
25a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid TypedRVATest::TestRelativeTargetX86(courgette::RVA word,
26a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                         courgette::RVA expected) const {
27a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  courgette::DisassemblerElf32X86::TypedRVAX86* typed_rva
28a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    = new courgette::DisassemblerElf32X86::TypedRVAX86(0);
29a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  const uint8* op_pointer = reinterpret_cast<const uint8*>(&word);
30a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
31a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  EXPECT_TRUE(typed_rva->ComputeRelativeTarget(op_pointer));
32a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  EXPECT_EQ(typed_rva->relative_target(), expected);
33558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
34558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delete typed_rva;
35a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
36a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
37a3f7b4e666c476898878fa745f637129375cd889Ben Murdochuint32 Read32LittleEndian(const void* address) {
38a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  return *reinterpret_cast<const uint32*>(address);
39a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
40a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
41a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid TypedRVATest::TestRelativeTargetARM(courgette::ARM_RVA arm_rva,
42a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                         courgette::RVA rva,
43a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                         uint32 op,
44a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                         courgette::RVA expected) const {
45a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  courgette::DisassemblerElf32ARM::TypedRVAARM* typed_rva
46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    = new courgette::DisassemblerElf32ARM::TypedRVAARM(arm_rva, rva);
47a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  uint8* op_pointer = reinterpret_cast<uint8*>(&op);
48a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
49a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  EXPECT_TRUE(typed_rva->ComputeRelativeTarget(op_pointer));
50a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  EXPECT_EQ(rva + typed_rva->relative_target(), expected);
51558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
52558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delete typed_rva;
53a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
54a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void TypedRVATest::TestARMOPEncode(courgette::ARM_RVA arm_rva,
56a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                             courgette::RVA rva,
57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                             uint32 op,
58a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                             courgette::RVA expected) const {
59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  uint16 c_op;
60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  uint32 addr;
61a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(courgette::DisassemblerElf32ARM::Compress(arm_rva, op, rva,
62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                                        &c_op, &addr));
63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(rva + addr, expected);
64a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  uint32 new_op;
66a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(courgette::DisassemblerElf32ARM::Decompress(arm_rva, c_op, addr,
67a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                                          &new_op));
68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(new_op, op);
69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
71a3f7b4e666c476898878fa745f637129375cd889Ben MurdochTEST_F(TypedRVATest, TestX86) {
72a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  TestRelativeTargetX86(0x0, 0x4);
73a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
74a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
75a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// ARM opcodes taken from and tested against the output of
76a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// "arm-linux-gnueabi-objdump -d daisy_3701.98.0/bin/ls"
77a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
78a3f7b4e666c476898878fa745f637129375cd889Ben MurdochTEST_F(TypedRVATest, TestARM_OFF8_PREFETCH) {
79a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  TestRelativeTargetARM(courgette::ARM_OFF8, 0x0, 0x0, 0x4);
80a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
81a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
82a3f7b4e666c476898878fa745f637129375cd889Ben MurdochTEST_F(TypedRVATest, TestARM_OFF8_FORWARDS) {
83a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  TestRelativeTargetARM(courgette::ARM_OFF8, 0x2bcc, 0xd00e, 0x2bec);
84a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  TestRelativeTargetARM(courgette::ARM_OFF8, 0x3752, 0xd910, 0x3776);
85a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
86a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
87a3f7b4e666c476898878fa745f637129375cd889Ben MurdochTEST_F(TypedRVATest, TestARM_OFF8_BACKWARDS) {
88a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  TestRelativeTargetARM(courgette::ARM_OFF8, 0x3774, 0xd1f6, 0x3764);
89a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
90a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
91a3f7b4e666c476898878fa745f637129375cd889Ben MurdochTEST_F(TypedRVATest, TestARM_OFF11_PREFETCH) {
92a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  TestRelativeTargetARM(courgette::ARM_OFF11, 0x0, 0x0, 0x4);
93a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
94a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
95a3f7b4e666c476898878fa745f637129375cd889Ben MurdochTEST_F(TypedRVATest, TestARM_OFF11_FORWARDS) {
96a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  TestRelativeTargetARM(courgette::ARM_OFF11, 0x2bea, 0xe005, 0x2bf8);
97a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
98a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
99a3f7b4e666c476898878fa745f637129375cd889Ben MurdochTEST_F(TypedRVATest, TestARM_OFF11_BACKWARDS) {
100a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  TestRelativeTargetARM(courgette::ARM_OFF11, 0x2f80, 0xe6cd, 0x2d1e);
101a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  TestRelativeTargetARM(courgette::ARM_OFF11, 0x3610, 0xe56a, 0x30e8);
102a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
103a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
104a3f7b4e666c476898878fa745f637129375cd889Ben MurdochTEST_F(TypedRVATest, TestARM_OFF24_PREFETCH) {
105a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  TestRelativeTargetARM(courgette::ARM_OFF24, 0x0, 0x0, 0x8);
106a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
107a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
108a3f7b4e666c476898878fa745f637129375cd889Ben MurdochTEST_F(TypedRVATest, TestARM_OFF24_FORWARDS) {
109a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  TestRelativeTargetARM(courgette::ARM_OFF24, 0x2384, 0x4af3613a, 0xffcda874);
110a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  TestRelativeTargetARM(courgette::ARM_OFF24, 0x23bc, 0x6af961b9, 0xffe5aaa8);
111a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  TestRelativeTargetARM(courgette::ARM_OFF24, 0x23d4, 0x2b006823, 0x1c468);
112a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
113a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
114a3f7b4e666c476898878fa745f637129375cd889Ben MurdochTEST_F(TypedRVATest, TestARM_OFF24_BACKWARDS) {
115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // TODO(paulgazz): find a real-world example of an non-thumb ARM
116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // branch op that jumps backwards.
117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(TypedRVATest, TestARM_OFF25_FORWARDS) {
120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestRelativeTargetARM(courgette::ARM_OFF25, 0x2bf4, 0xfe06f008, 0xb804);
121a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestRelativeTargetARM(courgette::ARM_OFF25, 0x2c58, 0xfeacf005, 0x89b4);
122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
123a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
124a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(TypedRVATest, TestARM_OFF25_BACKWARDS) {
125a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestRelativeTargetARM(courgette::ARM_OFF25, 0x2bd2, 0xeb9ef7ff, 0x2310);
126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestRelativeTargetARM(courgette::ARM_OFF25, 0x2bd8, 0xeb8ef7ff, 0x22f8);
127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestRelativeTargetARM(courgette::ARM_OFF25, 0x2c3e, 0xea2ef7ff, 0x209c);
128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(TypedRVATest, TestARM_OFF21_FORWARDS) {
131a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestRelativeTargetARM(courgette::ARM_OFF21, 0x2bc6, 0x84c7f000, 0x3558);
132a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestRelativeTargetARM(courgette::ARM_OFF21, 0x2bde, 0x871df000, 0x3a1c);
133a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestRelativeTargetARM(courgette::ARM_OFF21, 0x2c5e, 0x86c1f2c0, 0x39e4);
134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(TypedRVATest, TestARM_OFF21_BACKWARDS) {
137a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestRelativeTargetARM(courgette::ARM_OFF21, 0x67e4, 0xaee9f43f, 0x65ba);
138a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestRelativeTargetARM(courgette::ARM_OFF21, 0x67ee, 0xaee4f47f, 0x65ba);
139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
140a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
141a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(TypedRVATest, TestARMOPEncode) {
142a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestARMOPEncode(courgette::ARM_OFF8, 0x2bcc, 0xd00e, 0x2bec);
143a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestARMOPEncode(courgette::ARM_OFF8, 0x3752, 0xd910, 0x3776);
144a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestARMOPEncode(courgette::ARM_OFF8, 0x3774, 0xd1f6, 0x3764);
145a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestARMOPEncode(courgette::ARM_OFF11, 0x0, 0x0, 0x4);
146a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestARMOPEncode(courgette::ARM_OFF11, 0x2bea, 0xe005, 0x2bf8);
147a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestARMOPEncode(courgette::ARM_OFF11, 0x2f80, 0xe6cd, 0x2d1e);
148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestARMOPEncode(courgette::ARM_OFF11, 0x3610, 0xe56a, 0x30e8);
149a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestARMOPEncode(courgette::ARM_OFF24, 0x0, 0x0, 0x8);
150a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestARMOPEncode(courgette::ARM_OFF24, 0x2384, 0x4af3613a, 0xffcda874);
151a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestARMOPEncode(courgette::ARM_OFF24, 0x23bc, 0x6af961b9, 0xffe5aaa8);
152a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestARMOPEncode(courgette::ARM_OFF24, 0x23d4, 0x2b006823, 0x1c468);
153a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestARMOPEncode(courgette::ARM_OFF25, 0x2bf4, 0xf008fe06, 0xb804);
154a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestARMOPEncode(courgette::ARM_OFF25, 0x2c58, 0xf005feac, 0x89b4);
155a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestARMOPEncode(courgette::ARM_OFF25, 0x2bd2, 0xf7ffeb9e, 0x2310);
156a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestARMOPEncode(courgette::ARM_OFF25, 0x2bd8, 0xf7ffeb8e, 0x22f8);
157a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestARMOPEncode(courgette::ARM_OFF25, 0x2c3e, 0xf7ffea2e, 0x209c);
158a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestARMOPEncode(courgette::ARM_OFF21, 0x2bc6, 0xf00084c7, 0x3558);
159a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestARMOPEncode(courgette::ARM_OFF21, 0x2bde, 0xf000871d, 0x3a1c);
160a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestARMOPEncode(courgette::ARM_OFF21, 0x2c5e, 0xf2c086c1, 0x39e4);
161a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestARMOPEncode(courgette::ARM_OFF21, 0x67e4, 0xf43faee9, 0x65ba);
162a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  TestARMOPEncode(courgette::ARM_OFF21, 0x67ee, 0xf47faee4, 0x65ba);
163a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
164