[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