blob: c8d1d98bd0d00a3197aa6c6fae22f993601b4eea [file] [log] [blame]
Josh Gao6f580d82017-09-22 12:57:15 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdint.h>
18
19#include <utility>
20#include <type_traits>
21#include <vector>
22
23#include <gtest/gtest.h>
24
25#include <unwindstack/Elf.h>
26#include <unwindstack/ElfInterface.h>
27#include <unwindstack/MapInfo.h>
28#include <unwindstack/Regs.h>
29
30#include "Machine.h"
31
32namespace unwindstack {
33
34struct Register {
35 std::string expected_name;
36 uint64_t offset;
37
38 bool operator==(const Register& rhs) const {
39 return std::tie(expected_name, offset) == std::tie(rhs.expected_name, rhs.offset);
40 }
41};
42
43template<typename T>
44class RegsIterateTest : public ::testing::Test {
45};
46
47template<typename RegsType>
48std::vector<Register> ExpectedRegisters();
49
50template<>
51std::vector<Register> ExpectedRegisters<RegsArm>() {
52 std::vector<Register> result;
53 result.push_back({"r0", ARM_REG_R0});
54 result.push_back({"r1", ARM_REG_R1});
55 result.push_back({"r2", ARM_REG_R2});
56 result.push_back({"r3", ARM_REG_R3});
57 result.push_back({"r4", ARM_REG_R4});
58 result.push_back({"r5", ARM_REG_R5});
59 result.push_back({"r6", ARM_REG_R6});
60 result.push_back({"r7", ARM_REG_R7});
61 result.push_back({"r8", ARM_REG_R8});
62 result.push_back({"r9", ARM_REG_R9});
63 result.push_back({"r10", ARM_REG_R10});
64 result.push_back({"r11", ARM_REG_R11});
65 result.push_back({"ip", ARM_REG_R12});
66 result.push_back({"sp", ARM_REG_SP});
67 result.push_back({"lr", ARM_REG_LR});
68 result.push_back({"pc", ARM_REG_PC});
69 return result;
70}
71
72template<>
73std::vector<Register> ExpectedRegisters<RegsArm64>() {
74 std::vector<Register> result;
75 result.push_back({"x0", ARM64_REG_R0});
76 result.push_back({"x1", ARM64_REG_R1});
77 result.push_back({"x2", ARM64_REG_R2});
78 result.push_back({"x3", ARM64_REG_R3});
79 result.push_back({"x4", ARM64_REG_R4});
80 result.push_back({"x5", ARM64_REG_R5});
81 result.push_back({"x6", ARM64_REG_R6});
82 result.push_back({"x7", ARM64_REG_R7});
83 result.push_back({"x8", ARM64_REG_R8});
84 result.push_back({"x9", ARM64_REG_R9});
85 result.push_back({"x10", ARM64_REG_R10});
86 result.push_back({"x11", ARM64_REG_R11});
87 result.push_back({"x12", ARM64_REG_R12});
88 result.push_back({"x13", ARM64_REG_R13});
89 result.push_back({"x14", ARM64_REG_R14});
90 result.push_back({"x15", ARM64_REG_R15});
91 result.push_back({"x16", ARM64_REG_R16});
92 result.push_back({"x17", ARM64_REG_R17});
93 result.push_back({"x18", ARM64_REG_R18});
94 result.push_back({"x19", ARM64_REG_R19});
95 result.push_back({"x20", ARM64_REG_R20});
96 result.push_back({"x21", ARM64_REG_R21});
97 result.push_back({"x22", ARM64_REG_R22});
98 result.push_back({"x23", ARM64_REG_R23});
99 result.push_back({"x24", ARM64_REG_R24});
100 result.push_back({"x25", ARM64_REG_R25});
101 result.push_back({"x26", ARM64_REG_R26});
102 result.push_back({"x27", ARM64_REG_R27});
103 result.push_back({"x28", ARM64_REG_R28});
104 result.push_back({"x29", ARM64_REG_R29});
105 result.push_back({"sp", ARM64_REG_SP});
106 result.push_back({"lr", ARM64_REG_LR});
107 result.push_back({"pc", ARM64_REG_PC});
108 return result;
109}
110
111template<>
112std::vector<Register> ExpectedRegisters<RegsX86>() {
113 std::vector<Register> result;
114 result.push_back({"eax", X86_REG_EAX});
115 result.push_back({"ebx", X86_REG_EBX});
116 result.push_back({"ecx", X86_REG_ECX});
117 result.push_back({"edx", X86_REG_EDX});
118 result.push_back({"ebp", X86_REG_EBP});
119 result.push_back({"edi", X86_REG_EDI});
120 result.push_back({"esi", X86_REG_ESI});
121 result.push_back({"esp", X86_REG_ESP});
122 result.push_back({"eip", X86_REG_EIP});
123 return result;
124}
125
126template<>
127std::vector<Register> ExpectedRegisters<RegsX86_64>() {
128 std::vector<Register> result;
129 result.push_back({"rax", X86_64_REG_RAX});
130 result.push_back({"rbx", X86_64_REG_RBX});
131 result.push_back({"rcx", X86_64_REG_RCX});
132 result.push_back({"rdx", X86_64_REG_RDX});
133 result.push_back({"r8", X86_64_REG_R8});
134 result.push_back({"r9", X86_64_REG_R9});
135 result.push_back({"r10", X86_64_REG_R10});
136 result.push_back({"r11", X86_64_REG_R11});
137 result.push_back({"r12", X86_64_REG_R12});
138 result.push_back({"r13", X86_64_REG_R13});
139 result.push_back({"r14", X86_64_REG_R14});
140 result.push_back({"r15", X86_64_REG_R15});
141 result.push_back({"rdi", X86_64_REG_RDI});
142 result.push_back({"rsi", X86_64_REG_RSI});
143 result.push_back({"rbp", X86_64_REG_RBP});
144 result.push_back({"rsp", X86_64_REG_RSP});
145 result.push_back({"rip", X86_64_REG_RIP});
146 return result;
147}
148
149using RegTypes = ::testing::Types<RegsArm, RegsArm64, RegsX86, RegsX86_64>;
150TYPED_TEST_CASE(RegsIterateTest, RegTypes);
151
152TYPED_TEST(RegsIterateTest, iterate) {
153 std::vector<Register> expected = ExpectedRegisters<TypeParam>();
154 TypeParam regs;
155 for (const auto& reg : expected) {
156 regs[reg.offset] = reg.offset;
157 }
158
159 std::vector<Register> actual;
160 regs.IterateRegisters([&actual](const char* name, uint64_t value) {
161 actual.push_back({name, value});
162 });
163
164 ASSERT_EQ(expected, actual);
165}
166
167} // namespace unwindstack