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