180814287SRaphael Isemann //===-- RegisterContextLinux_i386.cpp -------------------------------------===//
23e699d41SVirgile Bello //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63e699d41SVirgile Bello //
73e699d41SVirgile Bello //===---------------------------------------------------------------------===//
83e699d41SVirgile Bello 
93e699d41SVirgile Bello #include "RegisterContextLinux_i386.h"
10b9c1b51eSKate Stone #include "RegisterContextPOSIX_x86.h"
113e699d41SVirgile Bello 
123e699d41SVirgile Bello using namespace lldb_private;
133e699d41SVirgile Bello using namespace lldb;
143e699d41SVirgile Bello 
15b9c1b51eSKate Stone struct GPR {
163e699d41SVirgile Bello   uint32_t ebx;
173e699d41SVirgile Bello   uint32_t ecx;
183e699d41SVirgile Bello   uint32_t edx;
193e699d41SVirgile Bello   uint32_t esi;
203e699d41SVirgile Bello   uint32_t edi;
213e699d41SVirgile Bello   uint32_t ebp;
223e699d41SVirgile Bello   uint32_t eax;
233e699d41SVirgile Bello   uint32_t ds;
243e699d41SVirgile Bello   uint32_t es;
253e699d41SVirgile Bello   uint32_t fs;
263e699d41SVirgile Bello   uint32_t gs;
274778e410SRavitheja Addepally   uint32_t orig_eax;
283e699d41SVirgile Bello   uint32_t eip;
293e699d41SVirgile Bello   uint32_t cs;
303e699d41SVirgile Bello   uint32_t eflags;
313e699d41SVirgile Bello   uint32_t esp;
323e699d41SVirgile Bello   uint32_t ss;
333e699d41SVirgile Bello };
343e699d41SVirgile Bello 
35b9c1b51eSKate Stone struct FPR_i386 {
363e699d41SVirgile Bello   uint16_t fctrl;     // FPU Control Word (fcw)
373e699d41SVirgile Bello   uint16_t fstat;     // FPU Status Word (fsw)
38bf2a8a28SSaleem Abdulrasool   uint16_t ftag;      // FPU Tag Word (ftw)
393e699d41SVirgile Bello   uint16_t fop;       // Last Instruction Opcode (fop)
40b9c1b51eSKate Stone   union {
41b9c1b51eSKate Stone     struct {
423e699d41SVirgile Bello       uint64_t fip; // Instruction Pointer
433e699d41SVirgile Bello       uint64_t fdp; // Data Pointer
443e699d41SVirgile Bello     } x86_64;
45b9c1b51eSKate Stone     struct {
463e699d41SVirgile Bello       uint32_t fioff; // FPU IP Offset (fip)
473e699d41SVirgile Bello       uint32_t fiseg; // FPU IP Selector (fcs)
483e699d41SVirgile Bello       uint32_t fooff; // FPU Operand Pointer Offset (foo)
493e699d41SVirgile Bello       uint32_t foseg; // FPU Operand Pointer Selector (fos)
50b9c1b51eSKate Stone     } i386_; // Added _ in the end to avoid error with gcc defining i386 in some
51b9c1b51eSKate Stone              // cases
523e699d41SVirgile Bello   } ptr;
533e699d41SVirgile Bello   uint32_t mxcsr;     // MXCSR Register State
543e699d41SVirgile Bello   uint32_t mxcsrmask; // MXCSR Mask
553e699d41SVirgile Bello   MMSReg stmm[8];     // 8*16 bytes for each FP-reg = 128 bytes
563e699d41SVirgile Bello   XMMReg xmm[8];      // 8*16 bytes for each XMM-reg = 128 bytes
573e699d41SVirgile Bello   uint32_t padding[56];
583e699d41SVirgile Bello };
593e699d41SVirgile Bello 
60b9c1b51eSKate Stone struct UserArea {
613e699d41SVirgile Bello   GPR regs;               // General purpose registers.
623e699d41SVirgile Bello   int32_t fpvalid;        // True if FPU is being used.
633e699d41SVirgile Bello   FPR_i386 i387;          // FPU registers.
643e699d41SVirgile Bello   uint32_t tsize;         // Text segment size.
653e699d41SVirgile Bello   uint32_t dsize;         // Data segment size.
663e699d41SVirgile Bello   uint32_t ssize;         // Stack segment size.
673e699d41SVirgile Bello   uint32_t start_code;    // VM address of text.
683e699d41SVirgile Bello   uint32_t start_stack;   // VM address of stack bottom (top in rsp).
693e699d41SVirgile Bello   int32_t signal;         // Signal causing core dump.
703e699d41SVirgile Bello   int32_t reserved;       // Unused.
713e699d41SVirgile Bello   uint32_t ar0;           // Location of GPR's.
723e699d41SVirgile Bello   uint32_t fpstate;       // Location of FPR's. Should be a FXSTATE *, but this
733e699d41SVirgile Bello                           //  has to be 32-bits even on 64-bit systems.
743e699d41SVirgile Bello   uint32_t magic;         // Identifier for core dumps.
753e699d41SVirgile Bello   char u_comm[32];        // Command causing core dump.
763e699d41SVirgile Bello   uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7).
773e699d41SVirgile Bello };
783e699d41SVirgile Bello 
793e699d41SVirgile Bello #define DR_SIZE sizeof(((UserArea *)NULL)->u_debugreg[0])
803e699d41SVirgile Bello #define DR_0_OFFSET 0xFC
81b9c1b51eSKate Stone #define DR_OFFSET(reg_index) (DR_0_OFFSET + (reg_index * 4))
823e699d41SVirgile Bello #define FPR_SIZE(reg) sizeof(((FPR_i386 *)NULL)->reg)
833e699d41SVirgile Bello 
843e699d41SVirgile Bello // Include RegisterInfos_i386 to declare our g_register_infos_i386 structure.
853e699d41SVirgile Bello #define DECLARE_REGISTER_INFOS_I386_STRUCT
863e699d41SVirgile Bello #include "RegisterInfos_i386.h"
873e699d41SVirgile Bello #undef DECLARE_REGISTER_INFOS_I386_STRUCT
883e699d41SVirgile Bello 
RegisterContextLinux_i386(const ArchSpec & target_arch)89b9c1b51eSKate Stone RegisterContextLinux_i386::RegisterContextLinux_i386(
90b9c1b51eSKate Stone     const ArchSpec &target_arch)
91b9c1b51eSKate Stone     : RegisterInfoInterface(target_arch) {
92*202af507SPavel Labath   RegisterInfo orig_ax = {
93*202af507SPavel Labath       "orig_eax",
94248a1305SKonrad Kleine       nullptr,
95248a1305SKonrad Kleine       sizeof(((GPR *)nullptr)->orig_eax),
96b9c1b51eSKate Stone       (LLVM_EXTENSION offsetof(GPR, orig_eax)),
97b9c1b51eSKate Stone       eEncodingUint,
98b9c1b51eSKate Stone       eFormatHex,
99*202af507SPavel Labath       {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
100*202af507SPavel Labath        LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
101b9c1b51eSKate Stone       nullptr,
102b9c1b51eSKate Stone       nullptr,
103*202af507SPavel Labath   };
1044778e410SRavitheja Addepally   d_register_infos.push_back(orig_ax);
1053e699d41SVirgile Bello }
1063e699d41SVirgile Bello 
GetGPRSize() const107b9c1b51eSKate Stone size_t RegisterContextLinux_i386::GetGPRSize() const { return sizeof(GPR); }
1083e699d41SVirgile Bello 
GetRegisterInfo() const109b9c1b51eSKate Stone const RegisterInfo *RegisterContextLinux_i386::GetRegisterInfo() const {
110b9c1b51eSKate Stone   switch (m_target_arch.GetMachine()) {
111906e9acfSGreg Clayton   case llvm::Triple::x86:
11203d30fc7SChaoren Lin   case llvm::Triple::x86_64:
1133e699d41SVirgile Bello     return g_register_infos_i386;
1143e699d41SVirgile Bello   default:
1153e699d41SVirgile Bello     assert(false && "Unhandled target architecture.");
116248a1305SKonrad Kleine     return nullptr;
1173e699d41SVirgile Bello   }
1183e699d41SVirgile Bello }
119af245d11STodd Fiala 
GetRegisterCount() const120b9c1b51eSKate Stone uint32_t RegisterContextLinux_i386::GetRegisterCount() const {
121b9c1b51eSKate Stone   return static_cast<uint32_t>(sizeof(g_register_infos_i386) /
122b9c1b51eSKate Stone                                sizeof(g_register_infos_i386[0]));
123af245d11STodd Fiala }
124af245d11STodd Fiala 
GetUserRegisterCount() const125b9c1b51eSKate Stone uint32_t RegisterContextLinux_i386::GetUserRegisterCount() const {
126d40ef999SVince Harron   return static_cast<uint32_t>(k_num_user_registers_i386);
127d40ef999SVince Harron }
1284778e410SRavitheja Addepally 
1294778e410SRavitheja Addepally const std::vector<lldb_private::RegisterInfo> *
GetDynamicRegisterInfoP() const130b9c1b51eSKate Stone RegisterContextLinux_i386::GetDynamicRegisterInfoP() const {
1314778e410SRavitheja Addepally   return &d_register_infos;
1324778e410SRavitheja Addepally }
133