1 //===-- RegisterContextLinux_i386.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 "RegisterContextLinux_i386.h"
10 #include "RegisterContextPOSIX_x86.h"
11 
12 using namespace lldb_private;
13 using namespace lldb;
14 
15 struct GPR {
16   uint32_t ebx;
17   uint32_t ecx;
18   uint32_t edx;
19   uint32_t esi;
20   uint32_t edi;
21   uint32_t ebp;
22   uint32_t eax;
23   uint32_t ds;
24   uint32_t es;
25   uint32_t fs;
26   uint32_t gs;
27   uint32_t orig_eax;
28   uint32_t eip;
29   uint32_t cs;
30   uint32_t eflags;
31   uint32_t esp;
32   uint32_t ss;
33 };
34 
35 struct FPR_i386 {
36   uint16_t fctrl;     // FPU Control Word (fcw)
37   uint16_t fstat;     // FPU Status Word (fsw)
38   uint16_t ftag;      // FPU Tag Word (ftw)
39   uint16_t fop;       // Last Instruction Opcode (fop)
40   union {
41     struct {
42       uint64_t fip; // Instruction Pointer
43       uint64_t fdp; // Data Pointer
44     } x86_64;
45     struct {
46       uint32_t fioff; // FPU IP Offset (fip)
47       uint32_t fiseg; // FPU IP Selector (fcs)
48       uint32_t fooff; // FPU Operand Pointer Offset (foo)
49       uint32_t foseg; // FPU Operand Pointer Selector (fos)
50     } i386_; // Added _ in the end to avoid error with gcc defining i386 in some
51              // cases
52   } ptr;
53   uint32_t mxcsr;     // MXCSR Register State
54   uint32_t mxcsrmask; // MXCSR Mask
55   MMSReg stmm[8];     // 8*16 bytes for each FP-reg = 128 bytes
56   XMMReg xmm[8];      // 8*16 bytes for each XMM-reg = 128 bytes
57   uint32_t padding[56];
58 };
59 
60 struct UserArea {
61   GPR regs;               // General purpose registers.
62   int32_t fpvalid;        // True if FPU is being used.
63   FPR_i386 i387;          // FPU registers.
64   uint32_t tsize;         // Text segment size.
65   uint32_t dsize;         // Data segment size.
66   uint32_t ssize;         // Stack segment size.
67   uint32_t start_code;    // VM address of text.
68   uint32_t start_stack;   // VM address of stack bottom (top in rsp).
69   int32_t signal;         // Signal causing core dump.
70   int32_t reserved;       // Unused.
71   uint32_t ar0;           // Location of GPR's.
72   uint32_t fpstate;       // Location of FPR's. Should be a FXSTATE *, but this
73                           //  has to be 32-bits even on 64-bit systems.
74   uint32_t magic;         // Identifier for core dumps.
75   char u_comm[32];        // Command causing core dump.
76   uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7).
77 };
78 
79 #define DR_SIZE sizeof(((UserArea *)NULL)->u_debugreg[0])
80 #define DR_0_OFFSET 0xFC
81 #define DR_OFFSET(reg_index) (DR_0_OFFSET + (reg_index * 4))
82 #define FPR_SIZE(reg) sizeof(((FPR_i386 *)NULL)->reg)
83 
84 // Include RegisterInfos_i386 to declare our g_register_infos_i386 structure.
85 #define DECLARE_REGISTER_INFOS_I386_STRUCT
86 #include "RegisterInfos_i386.h"
87 #undef DECLARE_REGISTER_INFOS_I386_STRUCT
88 
RegisterContextLinux_i386(const ArchSpec & target_arch)89 RegisterContextLinux_i386::RegisterContextLinux_i386(
90     const ArchSpec &target_arch)
91     : RegisterContextLinux_x86(
92           target_arch,
93           {"orig_eax",
94            nullptr,
95            sizeof(((GPR *)nullptr)->orig_eax),
96            (LLVM_EXTENSION offsetof(GPR, orig_eax)),
97            eEncodingUint,
98            eFormatHex,
99            {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
100             LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
101            nullptr,
102            nullptr,
103            nullptr}) {}
104 
GetGPRSizeStatic()105 size_t RegisterContextLinux_i386::GetGPRSizeStatic() { return sizeof(GPR); }
106 
GetRegisterInfo() const107 const RegisterInfo *RegisterContextLinux_i386::GetRegisterInfo() const {
108   switch (GetTargetArchitecture().GetMachine()) {
109   case llvm::Triple::x86:
110   case llvm::Triple::x86_64:
111     return g_register_infos_i386;
112   default:
113     assert(false && "Unhandled target architecture.");
114     return nullptr;
115   }
116 }
117 
GetRegisterCount() const118 uint32_t RegisterContextLinux_i386::GetRegisterCount() const {
119   return static_cast<uint32_t>(sizeof(g_register_infos_i386) /
120                                sizeof(g_register_infos_i386[0]));
121 }
122 
GetUserRegisterCount() const123 uint32_t RegisterContextLinux_i386::GetUserRegisterCount() const {
124   return static_cast<uint32_t>(k_num_user_registers_i386);
125 }
126