Home | History | Annotate | Download | only in tests
      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