1 //===-- RegisterContextMinidump_x86_32.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_32_H
10 #define LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_X86_32_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_32(llvm::ArrayRef<uint8_t> source_data,
36                               RegisterInfoInterface *target_reg_interface);
37 
38 // Reference: see breakpad/crashpad source or WinNT.h
39 struct MinidumpFloatingSaveAreaX86 {
40   llvm::support::ulittle32_t control_word;
41   llvm::support::ulittle32_t status_word;
42   llvm::support::ulittle32_t tag_word;
43   llvm::support::ulittle32_t error_offset;
44   llvm::support::ulittle32_t error_selector;
45   llvm::support::ulittle32_t data_offset;
46   llvm::support::ulittle32_t data_selector;
47 
48   enum {
49     RegisterAreaSize = 80,
50   };
51   // register_area contains eight 80-bit (x87 "long double") quantities for
52   // floating-point registers %st0 (%mm0) through %st7 (%mm7).
53   uint8_t register_area[RegisterAreaSize];
54   llvm::support::ulittle32_t cr0_npx_state;
55 };
56 
57 struct MinidumpContext_x86_32 {
58   // The context_flags field determines which parts
59   // of the structure are populated (have valid values)
60   llvm::support::ulittle32_t context_flags;
61 
62   // The next 6 registers are included with
63   // MinidumpContext_x86_32_Flags::DebugRegisters
64   llvm::support::ulittle32_t dr0;
65   llvm::support::ulittle32_t dr1;
66   llvm::support::ulittle32_t dr2;
67   llvm::support::ulittle32_t dr3;
68   llvm::support::ulittle32_t dr6;
69   llvm::support::ulittle32_t dr7;
70 
71   // The next field is included with
72   // MinidumpContext_x86_32_Flags::FloatingPoint
73   MinidumpFloatingSaveAreaX86 float_save;
74 
75   // The next 4 registers are included with
76   // MinidumpContext_x86_32_Flags::Segments
77   llvm::support::ulittle32_t gs;
78   llvm::support::ulittle32_t fs;
79   llvm::support::ulittle32_t es;
80   llvm::support::ulittle32_t ds;
81 
82   // The next 6 registers are included with
83   // MinidumpContext_x86_32_Flags::Integer
84   llvm::support::ulittle32_t edi;
85   llvm::support::ulittle32_t esi;
86   llvm::support::ulittle32_t ebx;
87   llvm::support::ulittle32_t edx;
88   llvm::support::ulittle32_t ecx;
89   llvm::support::ulittle32_t eax;
90 
91   // The next 6 registers are included with
92   // MinidumpContext_x86_32_Flags::Control
93   llvm::support::ulittle32_t ebp;
94   llvm::support::ulittle32_t eip;
95   llvm::support::ulittle32_t cs;     // WinNT.h says "must be sanitized"
96   llvm::support::ulittle32_t eflags; // WinNT.h says "must be sanitized"
97   llvm::support::ulittle32_t esp;
98   llvm::support::ulittle32_t ss;
99 
100   // The next field is included with
101   // MinidumpContext_x86_32_Flags::ExtendedRegisters
102   // It contains vector (MMX/SSE) registers.  It is laid out in the
103   // format used by the fxsave and fsrstor instructions, so it includes
104   // a copy of the x87 floating-point registers as well.  See FXSAVE in
105   // "Intel Architecture Software Developer's Manual, Volume 2."
106   enum {
107     ExtendedRegistersSize = 512,
108   };
109   uint8_t extended_registers[ExtendedRegistersSize];
110 };
111 
112 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
113 
114 // For context_flags. These values indicate the type of
115 // context stored in the structure. The high 24 bits identify the CPU, the
116 // low 8 bits identify the type of context saved.
117 enum class MinidumpContext_x86_32_Flags : uint32_t {
118   x86_32_Flag = 0x00010000, // CONTEXT_i386, CONTEXT_i486
119   Control = x86_32_Flag | 0x00000001,
120   Integer = x86_32_Flag | 0x00000002,
121   Segments = x86_32_Flag | 0x00000004,
122   FloatingPoint = x86_32_Flag | 0x00000008,
123   DebugRegisters = x86_32_Flag | 0x00000010,
124   ExtendedRegisters = x86_32_Flag | 0x00000020,
125   XState = x86_32_Flag | 0x00000040,
126 
127   Full = Control | Integer | Segments,
128   All = Full | FloatingPoint | DebugRegisters | ExtendedRegisters,
129 
130   LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ All)
131 };
132 
133 } // end namespace minidump
134 } // end namespace lldb_private
135 #endif // LLDB_SOURCE_PLUGINS_PROCESS_MINIDUMP_REGISTERCONTEXTMINIDUMP_X86_32_H
136