mirror of
https://github.com/intel/llvm.git
synced 2026-01-24 17:01:00 +08:00
Bug 25050: X87 FPU Special Purpose Registers
Summary:
- For x86_64-FreeBSD Platform:
-- LLDB now provides correct values of X87 FPU
Special Purpose Registers like fstat, ftag, fctrl etc..
Signed-off-by: Abhishek Aggarwal <abhishek.a.aggarwal@intel.com>
Reviewers: emaste, mikesart, clayborg
Subscribers: emaste
Differential Revision: http://reviews.llvm.org/D13434
llvm-svn: 249379
This commit is contained in:
@@ -58,6 +58,9 @@ RegisterContextPOSIXProcessMonitor_x86_64::RegisterContextPOSIXProcessMonitor_x8
|
||||
lldb_private::RegisterInfoInterface *register_info)
|
||||
: RegisterContextPOSIX_x86(thread, concrete_frame_idx, register_info)
|
||||
{
|
||||
// Store byte offset of fctrl (i.e. first register of FPR) wrt 'UserArea'
|
||||
const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
|
||||
m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset;
|
||||
}
|
||||
|
||||
ProcessMonitor &
|
||||
@@ -254,8 +257,15 @@ RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(const RegisterInfo *reg_
|
||||
}
|
||||
|
||||
// Get pointer to m_fpr.xstate.fxsave variable and set the data from it.
|
||||
assert (reg_info->byte_offset < sizeof(m_fpr));
|
||||
uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset;
|
||||
// Byte offsets of all registers are calculated wrt 'UserArea' structure.
|
||||
// However, ReadFPR() reads fpu registers {using ptrace(PT_GETFPREGS,..)}
|
||||
// and stores them in 'm_fpr' (of type FPR structure). To extract values of fpu
|
||||
// registers, m_fpr should be read at byte offsets calculated wrt to FPR structure.
|
||||
|
||||
// Since, FPR structure is also one of the member of UserArea structure.
|
||||
// byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) - byte_offset(fctrl wrt UserArea)
|
||||
assert ( (reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(m_fpr));
|
||||
uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea;
|
||||
switch (reg_info->byte_size)
|
||||
{
|
||||
case 2:
|
||||
@@ -308,8 +318,15 @@ RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(const RegisterInfo *reg
|
||||
else
|
||||
{
|
||||
// Get pointer to m_fpr.xstate.fxsave variable and set the data to it.
|
||||
assert (reg_info->byte_offset < sizeof(m_fpr));
|
||||
uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset;
|
||||
// Byte offsets of all registers are calculated wrt 'UserArea' structure.
|
||||
// However, WriteFPR() takes m_fpr (of type FPR structure) and writes only fpu
|
||||
// registers using ptrace(PT_SETFPREGS,..) API. Hence fpu registers should
|
||||
// be written in m_fpr at byte offsets calculated wrt FPR structure.
|
||||
|
||||
// Since, FPR structure is also one of the member of UserArea structure.
|
||||
// byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) - byte_offset(fctrl wrt UserArea)
|
||||
assert ( (reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(m_fpr));
|
||||
uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea;
|
||||
switch (reg_info->byte_size)
|
||||
{
|
||||
case 2:
|
||||
|
||||
@@ -91,6 +91,7 @@ protected:
|
||||
private:
|
||||
ProcessMonitor &
|
||||
GetMonitor();
|
||||
uint32_t m_fctrl_offset_in_userarea; // Offset of 'fctrl' in 'UserArea' Structure
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user