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 47 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<> 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<> 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({"sp", ARM64_REG_SP}); 115 result.push_back({"lr", ARM64_REG_LR}); 116 result.push_back({"pc", ARM64_REG_PC}); 117 return result; 118 } 119 120 template<> 121 std::vector<Register> ExpectedRegisters<RegsX86>() { 122 std::vector<Register> result; 123 result.push_back({"eax", X86_REG_EAX}); 124 result.push_back({"ebx", X86_REG_EBX}); 125 result.push_back({"ecx", X86_REG_ECX}); 126 result.push_back({"edx", X86_REG_EDX}); 127 result.push_back({"ebp", X86_REG_EBP}); 128 result.push_back({"edi", X86_REG_EDI}); 129 result.push_back({"esi", X86_REG_ESI}); 130 result.push_back({"esp", X86_REG_ESP}); 131 result.push_back({"eip", X86_REG_EIP}); 132 return result; 133 } 134 135 template<> 136 std::vector<Register> ExpectedRegisters<RegsX86_64>() { 137 std::vector<Register> result; 138 result.push_back({"rax", X86_64_REG_RAX}); 139 result.push_back({"rbx", X86_64_REG_RBX}); 140 result.push_back({"rcx", X86_64_REG_RCX}); 141 result.push_back({"rdx", X86_64_REG_RDX}); 142 result.push_back({"r8", X86_64_REG_R8}); 143 result.push_back({"r9", X86_64_REG_R9}); 144 result.push_back({"r10", X86_64_REG_R10}); 145 result.push_back({"r11", X86_64_REG_R11}); 146 result.push_back({"r12", X86_64_REG_R12}); 147 result.push_back({"r13", X86_64_REG_R13}); 148 result.push_back({"r14", X86_64_REG_R14}); 149 result.push_back({"r15", X86_64_REG_R15}); 150 result.push_back({"rdi", X86_64_REG_RDI}); 151 result.push_back({"rsi", X86_64_REG_RSI}); 152 result.push_back({"rbp", X86_64_REG_RBP}); 153 result.push_back({"rsp", X86_64_REG_RSP}); 154 result.push_back({"rip", X86_64_REG_RIP}); 155 return result; 156 } 157 158 template<> 159 std::vector<Register> ExpectedRegisters<RegsMips>() { 160 std::vector<Register> result; 161 result.push_back({"r0", MIPS_REG_R0}); 162 result.push_back({"r1", MIPS_REG_R1}); 163 result.push_back({"r2", MIPS_REG_R2}); 164 result.push_back({"r3", MIPS_REG_R3}); 165 result.push_back({"r4", MIPS_REG_R4}); 166 result.push_back({"r5", MIPS_REG_R5}); 167 result.push_back({"r6", MIPS_REG_R6}); 168 result.push_back({"r7", MIPS_REG_R7}); 169 result.push_back({"r8", MIPS_REG_R8}); 170 result.push_back({"r9", MIPS_REG_R9}); 171 result.push_back({"r10", MIPS_REG_R10}); 172 result.push_back({"r11", MIPS_REG_R11}); 173 result.push_back({"r12", MIPS_REG_R12}); 174 result.push_back({"r13", MIPS_REG_R13}); 175 result.push_back({"r14", MIPS_REG_R14}); 176 result.push_back({"r15", MIPS_REG_R15}); 177 result.push_back({"r16", MIPS_REG_R16}); 178 result.push_back({"r17", MIPS_REG_R17}); 179 result.push_back({"r18", MIPS_REG_R18}); 180 result.push_back({"r19", MIPS_REG_R19}); 181 result.push_back({"r20", MIPS_REG_R20}); 182 result.push_back({"r21", MIPS_REG_R21}); 183 result.push_back({"r22", MIPS_REG_R22}); 184 result.push_back({"r23", MIPS_REG_R23}); 185 result.push_back({"r24", MIPS_REG_R24}); 186 result.push_back({"r25", MIPS_REG_R25}); 187 result.push_back({"r26", MIPS_REG_R26}); 188 result.push_back({"r27", MIPS_REG_R27}); 189 result.push_back({"r28", MIPS_REG_R28}); 190 result.push_back({"sp", MIPS_REG_SP}); 191 result.push_back({"r30", MIPS_REG_R30}); 192 result.push_back({"ra", MIPS_REG_RA}); 193 result.push_back({"pc", MIPS_REG_PC}); 194 195 return result; 196 } 197 198 template<> 199 std::vector<Register> ExpectedRegisters<RegsMips64>() { 200 std::vector<Register> result; 201 result.push_back({"r0", MIPS64_REG_R0}); 202 result.push_back({"r1", MIPS64_REG_R1}); 203 result.push_back({"r2", MIPS64_REG_R2}); 204 result.push_back({"r3", MIPS64_REG_R3}); 205 result.push_back({"r4", MIPS64_REG_R4}); 206 result.push_back({"r5", MIPS64_REG_R5}); 207 result.push_back({"r6", MIPS64_REG_R6}); 208 result.push_back({"r7", MIPS64_REG_R7}); 209 result.push_back({"r8", MIPS64_REG_R8}); 210 result.push_back({"r9", MIPS64_REG_R9}); 211 result.push_back({"r10", MIPS64_REG_R10}); 212 result.push_back({"r11", MIPS64_REG_R11}); 213 result.push_back({"r12", MIPS64_REG_R12}); 214 result.push_back({"r13", MIPS64_REG_R13}); 215 result.push_back({"r14", MIPS64_REG_R14}); 216 result.push_back({"r15", MIPS64_REG_R15}); 217 result.push_back({"r16", MIPS64_REG_R16}); 218 result.push_back({"r17", MIPS64_REG_R17}); 219 result.push_back({"r18", MIPS64_REG_R18}); 220 result.push_back({"r19", MIPS64_REG_R19}); 221 result.push_back({"r20", MIPS64_REG_R20}); 222 result.push_back({"r21", MIPS64_REG_R21}); 223 result.push_back({"r22", MIPS64_REG_R22}); 224 result.push_back({"r23", MIPS64_REG_R23}); 225 result.push_back({"r24", MIPS64_REG_R24}); 226 result.push_back({"r25", MIPS64_REG_R25}); 227 result.push_back({"r26", MIPS64_REG_R26}); 228 result.push_back({"r27", MIPS64_REG_R27}); 229 result.push_back({"r28", MIPS64_REG_R28}); 230 result.push_back({"sp", MIPS64_REG_SP}); 231 result.push_back({"r30", MIPS64_REG_R30}); 232 result.push_back({"ra", MIPS64_REG_RA}); 233 result.push_back({"pc", MIPS64_REG_PC}); 234 235 return result; 236 } 237 238 using RegTypes = ::testing::Types<RegsArm, RegsArm64, RegsX86, RegsX86_64, RegsMips, RegsMips64>; 239 TYPED_TEST_CASE(RegsIterateTest, RegTypes); 240 241 TYPED_TEST(RegsIterateTest, iterate) { 242 std::vector<Register> expected = ExpectedRegisters<TypeParam>(); 243 TypeParam regs; 244 for (const auto& reg : expected) { 245 regs[reg.offset] = reg.offset; 246 } 247 248 std::vector<Register> actual; 249 regs.IterateRegisters([&actual](const char* name, uint64_t value) { 250 actual.push_back({name, value}); 251 }); 252 253 ASSERT_EQ(expected, actual); 254 } 255 256 } // namespace unwindstack 257