10b57cec5SDimitry Andric //===-- RegisterContextDarwin_i386.h ----------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 95ffd83dbSDimitry Andric #ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_I386_H 105ffd83dbSDimitry Andric #define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_I386_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "lldb/Target/RegisterContext.h" 130b57cec5SDimitry Andric #include "lldb/lldb-private.h" 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric class RegisterContextDarwin_i386 : public lldb_private::RegisterContext { 160b57cec5SDimitry Andric public: 170b57cec5SDimitry Andric RegisterContextDarwin_i386(lldb_private::Thread &thread, 180b57cec5SDimitry Andric uint32_t concrete_frame_idx); 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric ~RegisterContextDarwin_i386() override; 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric void InvalidateAllRegisters() override; 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric size_t GetRegisterCount() override; 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric size_t GetRegisterSetCount() override; 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric bool ReadRegister(const lldb_private::RegisterInfo *reg_info, 330b57cec5SDimitry Andric lldb_private::RegisterValue &value) override; 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric bool WriteRegister(const lldb_private::RegisterInfo *reg_info, 360b57cec5SDimitry Andric const lldb_private::RegisterValue &value) override; 370b57cec5SDimitry Andric 3881ad6265SDimitry Andric bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, 430b57cec5SDimitry Andric uint32_t num) override; 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric bool HardwareSingleStep(bool enable) override; 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric struct GPR { 480b57cec5SDimitry Andric uint32_t eax; 490b57cec5SDimitry Andric uint32_t ebx; 500b57cec5SDimitry Andric uint32_t ecx; 510b57cec5SDimitry Andric uint32_t edx; 520b57cec5SDimitry Andric uint32_t edi; 530b57cec5SDimitry Andric uint32_t esi; 540b57cec5SDimitry Andric uint32_t ebp; 550b57cec5SDimitry Andric uint32_t esp; 560b57cec5SDimitry Andric uint32_t ss; 570b57cec5SDimitry Andric uint32_t eflags; 580b57cec5SDimitry Andric uint32_t eip; 590b57cec5SDimitry Andric uint32_t cs; 600b57cec5SDimitry Andric uint32_t ds; 610b57cec5SDimitry Andric uint32_t es; 620b57cec5SDimitry Andric uint32_t fs; 630b57cec5SDimitry Andric uint32_t gs; 640b57cec5SDimitry Andric }; 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric struct MMSReg { 670b57cec5SDimitry Andric uint8_t bytes[10]; 680b57cec5SDimitry Andric uint8_t pad[6]; 690b57cec5SDimitry Andric }; 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric struct XMMReg { 720b57cec5SDimitry Andric uint8_t bytes[16]; 730b57cec5SDimitry Andric }; 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric struct FPU { 760b57cec5SDimitry Andric uint32_t pad[2]; 770b57cec5SDimitry Andric uint16_t fcw; 780b57cec5SDimitry Andric uint16_t fsw; 790b57cec5SDimitry Andric uint8_t ftw; 800b57cec5SDimitry Andric uint8_t pad1; 810b57cec5SDimitry Andric uint16_t fop; 820b57cec5SDimitry Andric uint32_t ip; 830b57cec5SDimitry Andric uint16_t cs; 840b57cec5SDimitry Andric uint16_t pad2; 850b57cec5SDimitry Andric uint32_t dp; 860b57cec5SDimitry Andric uint16_t ds; 870b57cec5SDimitry Andric uint16_t pad3; 880b57cec5SDimitry Andric uint32_t mxcsr; 890b57cec5SDimitry Andric uint32_t mxcsrmask; 900b57cec5SDimitry Andric MMSReg stmm[8]; 910b57cec5SDimitry Andric XMMReg xmm[8]; 920b57cec5SDimitry Andric uint8_t pad4[14 * 16]; 930b57cec5SDimitry Andric int pad5; 940b57cec5SDimitry Andric }; 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric struct EXC { 970b57cec5SDimitry Andric uint32_t trapno; 980b57cec5SDimitry Andric uint32_t err; 990b57cec5SDimitry Andric uint32_t faultvaddr; 1000b57cec5SDimitry Andric }; 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric protected: 1030b57cec5SDimitry Andric enum { GPRRegSet = 1, FPURegSet = 2, EXCRegSet = 3 }; 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric enum { 1060b57cec5SDimitry Andric GPRWordCount = sizeof(GPR) / sizeof(uint32_t), 1070b57cec5SDimitry Andric FPUWordCount = sizeof(FPU) / sizeof(uint32_t), 1080b57cec5SDimitry Andric EXCWordCount = sizeof(EXC) / sizeof(uint32_t) 1090b57cec5SDimitry Andric }; 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric enum { Read = 0, Write = 1, kNumErrors = 2 }; 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric GPR gpr; 1140b57cec5SDimitry Andric FPU fpu; 1150b57cec5SDimitry Andric EXC exc; 1160b57cec5SDimitry Andric int gpr_errs[2]; // Read/Write errors 1170b57cec5SDimitry Andric int fpu_errs[2]; // Read/Write errors 1180b57cec5SDimitry Andric int exc_errs[2]; // Read/Write errors 1190b57cec5SDimitry Andric InvalidateAllRegisterStates()1200b57cec5SDimitry Andric void InvalidateAllRegisterStates() { 1210b57cec5SDimitry Andric SetError(GPRRegSet, Read, -1); 1220b57cec5SDimitry Andric SetError(FPURegSet, Read, -1); 1230b57cec5SDimitry Andric SetError(EXCRegSet, Read, -1); 1240b57cec5SDimitry Andric } 1250b57cec5SDimitry Andric GetError(int flavor,uint32_t err_idx)1260b57cec5SDimitry Andric int GetError(int flavor, uint32_t err_idx) const { 1270b57cec5SDimitry Andric if (err_idx < kNumErrors) { 1280b57cec5SDimitry Andric switch (flavor) { 1290b57cec5SDimitry Andric // When getting all errors, just OR all values together to see if 1300b57cec5SDimitry Andric // we got any kind of error. 1310b57cec5SDimitry Andric case GPRRegSet: 1320b57cec5SDimitry Andric return gpr_errs[err_idx]; 1330b57cec5SDimitry Andric case FPURegSet: 1340b57cec5SDimitry Andric return fpu_errs[err_idx]; 1350b57cec5SDimitry Andric case EXCRegSet: 1360b57cec5SDimitry Andric return exc_errs[err_idx]; 1370b57cec5SDimitry Andric default: 1380b57cec5SDimitry Andric break; 1390b57cec5SDimitry Andric } 1400b57cec5SDimitry Andric } 1410b57cec5SDimitry Andric return -1; 1420b57cec5SDimitry Andric } 1430b57cec5SDimitry Andric SetError(int flavor,uint32_t err_idx,int err)1440b57cec5SDimitry Andric bool SetError(int flavor, uint32_t err_idx, int err) { 1450b57cec5SDimitry Andric if (err_idx < kNumErrors) { 1460b57cec5SDimitry Andric switch (flavor) { 1470b57cec5SDimitry Andric case GPRRegSet: 1480b57cec5SDimitry Andric gpr_errs[err_idx] = err; 1490b57cec5SDimitry Andric return true; 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric case FPURegSet: 1520b57cec5SDimitry Andric fpu_errs[err_idx] = err; 1530b57cec5SDimitry Andric return true; 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric case EXCRegSet: 1560b57cec5SDimitry Andric exc_errs[err_idx] = err; 1570b57cec5SDimitry Andric return true; 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andric default: 1600b57cec5SDimitry Andric break; 1610b57cec5SDimitry Andric } 1620b57cec5SDimitry Andric } 1630b57cec5SDimitry Andric return false; 1640b57cec5SDimitry Andric } 1650b57cec5SDimitry Andric RegisterSetIsCached(int set)1660b57cec5SDimitry Andric bool RegisterSetIsCached(int set) const { return GetError(set, Read) == 0; } 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric void LogGPR(lldb_private::Log *log, const char *title); 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric int ReadGPR(bool force); 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric int ReadFPU(bool force); 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric int ReadEXC(bool force); 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric int WriteGPR(); 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric int WriteFPU(); 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric int WriteEXC(); 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric // Subclasses override these to do the actual reading. 1830b57cec5SDimitry Andric virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) = 0; 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric virtual int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) = 0; 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric virtual int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) = 0; 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric virtual int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) = 0; 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric virtual int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) = 0; 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric virtual int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) = 0; 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric int ReadRegisterSet(uint32_t set, bool force); 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric int WriteRegisterSet(uint32_t set); 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andric static uint32_t GetRegisterNumber(uint32_t reg_kind, uint32_t reg_num); 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric static int GetSetForNativeRegNum(int reg_num); 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric static size_t GetRegisterInfosCount(); 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric static const lldb_private::RegisterInfo *GetRegisterInfos(); 2060b57cec5SDimitry Andric }; 2070b57cec5SDimitry Andric 2085ffd83dbSDimitry Andric #endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_I386_H 209