• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- RegisterContextMinidumpTest.cpp -----------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
10 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
11 #include "Plugins/Process/minidump/RegisterContextMinidump_x86_32.h"
12 #include "Plugins/Process/minidump/RegisterContextMinidump_x86_64.h"
13 #include "Plugins/Process/minidump/RegisterContextMinidump_ARM.h"
14 #include "lldb/Utility/DataBuffer.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "gtest/gtest.h"
17 
18 using namespace lldb_private;
19 using namespace lldb_private::minidump;
20 
reg32(const DataBuffer & Buf,const RegisterInfo & Info)21 static uint32_t reg32(const DataBuffer &Buf, const RegisterInfo &Info) {
22   return *reinterpret_cast<const uint32_t *>(Buf.GetBytes() + Info.byte_offset);
23 }
24 
reg64(const DataBuffer & Buf,const RegisterInfo & Info)25 static uint64_t reg64(const DataBuffer &Buf, const RegisterInfo &Info) {
26   return *reinterpret_cast<const uint64_t *>(Buf.GetBytes() + Info.byte_offset);
27 }
28 
TEST(RegisterContextMinidump,ConvertMinidumpContext_x86_32)29 TEST(RegisterContextMinidump, ConvertMinidumpContext_x86_32) {
30   MinidumpContext_x86_32 Context;
31   Context.context_flags =
32       static_cast<uint32_t>(MinidumpContext_x86_32_Flags::x86_32_Flag |
33                             MinidumpContext_x86_32_Flags::Control |
34                             MinidumpContext_x86_32_Flags::Segments |
35                             MinidumpContext_x86_32_Flags::Integer);
36   Context.eax = 0x00010203;
37   Context.ebx = 0x04050607;
38   Context.ecx = 0x08090a0b;
39   Context.edx = 0x0c0d0e0f;
40   Context.edi = 0x10111213;
41   Context.esi = 0x14151617;
42   Context.ebp = 0x18191a1b;
43   Context.esp = 0x1c1d1e1f;
44   Context.eip = 0x20212223;
45   Context.eflags = 0x24252627;
46   Context.cs = 0x2829;
47   Context.fs = 0x2a2b;
48   Context.gs = 0x2c2d;
49   Context.ss = 0x2e2f;
50   Context.ds = 0x3031;
51   Context.es = 0x3233;
52   llvm::ArrayRef<uint8_t> ContextRef(reinterpret_cast<uint8_t *>(&Context),
53                                      sizeof(Context));
54 
55   ArchSpec arch("i386-pc-linux");
56   auto RegInterface = std::make_unique<RegisterContextLinux_i386>(arch);
57   lldb::DataBufferSP Buf =
58       ConvertMinidumpContext_x86_32(ContextRef, RegInterface.get());
59   ASSERT_EQ(RegInterface->GetGPRSize(), Buf->GetByteSize());
60 
61   const RegisterInfo *Info = RegInterface->GetRegisterInfo();
62   ASSERT_NE(nullptr, Info);
63 
64   EXPECT_EQ(Context.eax, reg32(*Buf, Info[lldb_eax_i386]));
65   EXPECT_EQ(Context.ebx, reg32(*Buf, Info[lldb_ebx_i386]));
66   EXPECT_EQ(Context.ecx, reg32(*Buf, Info[lldb_ecx_i386]));
67   EXPECT_EQ(Context.edx, reg32(*Buf, Info[lldb_edx_i386]));
68   EXPECT_EQ(Context.edi, reg32(*Buf, Info[lldb_edi_i386]));
69   EXPECT_EQ(Context.esi, reg32(*Buf, Info[lldb_esi_i386]));
70   EXPECT_EQ(Context.ebp, reg32(*Buf, Info[lldb_ebp_i386]));
71   EXPECT_EQ(Context.esp, reg32(*Buf, Info[lldb_esp_i386]));
72   EXPECT_EQ(Context.eip, reg32(*Buf, Info[lldb_eip_i386]));
73   EXPECT_EQ(Context.eflags, reg32(*Buf, Info[lldb_eflags_i386]));
74   EXPECT_EQ(Context.cs, reg32(*Buf, Info[lldb_cs_i386]));
75   EXPECT_EQ(Context.fs, reg32(*Buf, Info[lldb_fs_i386]));
76   EXPECT_EQ(Context.gs, reg32(*Buf, Info[lldb_gs_i386]));
77   EXPECT_EQ(Context.ss, reg32(*Buf, Info[lldb_ss_i386]));
78   EXPECT_EQ(Context.ds, reg32(*Buf, Info[lldb_ds_i386]));
79   EXPECT_EQ(Context.es, reg32(*Buf, Info[lldb_es_i386]));
80 }
81 
TEST(RegisterContextMinidump,ConvertMinidumpContext_x86_64)82 TEST(RegisterContextMinidump, ConvertMinidumpContext_x86_64) {
83   MinidumpContext_x86_64 Context;
84   Context.context_flags =
85       static_cast<uint32_t>(MinidumpContext_x86_64_Flags::x86_64_Flag |
86                             MinidumpContext_x86_64_Flags::Control |
87                             MinidumpContext_x86_64_Flags::Segments |
88                             MinidumpContext_x86_64_Flags::Integer);
89   Context.rax = 0x0001020304050607;
90   Context.rbx = 0x08090a0b0c0d0e0f;
91   Context.rcx = 0x1011121314151617;
92   Context.rdx = 0x18191a1b1c1d1e1f;
93   Context.rdi = 0x2021222324252627;
94   Context.rsi = 0x28292a2b2c2d2e2f;
95   Context.rbp = 0x3031323334353637;
96   Context.rsp = 0x38393a3b3c3d3e3f;
97   Context.r8 = 0x4041424344454647;
98   Context.r9 = 0x48494a4b4c4d4e4f;
99   Context.r10 = 0x5051525354555657;
100   Context.r11 = 0x58595a5b5c5d5e5f;
101   Context.r12 = 0x6061626364656667;
102   Context.r13 = 0x68696a6b6c6d6e6f;
103   Context.r14 = 0x7071727374757677;
104   Context.r15 = 0x78797a7b7c7d7e7f;
105   Context.rip = 0x8081828384858687;
106   Context.eflags = 0x88898a8b;
107   Context.cs = 0x8c8d;
108   Context.fs = 0x8e8f;
109   Context.gs = 0x9091;
110   Context.ss = 0x9293;
111   Context.ds = 0x9495;
112   Context.ss = 0x9697;
113   llvm::ArrayRef<uint8_t> ContextRef(reinterpret_cast<uint8_t *>(&Context),
114                                      sizeof(Context));
115 
116   ArchSpec arch("x86_64-pc-linux");
117   auto RegInterface = std::make_unique<RegisterContextLinux_x86_64>(arch);
118   lldb::DataBufferSP Buf =
119       ConvertMinidumpContext_x86_64(ContextRef, RegInterface.get());
120   ASSERT_EQ(RegInterface->GetGPRSize(), Buf->GetByteSize());
121 
122   const RegisterInfo *Info = RegInterface->GetRegisterInfo();
123   EXPECT_EQ(Context.rax, reg64(*Buf, Info[lldb_rax_x86_64]));
124   EXPECT_EQ(Context.rbx, reg64(*Buf, Info[lldb_rbx_x86_64]));
125   EXPECT_EQ(Context.rcx, reg64(*Buf, Info[lldb_rcx_x86_64]));
126   EXPECT_EQ(Context.rdx, reg64(*Buf, Info[lldb_rdx_x86_64]));
127   EXPECT_EQ(Context.rdi, reg64(*Buf, Info[lldb_rdi_x86_64]));
128   EXPECT_EQ(Context.rsi, reg64(*Buf, Info[lldb_rsi_x86_64]));
129   EXPECT_EQ(Context.rbp, reg64(*Buf, Info[lldb_rbp_x86_64]));
130   EXPECT_EQ(Context.rsp, reg64(*Buf, Info[lldb_rsp_x86_64]));
131   EXPECT_EQ(Context.r8, reg64(*Buf, Info[lldb_r8_x86_64]));
132   EXPECT_EQ(Context.r9, reg64(*Buf, Info[lldb_r9_x86_64]));
133   EXPECT_EQ(Context.r10, reg64(*Buf, Info[lldb_r10_x86_64]));
134   EXPECT_EQ(Context.r11, reg64(*Buf, Info[lldb_r11_x86_64]));
135   EXPECT_EQ(Context.r12, reg64(*Buf, Info[lldb_r12_x86_64]));
136   EXPECT_EQ(Context.r13, reg64(*Buf, Info[lldb_r13_x86_64]));
137   EXPECT_EQ(Context.r14, reg64(*Buf, Info[lldb_r14_x86_64]));
138   EXPECT_EQ(Context.r15, reg64(*Buf, Info[lldb_r15_x86_64]));
139   EXPECT_EQ(Context.rip, reg64(*Buf, Info[lldb_rip_x86_64]));
140   EXPECT_EQ(Context.eflags, reg64(*Buf, Info[lldb_rflags_x86_64]));
141   EXPECT_EQ(Context.cs, reg64(*Buf, Info[lldb_cs_x86_64]));
142   EXPECT_EQ(Context.fs, reg64(*Buf, Info[lldb_fs_x86_64]));
143   EXPECT_EQ(Context.gs, reg64(*Buf, Info[lldb_gs_x86_64]));
144   EXPECT_EQ(Context.ss, reg64(*Buf, Info[lldb_ss_x86_64]));
145   EXPECT_EQ(Context.ds, reg64(*Buf, Info[lldb_ds_x86_64]));
146   EXPECT_EQ(Context.es, reg64(*Buf, Info[lldb_es_x86_64]));
147 }
148 
TestARMRegInfo(const lldb_private::RegisterInfo * info)149 static void TestARMRegInfo(const lldb_private::RegisterInfo *info) {
150   // Make sure we have valid register numbers for eRegisterKindEHFrame and
151   // eRegisterKindDWARF for GPR registers r0-r15 so that we can unwind
152   // correctly when using this information.
153   llvm::StringRef name(info->name);
154   llvm::StringRef alt_name(info->alt_name);
155   if (name.startswith("r") || alt_name.startswith("r")) {
156     EXPECT_NE(info->kinds[lldb::eRegisterKindEHFrame], LLDB_INVALID_REGNUM);
157     EXPECT_NE(info->kinds[lldb::eRegisterKindDWARF], LLDB_INVALID_REGNUM);
158   }
159   // Verify generic register are set correctly
160   if (name == "r0") {
161     EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric],
162               (uint32_t)LLDB_REGNUM_GENERIC_ARG1);
163   } else if (name == "r1") {
164     EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric],
165               (uint32_t)LLDB_REGNUM_GENERIC_ARG2);
166   } else if (name == "r2") {
167     EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric],
168               (uint32_t)LLDB_REGNUM_GENERIC_ARG3);
169   } else if (name == "r3") {
170     EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric],
171               (uint32_t)LLDB_REGNUM_GENERIC_ARG4);
172   } else if (name == "sp") {
173     EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric],
174               (uint32_t)LLDB_REGNUM_GENERIC_SP);
175   } else if (name == "fp") {
176     EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric],
177               (uint32_t)LLDB_REGNUM_GENERIC_FP);
178   } else if (name == "lr") {
179     EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric],
180               (uint32_t)LLDB_REGNUM_GENERIC_RA);
181   } else if (name == "pc") {
182     EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric],
183               (uint32_t)LLDB_REGNUM_GENERIC_PC);
184   } else if (name == "cpsr") {
185     EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric],
186               (uint32_t)LLDB_REGNUM_GENERIC_FLAGS);
187   }
188 }
189 
TEST(RegisterContextMinidump,CheckRegisterContextMinidump_ARM)190 TEST(RegisterContextMinidump, CheckRegisterContextMinidump_ARM) {
191   size_t num_regs = RegisterContextMinidump_ARM::GetRegisterCountStatic();
192   const lldb_private::RegisterInfo *reg_info;
193   for (size_t reg=0; reg<num_regs; ++reg) {
194     reg_info = RegisterContextMinidump_ARM::GetRegisterInfoAtIndexStatic(reg,
195                                                                          true);
196     TestARMRegInfo(reg_info);
197     reg_info = RegisterContextMinidump_ARM::GetRegisterInfoAtIndexStatic(reg,
198                                                                          false);
199     TestARMRegInfo(reg_info);
200   }
201 }
202