[Lldb-commits] [lldb] r180111 - Added 64-bit POSIX support to write general-purpose floating-point registers.
Ashok Thirumurthi
ashok.thirumurthi at intel.com
Tue Apr 23 07:59:02 PDT 2013
Author: athirumu
Date: Tue Apr 23 09:59:02 2013
New Revision: 180111
URL: http://llvm.org/viewvc/llvm-project?rev=180111&view=rev
Log:
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
Modified:
lldb/trunk/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp
lldb/trunk/test/functionalities/register/TestRegisters.py
Modified: lldb/trunk/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp?rev=180111&r1=180110&r2=180111&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp Tue Apr 23 09:59:02 2013
@@ -688,11 +688,47 @@ RegisterContext_x86_64::WriteRegister(co
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
Modified: lldb/trunk/test/functionalities/register/TestRegisters.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/register/TestRegisters.py?rev=180111&r1=180110&r2=180111&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/register/TestRegisters.py (original)
+++ lldb/trunk/test/functionalities/register/TestRegisters.py Tue Apr 23 09:59:02 2013
@@ -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")
More information about the lldb-commits
mailing list