xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1dda28197Spatrick //===-- RegisterContextLinux_i386.cpp -------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===---------------------------------------------------------------------===//
8061da546Spatrick 
9061da546Spatrick #include "RegisterContextLinux_i386.h"
10061da546Spatrick #include "RegisterContextPOSIX_x86.h"
11061da546Spatrick 
12061da546Spatrick using namespace lldb_private;
13061da546Spatrick using namespace lldb;
14061da546Spatrick 
15061da546Spatrick struct GPR {
16061da546Spatrick   uint32_t ebx;
17061da546Spatrick   uint32_t ecx;
18061da546Spatrick   uint32_t edx;
19061da546Spatrick   uint32_t esi;
20061da546Spatrick   uint32_t edi;
21061da546Spatrick   uint32_t ebp;
22061da546Spatrick   uint32_t eax;
23061da546Spatrick   uint32_t ds;
24061da546Spatrick   uint32_t es;
25061da546Spatrick   uint32_t fs;
26061da546Spatrick   uint32_t gs;
27061da546Spatrick   uint32_t orig_eax;
28061da546Spatrick   uint32_t eip;
29061da546Spatrick   uint32_t cs;
30061da546Spatrick   uint32_t eflags;
31061da546Spatrick   uint32_t esp;
32061da546Spatrick   uint32_t ss;
33061da546Spatrick };
34061da546Spatrick 
35061da546Spatrick struct FPR_i386 {
36061da546Spatrick   uint16_t fctrl;     // FPU Control Word (fcw)
37061da546Spatrick   uint16_t fstat;     // FPU Status Word (fsw)
38061da546Spatrick   uint16_t ftag;      // FPU Tag Word (ftw)
39061da546Spatrick   uint16_t fop;       // Last Instruction Opcode (fop)
40061da546Spatrick   union {
41061da546Spatrick     struct {
42061da546Spatrick       uint64_t fip; // Instruction Pointer
43061da546Spatrick       uint64_t fdp; // Data Pointer
44061da546Spatrick     } x86_64;
45061da546Spatrick     struct {
46061da546Spatrick       uint32_t fioff; // FPU IP Offset (fip)
47061da546Spatrick       uint32_t fiseg; // FPU IP Selector (fcs)
48061da546Spatrick       uint32_t fooff; // FPU Operand Pointer Offset (foo)
49061da546Spatrick       uint32_t foseg; // FPU Operand Pointer Selector (fos)
50061da546Spatrick     } i386_; // Added _ in the end to avoid error with gcc defining i386 in some
51061da546Spatrick              // cases
52061da546Spatrick   } ptr;
53061da546Spatrick   uint32_t mxcsr;     // MXCSR Register State
54061da546Spatrick   uint32_t mxcsrmask; // MXCSR Mask
55061da546Spatrick   MMSReg stmm[8];     // 8*16 bytes for each FP-reg = 128 bytes
56061da546Spatrick   XMMReg xmm[8];      // 8*16 bytes for each XMM-reg = 128 bytes
57061da546Spatrick   uint32_t padding[56];
58061da546Spatrick };
59061da546Spatrick 
60061da546Spatrick struct UserArea {
61061da546Spatrick   GPR regs;               // General purpose registers.
62061da546Spatrick   int32_t fpvalid;        // True if FPU is being used.
63061da546Spatrick   FPR_i386 i387;          // FPU registers.
64061da546Spatrick   uint32_t tsize;         // Text segment size.
65061da546Spatrick   uint32_t dsize;         // Data segment size.
66061da546Spatrick   uint32_t ssize;         // Stack segment size.
67061da546Spatrick   uint32_t start_code;    // VM address of text.
68061da546Spatrick   uint32_t start_stack;   // VM address of stack bottom (top in rsp).
69061da546Spatrick   int32_t signal;         // Signal causing core dump.
70061da546Spatrick   int32_t reserved;       // Unused.
71061da546Spatrick   uint32_t ar0;           // Location of GPR's.
72061da546Spatrick   uint32_t fpstate;       // Location of FPR's. Should be a FXSTATE *, but this
73061da546Spatrick                           //  has to be 32-bits even on 64-bit systems.
74061da546Spatrick   uint32_t magic;         // Identifier for core dumps.
75061da546Spatrick   char u_comm[32];        // Command causing core dump.
76061da546Spatrick   uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7).
77061da546Spatrick };
78061da546Spatrick 
79061da546Spatrick #define DR_SIZE sizeof(((UserArea *)NULL)->u_debugreg[0])
80061da546Spatrick #define DR_0_OFFSET 0xFC
81061da546Spatrick #define DR_OFFSET(reg_index) (DR_0_OFFSET + (reg_index * 4))
82061da546Spatrick #define FPR_SIZE(reg) sizeof(((FPR_i386 *)NULL)->reg)
83061da546Spatrick 
84061da546Spatrick // Include RegisterInfos_i386 to declare our g_register_infos_i386 structure.
85061da546Spatrick #define DECLARE_REGISTER_INFOS_I386_STRUCT
86061da546Spatrick #include "RegisterInfos_i386.h"
87061da546Spatrick #undef DECLARE_REGISTER_INFOS_I386_STRUCT
88061da546Spatrick 
RegisterContextLinux_i386(const ArchSpec & target_arch)89061da546Spatrick RegisterContextLinux_i386::RegisterContextLinux_i386(
90061da546Spatrick     const ArchSpec &target_arch)
91061da546Spatrick     : RegisterInfoInterface(target_arch) {
92*f6aab3d8Srobert   RegisterInfo orig_ax = {
93*f6aab3d8Srobert       "orig_eax",
94061da546Spatrick       nullptr,
95061da546Spatrick       sizeof(((GPR *)nullptr)->orig_eax),
96061da546Spatrick       (LLVM_EXTENSION offsetof(GPR, orig_eax)),
97061da546Spatrick       eEncodingUint,
98061da546Spatrick       eFormatHex,
99*f6aab3d8Srobert       {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
100*f6aab3d8Srobert        LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
101061da546Spatrick       nullptr,
102061da546Spatrick       nullptr,
103*f6aab3d8Srobert   };
104061da546Spatrick   d_register_infos.push_back(orig_ax);
105061da546Spatrick }
106061da546Spatrick 
GetGPRSizeStatic()107*f6aab3d8Srobert size_t RegisterContextLinux_i386::GetGPRSizeStatic() { return sizeof(GPR); }
108061da546Spatrick 
GetRegisterInfo() const109061da546Spatrick const RegisterInfo *RegisterContextLinux_i386::GetRegisterInfo() const {
110*f6aab3d8Srobert   switch (GetTargetArchitecture().GetMachine()) {
111061da546Spatrick   case llvm::Triple::x86:
112061da546Spatrick   case llvm::Triple::x86_64:
113061da546Spatrick     return g_register_infos_i386;
114061da546Spatrick   default:
115061da546Spatrick     assert(false && "Unhandled target architecture.");
116061da546Spatrick     return nullptr;
117061da546Spatrick   }
118061da546Spatrick }
119061da546Spatrick 
GetRegisterCount() const120061da546Spatrick uint32_t RegisterContextLinux_i386::GetRegisterCount() const {
121061da546Spatrick   return static_cast<uint32_t>(sizeof(g_register_infos_i386) /
122061da546Spatrick                                sizeof(g_register_infos_i386[0]));
123061da546Spatrick }
124061da546Spatrick 
GetUserRegisterCount() const125061da546Spatrick uint32_t RegisterContextLinux_i386::GetUserRegisterCount() const {
126061da546Spatrick   return static_cast<uint32_t>(k_num_user_registers_i386);
127061da546Spatrick }
128061da546Spatrick 
129061da546Spatrick const std::vector<lldb_private::RegisterInfo> *
GetDynamicRegisterInfoP() const130061da546Spatrick RegisterContextLinux_i386::GetDynamicRegisterInfoP() const {
131061da546Spatrick   return &d_register_infos;
132061da546Spatrick }
133