1 /*
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/MachineArm.h>
28 #include <unwindstack/MachineArm64.h>
29 #include <unwindstack/MachineMips.h>
30 #include <unwindstack/MachineMips64.h>
31 #include <unwindstack/MachineX86.h>
32 #include <unwindstack/MachineX86_64.h>
33 #include <unwindstack/MapInfo.h>
34 #include <unwindstack/RegsArm.h>
35 #include <unwindstack/RegsArm64.h>
36 #include <unwindstack/RegsMips.h>
37 #include <unwindstack/RegsMips64.h>
38 #include <unwindstack/RegsX86.h>
39 #include <unwindstack/RegsX86_64.h>
40 
41 namespace unwindstack {
42 
43 struct Register {
44   std::string expected_name;
45   uint64_t offset;
46 
operator ==unwindstack::Register47   bool operator==(const Register& rhs) const {
48     return std::tie(expected_name, offset) == std::tie(rhs.expected_name, rhs.offset);
49   }
50 };
51 
52 template<typename T>
53 class RegsIterateTest : public ::testing::Test {
54 };
55 
56 template<typename RegsType>
57 std::vector<Register> ExpectedRegisters();
58 
59 template<>
ExpectedRegisters()60 std::vector<Register> ExpectedRegisters<RegsArm>() {
61   std::vector<Register> result;
62   result.push_back({"r0", ARM_REG_R0});
63   result.push_back({"r1", ARM_REG_R1});
64   result.push_back({"r2", ARM_REG_R2});
65   result.push_back({"r3", ARM_REG_R3});
66   result.push_back({"r4", ARM_REG_R4});
67   result.push_back({"r5", ARM_REG_R5});
68   result.push_back({"r6", ARM_REG_R6});
69   result.push_back({"r7", ARM_REG_R7});
70   result.push_back({"r8", ARM_REG_R8});
71   result.push_back({"r9", ARM_REG_R9});
72   result.push_back({"r10", ARM_REG_R10});
73   result.push_back({"r11", ARM_REG_R11});
74   result.push_back({"ip", ARM_REG_R12});
75   result.push_back({"sp", ARM_REG_SP});
76   result.push_back({"lr", ARM_REG_LR});
77   result.push_back({"pc", ARM_REG_PC});
78   return result;
79 }
80 
81 template<>
ExpectedRegisters()82 std::vector<Register> ExpectedRegisters<RegsArm64>() {
83   std::vector<Register> result;
84   result.push_back({"x0", ARM64_REG_R0});
85   result.push_back({"x1", ARM64_REG_R1});
86   result.push_back({"x2", ARM64_REG_R2});
87   result.push_back({"x3", ARM64_REG_R3});
88   result.push_back({"x4", ARM64_REG_R4});
89   result.push_back({"x5", ARM64_REG_R5});
90   result.push_back({"x6", ARM64_REG_R6});
91   result.push_back({"x7", ARM64_REG_R7});
92   result.push_back({"x8", ARM64_REG_R8});
93   result.push_back({"x9", ARM64_REG_R9});
94   result.push_back({"x10", ARM64_REG_R10});
95   result.push_back({"x11", ARM64_REG_R11});
96   result.push_back({"x12", ARM64_REG_R12});
97   result.push_back({"x13", ARM64_REG_R13});
98   result.push_back({"x14", ARM64_REG_R14});
99   result.push_back({"x15", ARM64_REG_R15});
100   result.push_back({"x16", ARM64_REG_R16});
101   result.push_back({"x17", ARM64_REG_R17});
102   result.push_back({"x18", ARM64_REG_R18});
103   result.push_back({"x19", ARM64_REG_R19});
104   result.push_back({"x20", ARM64_REG_R20});
105   result.push_back({"x21", ARM64_REG_R21});
106   result.push_back({"x22", ARM64_REG_R22});
107   result.push_back({"x23", ARM64_REG_R23});
108   result.push_back({"x24", ARM64_REG_R24});
109   result.push_back({"x25", ARM64_REG_R25});
110   result.push_back({"x26", ARM64_REG_R26});
111   result.push_back({"x27", ARM64_REG_R27});
112   result.push_back({"x28", ARM64_REG_R28});
113   result.push_back({"x29", ARM64_REG_R29});
114   result.push_back({"lr", ARM64_REG_LR});
115   result.push_back({"sp", ARM64_REG_SP});
116   result.push_back({"pc", ARM64_REG_PC});
117   result.push_back({"pst", ARM64_REG_PSTATE});
118   return result;
119 }
120 
121 template<>
ExpectedRegisters()122 std::vector<Register> ExpectedRegisters<RegsX86>() {
123   std::vector<Register> result;
124   result.push_back({"eax", X86_REG_EAX});
125   result.push_back({"ebx", X86_REG_EBX});
126   result.push_back({"ecx", X86_REG_ECX});
127   result.push_back({"edx", X86_REG_EDX});
128   result.push_back({"ebp", X86_REG_EBP});
129   result.push_back({"edi", X86_REG_EDI});
130   result.push_back({"esi", X86_REG_ESI});
131   result.push_back({"esp", X86_REG_ESP});
132   result.push_back({"eip", X86_REG_EIP});
133   return result;
134 }
135 
136 template<>
ExpectedRegisters()137 std::vector<Register> ExpectedRegisters<RegsX86_64>() {
138   std::vector<Register> result;
139   result.push_back({"rax", X86_64_REG_RAX});
140   result.push_back({"rbx", X86_64_REG_RBX});
141   result.push_back({"rcx", X86_64_REG_RCX});
142   result.push_back({"rdx", X86_64_REG_RDX});
143   result.push_back({"r8", X86_64_REG_R8});
144   result.push_back({"r9", X86_64_REG_R9});
145   result.push_back({"r10", X86_64_REG_R10});
146   result.push_back({"r11", X86_64_REG_R11});
147   result.push_back({"r12", X86_64_REG_R12});
148   result.push_back({"r13", X86_64_REG_R13});
149   result.push_back({"r14", X86_64_REG_R14});
150   result.push_back({"r15", X86_64_REG_R15});
151   result.push_back({"rdi", X86_64_REG_RDI});
152   result.push_back({"rsi", X86_64_REG_RSI});
153   result.push_back({"rbp", X86_64_REG_RBP});
154   result.push_back({"rsp", X86_64_REG_RSP});
155   result.push_back({"rip", X86_64_REG_RIP});
156   return result;
157 }
158 
159 template<>
ExpectedRegisters()160 std::vector<Register> ExpectedRegisters<RegsMips>() {
161   std::vector<Register> result;
162   result.push_back({"r0", MIPS_REG_R0});
163   result.push_back({"r1", MIPS_REG_R1});
164   result.push_back({"r2", MIPS_REG_R2});
165   result.push_back({"r3", MIPS_REG_R3});
166   result.push_back({"r4", MIPS_REG_R4});
167   result.push_back({"r5", MIPS_REG_R5});
168   result.push_back({"r6", MIPS_REG_R6});
169   result.push_back({"r7", MIPS_REG_R7});
170   result.push_back({"r8", MIPS_REG_R8});
171   result.push_back({"r9", MIPS_REG_R9});
172   result.push_back({"r10", MIPS_REG_R10});
173   result.push_back({"r11", MIPS_REG_R11});
174   result.push_back({"r12", MIPS_REG_R12});
175   result.push_back({"r13", MIPS_REG_R13});
176   result.push_back({"r14", MIPS_REG_R14});
177   result.push_back({"r15", MIPS_REG_R15});
178   result.push_back({"r16", MIPS_REG_R16});
179   result.push_back({"r17", MIPS_REG_R17});
180   result.push_back({"r18", MIPS_REG_R18});
181   result.push_back({"r19", MIPS_REG_R19});
182   result.push_back({"r20", MIPS_REG_R20});
183   result.push_back({"r21", MIPS_REG_R21});
184   result.push_back({"r22", MIPS_REG_R22});
185   result.push_back({"r23", MIPS_REG_R23});
186   result.push_back({"r24", MIPS_REG_R24});
187   result.push_back({"r25", MIPS_REG_R25});
188   result.push_back({"r26", MIPS_REG_R26});
189   result.push_back({"r27", MIPS_REG_R27});
190   result.push_back({"r28", MIPS_REG_R28});
191   result.push_back({"sp", MIPS_REG_SP});
192   result.push_back({"r30", MIPS_REG_R30});
193   result.push_back({"ra", MIPS_REG_RA});
194   result.push_back({"pc", MIPS_REG_PC});
195 
196   return result;
197 }
198 
199 template<>
ExpectedRegisters()200 std::vector<Register> ExpectedRegisters<RegsMips64>() {
201   std::vector<Register> result;
202   result.push_back({"r0", MIPS64_REG_R0});
203   result.push_back({"r1", MIPS64_REG_R1});
204   result.push_back({"r2", MIPS64_REG_R2});
205   result.push_back({"r3", MIPS64_REG_R3});
206   result.push_back({"r4", MIPS64_REG_R4});
207   result.push_back({"r5", MIPS64_REG_R5});
208   result.push_back({"r6", MIPS64_REG_R6});
209   result.push_back({"r7", MIPS64_REG_R7});
210   result.push_back({"r8", MIPS64_REG_R8});
211   result.push_back({"r9", MIPS64_REG_R9});
212   result.push_back({"r10", MIPS64_REG_R10});
213   result.push_back({"r11", MIPS64_REG_R11});
214   result.push_back({"r12", MIPS64_REG_R12});
215   result.push_back({"r13", MIPS64_REG_R13});
216   result.push_back({"r14", MIPS64_REG_R14});
217   result.push_back({"r15", MIPS64_REG_R15});
218   result.push_back({"r16", MIPS64_REG_R16});
219   result.push_back({"r17", MIPS64_REG_R17});
220   result.push_back({"r18", MIPS64_REG_R18});
221   result.push_back({"r19", MIPS64_REG_R19});
222   result.push_back({"r20", MIPS64_REG_R20});
223   result.push_back({"r21", MIPS64_REG_R21});
224   result.push_back({"r22", MIPS64_REG_R22});
225   result.push_back({"r23", MIPS64_REG_R23});
226   result.push_back({"r24", MIPS64_REG_R24});
227   result.push_back({"r25", MIPS64_REG_R25});
228   result.push_back({"r26", MIPS64_REG_R26});
229   result.push_back({"r27", MIPS64_REG_R27});
230   result.push_back({"r28", MIPS64_REG_R28});
231   result.push_back({"sp", MIPS64_REG_SP});
232   result.push_back({"r30", MIPS64_REG_R30});
233   result.push_back({"ra", MIPS64_REG_RA});
234   result.push_back({"pc", MIPS64_REG_PC});
235 
236   return result;
237 }
238 
239 using RegTypes = ::testing::Types<RegsArm, RegsArm64, RegsX86, RegsX86_64, RegsMips, RegsMips64>;
240 TYPED_TEST_SUITE(RegsIterateTest, RegTypes);
241 
TYPED_TEST(RegsIterateTest,iterate)242 TYPED_TEST(RegsIterateTest, iterate) {
243   std::vector<Register> expected = ExpectedRegisters<TypeParam>();
244   TypeParam regs;
245   for (const auto& reg : expected) {
246     regs[reg.offset] = reg.offset;
247   }
248 
249   std::vector<Register> actual;
250   regs.IterateRegisters([&actual](const char* name, uint64_t value) {
251     actual.push_back({name, value});
252   });
253 
254   ASSERT_EQ(expected, actual);
255 }
256 
257 }  // namespace unwindstack
258