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:
Ashok Thirumurthi 2013-04-23 14:59:02 +00:00
parent d408de6a2e
commit c140c631cb
2 changed files with 95 additions and 5 deletions

View File

@ -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

View File

@ -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")