1 //===-- RegisterContextMinidumpTest.cpp -----------------------------------===//
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
7 //===----------------------------------------------------------------------===//
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"
18 using namespace lldb_private
;
19 using namespace lldb_private::minidump
;
21 static uint32_t reg32(const DataBuffer
&Buf
, const RegisterInfo
&Info
) {
22 return *reinterpret_cast<const uint32_t *>(Buf
.GetBytes() + Info
.byte_offset
);
25 static uint64_t reg64(const DataBuffer
&Buf
, const RegisterInfo
&Info
) {
26 return *reinterpret_cast<const uint64_t *>(Buf
.GetBytes() + Info
.byte_offset
);
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;
52 llvm::ArrayRef
<uint8_t> ContextRef(reinterpret_cast<uint8_t *>(&Context
),
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());
61 const RegisterInfo
*Info
= RegInterface
->GetRegisterInfo();
62 ASSERT_NE(nullptr, Info
);
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
]));
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;
113 llvm::ArrayRef
<uint8_t> ContextRef(reinterpret_cast<uint8_t *>(&Context
),
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());
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
]));
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
.starts_with("r") || alt_name
.starts_with("r")) {
156 EXPECT_NE(info
->kinds
[lldb::eRegisterKindEHFrame
], LLDB_INVALID_REGNUM
);
157 EXPECT_NE(info
->kinds
[lldb::eRegisterKindDWARF
], LLDB_INVALID_REGNUM
);
159 // Verify generic register are set correctly
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
);
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
,
196 TestARMRegInfo(reg_info
);
197 reg_info
= RegisterContextMinidump_ARM::GetRegisterInfoAtIndexStatic(reg
,
199 TestARMRegInfo(reg_info
);