126 lines · cpp
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-exception6//7//===---------------------------------------------------------------------===//8 9#include "RegisterContextLinux_i386.h"10#include "RegisterContextPOSIX_x86.h"11 12using namespace lldb_private;13using namespace lldb;14 15struct 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 35struct 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 Pointer43 uint64_t fdp; // Data Pointer44 } 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 some51 // cases52 } ptr;53 uint32_t mxcsr; // MXCSR Register State54 uint32_t mxcsrmask; // MXCSR Mask55 MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes56 XMMReg xmm[8]; // 8*16 bytes for each XMM-reg = 128 bytes57 uint32_t padding[56];58};59 60struct 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 this73 // 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 0xFC81#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_STRUCT86#include "RegisterInfos_i386.h"87#undef DECLARE_REGISTER_INFOS_I386_STRUCT88 89RegisterContextLinux_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 105size_t RegisterContextLinux_i386::GetGPRSizeStatic() { return sizeof(GPR); }106 107const 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 118uint32_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 123uint32_t RegisterContextLinux_i386::GetUserRegisterCount() const {124 return static_cast<uint32_t>(k_num_user_registers_i386);125}126