1 //===-- RegisterContextMinidump_x86_64.h ------------------------*- C++ -*-===//
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 #ifndef LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_X86_64_H
10 #define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_X86_64_H
11 
12 #include "MinidumpTypes.h"
13 
14 #include "Plugins/Process/Utility/RegisterInfoInterface.h"
15 #include "Plugins/Process/Utility/lldb-x86-register-enums.h"
16 
17 #include "lldb/Target/RegisterContext.h"
18 
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/BitmaskEnum.h"
21 #include "llvm/Support/Endian.h"
22 
23 // C includes
24 // C++ includes
25 
26 namespace lldb_private {
27 
28 namespace minidump {
29 
30 // This function receives an ArrayRef pointing to the bytes of the Minidump
31 // register context and returns a DataBuffer that's ordered by the offsets
32 // specified in the RegisterInfoInterface argument
33 // This way we can reuse the already existing register contexts
34 lldb::DataBufferSP
35 ConvertMinidumpContext_x86_64(llvm::ArrayRef<uint8_t> source_data,
36                               RegisterInfoInterface *target_reg_interface);
37 
38 struct Uint128 {
39   llvm::support::ulittle64_t high;
40   llvm::support::ulittle64_t low;
41 };
42 
43 // Reference: see breakpad/crashpad source or WinNT.h
44 struct MinidumpXMMSaveArea32AMD64 {
45   llvm::support::ulittle16_t control_word;
46   llvm::support::ulittle16_t status_word;
47   uint8_t tag_word;
48   uint8_t reserved1;
49   llvm::support::ulittle16_t error_opcode;
50   llvm::support::ulittle32_t error_offset;
51   llvm::support::ulittle16_t error_selector;
52   llvm::support::ulittle16_t reserved2;
53   llvm::support::ulittle32_t data_offset;
54   llvm::support::ulittle16_t data_selector;
55   llvm::support::ulittle16_t reserved3;
56   llvm::support::ulittle32_t mx_csr;
57   llvm::support::ulittle32_t mx_csr_mask;
58   Uint128 float_registers[8];
59   Uint128 xmm_registers[16];
60   uint8_t reserved4[96];
61 };
62 
63 struct MinidumpContext_x86_64 {
64   // Register parameter home addresses.
65   llvm::support::ulittle64_t p1_home;
66   llvm::support::ulittle64_t p2_home;
67   llvm::support::ulittle64_t p3_home;
68   llvm::support::ulittle64_t p4_home;
69   llvm::support::ulittle64_t p5_home;
70   llvm::support::ulittle64_t p6_home;
71 
72   // The context_flags field determines which parts
73   // of the structure are populated (have valid values)
74   llvm::support::ulittle32_t context_flags;
75   llvm::support::ulittle32_t mx_csr;
76 
77   // The next register is included with
78   // MinidumpContext_x86_64_Flags::Control
79   llvm::support::ulittle16_t cs;
80 
81   // The next 4 registers are included with
82   // MinidumpContext_x86_64_Flags::Segments
83   llvm::support::ulittle16_t ds;
84   llvm::support::ulittle16_t es;
85   llvm::support::ulittle16_t fs;
86   llvm::support::ulittle16_t gs;
87 
88   // The next 2 registers are included with
89   // MinidumpContext_x86_64_Flags::Control
90   llvm::support::ulittle16_t ss;
91   llvm::support::ulittle32_t eflags;
92 
93   // The next 6 registers are included with
94   // MinidumpContext_x86_64_Flags::DebugRegisters
95   llvm::support::ulittle64_t dr0;
96   llvm::support::ulittle64_t dr1;
97   llvm::support::ulittle64_t dr2;
98   llvm::support::ulittle64_t dr3;
99   llvm::support::ulittle64_t dr6;
100   llvm::support::ulittle64_t dr7;
101 
102   // The next 4 registers are included with
103   // MinidumpContext_x86_64_Flags::Integer
104   llvm::support::ulittle64_t rax;
105   llvm::support::ulittle64_t rcx;
106   llvm::support::ulittle64_t rdx;
107   llvm::support::ulittle64_t rbx;
108 
109   // The next register is included with
110   // MinidumpContext_x86_64_Flags::Control
111   llvm::support::ulittle64_t rsp;
112 
113   // The next 11 registers are included with
114   // MinidumpContext_x86_64_Flags::Integer
115   llvm::support::ulittle64_t rbp;
116   llvm::support::ulittle64_t rsi;
117   llvm::support::ulittle64_t rdi;
118   llvm::support::ulittle64_t r8;
119   llvm::support::ulittle64_t r9;
120   llvm::support::ulittle64_t r10;
121   llvm::support::ulittle64_t r11;
122   llvm::support::ulittle64_t r12;
123   llvm::support::ulittle64_t r13;
124   llvm::support::ulittle64_t r14;
125   llvm::support::ulittle64_t r15;
126 
127   // The next register is included with
128   // MinidumpContext_x86_64_Flags::Control
129   llvm::support::ulittle64_t rip;
130 
131   // The next set of registers are included with
132   // MinidumpContext_x86_64_Flags:FloatingPoint
133   union FPR {
134     MinidumpXMMSaveArea32AMD64 flt_save;
135     struct {
136       Uint128 header[2];
137       Uint128 legacy[8];
138       Uint128 xmm[16];
139     } sse_registers;
140   };
141 
142   enum {
143     VRCount = 26,
144   };
145 
146   Uint128 vector_register[VRCount];
147   llvm::support::ulittle64_t vector_control;
148 
149   // The next 5 registers are included with
150   // MinidumpContext_x86_64_Flags::DebugRegisters
151   llvm::support::ulittle64_t debug_control;
152   llvm::support::ulittle64_t last_branch_to_rip;
153   llvm::support::ulittle64_t last_branch_from_rip;
154   llvm::support::ulittle64_t last_exception_to_rip;
155   llvm::support::ulittle64_t last_exception_from_rip;
156 };
157 
158 // For context_flags. These values indicate the type of
159 // context stored in the structure. The high 24 bits identify the CPU, the
160 // low 8 bits identify the type of context saved.
161 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
162 
163 enum class MinidumpContext_x86_64_Flags : uint32_t {
164   x86_64_Flag = 0x00100000,
165   Control = x86_64_Flag | 0x00000001,
166   Integer = x86_64_Flag | 0x00000002,
167   Segments = x86_64_Flag | 0x00000004,
168   FloatingPoint = x86_64_Flag | 0x00000008,
169   DebugRegisters = x86_64_Flag | 0x00000010,
170   XState = x86_64_Flag | 0x00000040,
171 
172   Full = Control | Integer | FloatingPoint,
173   All = Full | Segments | DebugRegisters,
174 
175   LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ All)
176 };
177 
178 } // end namespace minidump
179 } // end namespace lldb_private
180 #endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_X86_64_H
181