forked from OSchip/llvm-project
Added 64-bit POSIX support to write general-purpose floating-point registers.
- Includes tests that write, verify and restore floating-point register content using SBFrame. Reviewed by: Daniel Malea llvm-svn: 180111
This commit is contained in:
parent
d408de6a2e
commit
c140c631cb
|
@ -688,11 +688,47 @@ RegisterContext_x86_64::WriteRegister(const lldb_private::RegisterInfo *reg_info
|
|||
const lldb_private::RegisterValue &value)
|
||||
{
|
||||
const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
|
||||
if (IsAVX(reg))
|
||||
return false;
|
||||
if (IsGPR(reg)) {
|
||||
ProcessMonitor &monitor = GetMonitor();
|
||||
return monitor.WriteRegisterValue(m_thread.GetID(), GetRegOffset(reg), value);
|
||||
}
|
||||
|
||||
ProcessMonitor &monitor = GetMonitor();
|
||||
return monitor.WriteRegisterValue(m_thread.GetID(), GetRegOffset(reg), value);
|
||||
if (IsFPR(reg)) {
|
||||
// Note that lldb uses slightly different naming conventions from sys/user.h
|
||||
switch (reg)
|
||||
{
|
||||
default:
|
||||
return false;
|
||||
case fpu_dp:
|
||||
user.i387.dp = value.GetAsUInt64();
|
||||
break;
|
||||
case fpu_fcw:
|
||||
user.i387.fcw = value.GetAsUInt16();
|
||||
break;
|
||||
case fpu_fsw:
|
||||
user.i387.fsw = value.GetAsUInt16();
|
||||
break;
|
||||
case fpu_ip:
|
||||
user.i387.ip = value.GetAsUInt64();
|
||||
break;
|
||||
case fpu_fop:
|
||||
user.i387.fop = value.GetAsUInt16();
|
||||
break;
|
||||
case fpu_ftw:
|
||||
user.i387.ftw = value.GetAsUInt16();
|
||||
break;
|
||||
case fpu_mxcsr:
|
||||
user.i387.mxcsr = value.GetAsUInt32();
|
||||
break;
|
||||
case fpu_mxcsrmask:
|
||||
user.i387.mxcsrmask = value.GetAsUInt32();
|
||||
break;
|
||||
}
|
||||
if (WriteFPR()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -20,6 +20,13 @@ class RegisterCommandsTestCase(TestBase):
|
|||
self.buildDefault()
|
||||
self.register_commands()
|
||||
|
||||
def test_fp_register_write(self):
|
||||
"""Test commands that write to registers, in particular floating-point registers."""
|
||||
if not self.getArchitecture() in ['i386', 'x86_64']:
|
||||
self.skipTest("This test requires i386 or x86_64 as the architecture for the inferior")
|
||||
self.buildDefault()
|
||||
self.fp_register_write()
|
||||
|
||||
def test_register_expressions(self):
|
||||
"""Test expression evaluation with commands related to registers."""
|
||||
if not self.getArchitecture() in ['i386', 'x86_64']:
|
||||
|
@ -68,6 +75,52 @@ class RegisterCommandsTestCase(TestBase):
|
|||
self.expect("register read -s 3",
|
||||
substrs = ['invalid register set index: 3'], error = True)
|
||||
|
||||
def write_and_restore(self, frame, register):
|
||||
value = frame.FindValue(register, lldb.eValueTypeRegister)
|
||||
self.assertTrue(value.IsValid(), "finding a value for register " + register)
|
||||
|
||||
error = lldb.SBError()
|
||||
register_value = value.GetValueAsUnsigned(error, 0)
|
||||
self.assertTrue(error.Success(), "reading a value for " + register)
|
||||
|
||||
self.runCmd("register write " + register + " 0xff0e")
|
||||
self.expect("register read " + register,
|
||||
substrs = [register + ' = 0x', 'ff0e'])
|
||||
|
||||
self.runCmd("register write " + register + " " + str(register_value))
|
||||
self.expect("register read " + register,
|
||||
substrs = [register + ' = 0x'])
|
||||
|
||||
def fp_register_write(self):
|
||||
exe = os.path.join(os.getcwd(), "a.out")
|
||||
|
||||
# Create a target by the debugger.
|
||||
target = self.dbg.CreateTarget(exe)
|
||||
self.assertTrue(target, VALID_TARGET)
|
||||
|
||||
lldbutil.run_break_set_by_symbol (self, "main", num_expected_locations=-1)
|
||||
|
||||
# Launch the process, and do not stop at the entry point.
|
||||
process = target.LaunchSimple(None, None, os.getcwd())
|
||||
|
||||
process = target.GetProcess()
|
||||
self.assertTrue(process.GetState() == lldb.eStateStopped,
|
||||
PROCESS_STOPPED)
|
||||
|
||||
thread = process.GetThreadAtIndex(0)
|
||||
self.assertTrue(thread.IsValid(), "current thread is valid")
|
||||
|
||||
currentFrame = thread.GetFrameAtIndex(0)
|
||||
self.assertTrue(currentFrame.IsValid(), "current frame is valid")
|
||||
|
||||
self.write_and_restore(currentFrame, "fcw")
|
||||
self.write_and_restore(currentFrame, "fsw")
|
||||
self.write_and_restore(currentFrame, "ftw")
|
||||
self.write_and_restore(currentFrame, "ip")
|
||||
self.write_and_restore(currentFrame, "dp")
|
||||
self.write_and_restore(currentFrame, "mxcsr")
|
||||
self.write_and_restore(currentFrame, "mxcsrmask")
|
||||
|
||||
@expectedFailureLinux # bugzilla 14661 - Expressions involving XMM registers fail on Linux
|
||||
def register_expressions(self):
|
||||
"""Test expression evaluation with commands related to registers."""
|
||||
|
@ -93,7 +146,8 @@ class RegisterCommandsTestCase(TestBase):
|
|||
substrs = ['eax'])
|
||||
|
||||
# Test reading of rax and eax.
|
||||
self.runCmd("register read rax eax")
|
||||
self.expect("register read rax eax",
|
||||
substrs = ['rax = 0x', 'eax = 0x'])
|
||||
|
||||
# Now write rax with a unique bit pattern and test that eax indeed represents the lower half of rax.
|
||||
self.runCmd("register write rax 0x1234567887654321")
|
||||
|
|
Loading…
Reference in New Issue