summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp44
-rw-r--r--lldb/test/functionalities/register/TestRegisters.py56
2 files changed, 95 insertions, 5 deletions
diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp b/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp
index 36a4a9e6e91..7fc6426d3e8 100644
--- a/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp
+++ b/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp
@@ -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
diff --git a/lldb/test/functionalities/register/TestRegisters.py b/lldb/test/functionalities/register/TestRegisters.py
index 6a4e6957f65..c34f6722439 100644
--- a/lldb/test/functionalities/register/TestRegisters.py
+++ b/lldb/test/functionalities/register/TestRegisters.py
@@ -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")
OpenPOWER on IntegriCloud