guiandrade created this revision.
guiandrade added a reviewer: labath.
guiandrade added a project: LLDB.
Herald added subscribers: lldb-commits, JDevlieghere.

This change increases the offset of MPX registers (by 128) so they
do not overlap with the offset associated with AVX registers. That was
causing MPX data in GDBRemoteRegisterContext::m_reg_data to get overwritten.


Repository:
  rLLDB LLDB

https://reviews.llvm.org/D68874

Files:
  
lldb/packages/Python/lldbsuite/test/commands/register/register/intel_xtended_registers/mpx_offset_intersection/Makefile
  
lldb/packages/Python/lldbsuite/test/commands/register/register/intel_xtended_registers/mpx_offset_intersection/TestMPXOffsetIntersection.py
  
lldb/packages/Python/lldbsuite/test/commands/register/register/intel_xtended_registers/mpx_offset_intersection/main.cpp
  lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
  lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
  lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
  lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
  lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h

Index: lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
===================================================================
--- lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
+++ lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
@@ -25,15 +25,18 @@
    LLVM_EXTENSION offsetof(FPR, xsave) +                                       \
    LLVM_EXTENSION offsetof(XSAVE, ymmh[0]) + (32 * reg_index))
 
+// Guarantees BNDR/BNDC offsets do not overlap with YMM offsets.
+#define GDB_REMOTE_OFFSET 128
+
 #define BNDR_OFFSET(reg_index)                                                 \
   (LLVM_EXTENSION offsetof(UserArea, fpr) +                                    \
    LLVM_EXTENSION offsetof(FPR, xsave) +                                       \
-   LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index]))
+   LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index]) + GDB_REMOTE_OFFSET)
 
 #define BNDC_OFFSET(reg_index)                                                 \
   (LLVM_EXTENSION offsetof(UserArea, fpr) +                                    \
    LLVM_EXTENSION offsetof(FPR, xsave) +                                       \
-   LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index]))
+   LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index]) + GDB_REMOTE_OFFSET)
 
 #ifdef DECLARE_REGISTER_INFOS_X86_64_STRUCT
 
Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
+++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
@@ -75,6 +75,8 @@
 
   Status WriteFPR() override;
 
+  uint32_t GetPtraceOffset(uint32_t reg_index) override;
+
 private:
   // Private member types.
   enum class XStateType { Invalid, FXSAVE, XSAVE };
Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
+++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
@@ -1213,4 +1213,11 @@
   return 4;
 }
 
+uint32_t
+NativeRegisterContextLinux_x86_64::GetPtraceOffset(uint32_t reg_index) {
+  // If register is MPX, remove extra factor from gdb offset
+  return GetRegisterInfoAtIndex(reg_index)->byte_offset -
+         (IsMPX(reg_index) ? 128 : 0);
+}
+
 #endif // defined(__i386__) || defined(__x86_64__)
Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
+++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
@@ -60,6 +60,10 @@
 
   virtual size_t GetFPRSize() = 0;
 
+  virtual uint32_t GetPtraceOffset(uint32_t reg_index) {
+    return GetRegisterInfoAtIndex(reg_index)->byte_offset;
+  }
+
   // The Do*** functions are executed on the privileged thread and can perform
   // ptrace
   // operations directly.
Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
+++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
@@ -34,7 +34,7 @@
   if (!reg_info)
     return Status("register %" PRIu32 " not found", reg_index);
 
-  return DoReadRegisterValue(reg_info->byte_offset, reg_info->name,
+  return DoReadRegisterValue(GetPtraceOffset(reg_index), reg_info->name,
                              reg_info->byte_size, reg_value);
 }
 
@@ -91,7 +91,8 @@
                   "for write register index %" PRIu32,
                   __FUNCTION__, reg_to_write);
 
-  return DoWriteRegisterValue(reg_info->byte_offset, reg_info->name, reg_value);
+  return DoWriteRegisterValue(GetPtraceOffset(reg_index), reg_info->name,
+                              reg_value);
 }
 
 Status NativeRegisterContextLinux::ReadGPR() {
Index: lldb/packages/Python/lldbsuite/test/commands/register/register/intel_xtended_registers/mpx_offset_intersection/main.cpp
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/commands/register/register/intel_xtended_registers/mpx_offset_intersection/main.cpp
@@ -0,0 +1,6 @@
+#include <cstdint>
+
+int main() {
+  asm volatile("int3");
+  return 0;
+}
Index: lldb/packages/Python/lldbsuite/test/commands/register/register/intel_xtended_registers/mpx_offset_intersection/TestMPXOffsetIntersection.py
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/commands/register/register/intel_xtended_registers/mpx_offset_intersection/TestMPXOffsetIntersection.py
@@ -0,0 +1,73 @@
+"""
+Test Intel(R) MPX registers do not get overwritten by AVX data.
+"""
+
+from __future__ import print_function
+
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class MPXOffsetIntersectionTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    AVX_REGS = ('ymm' + str(i) for i in range(16))
+    YMM_VALUE = '{' + ' '.join(('0x00' for _ in range(32))) + '}'
+
+    MPX_REGULAR_REGS = ('bnd0', 'bnd1', 'bnd2', 'bnd3')
+    MPX_CONFIG_REGS = ('bndcfgu', 'bndstatus')
+    BND_VALUE = '{' + ' '.join(('0xff' for _ in range(16))) + '}'
+
+    def setUp(self):
+        TestBase.setUp(self)
+
+    @skipIf(oslist=no_match(['linux']))
+    @skipIf(archs=no_match(['x86_64']))
+    def test_mpx_registers_offset_intersection(self):
+        """Test if AVX data does not overwrite MPX values."""
+        self.build()
+        self.mpx_registers_offset_intersection()
+
+    def mpx_registers_offset_intersection(self):
+        exe = self.getBuildArtifact('a.out')
+        self.runCmd('file ' + exe, CURRENT_EXECUTABLE_SET)
+        self.runCmd('run', RUN_SUCCEEDED)
+        target = self.dbg.GetSelectedTarget()
+        process = target.GetProcess()
+        thread = process.GetThreadAtIndex(0)
+        currentFrame = thread.GetFrameAtIndex(0)
+
+        has_avx = False
+        has_mpx = False
+        for registerSet in currentFrame.GetRegisters():
+            if 'advanced vector extensions' in registerSet.GetName().lower():
+                has_avx = True
+            if 'memory protection extension' in registerSet.GetName().lower():
+                has_mpx = True
+        if not (has_avx and has_mpx):
+            self.skipTest('Both AVX and MPX registers must be supported.')
+
+        for reg in self.AVX_REGS:
+            self.runCmd('register write ' + reg + " '" + self.YMM_VALUE + " '")
+        for reg in self.MPX_REGULAR_REGS + self.MPX_CONFIG_REGS:
+            self.runCmd('register write ' + reg + " '" + self.BND_VALUE + " '")
+
+        self.verify_mpx()
+        self.verify_avx()
+        self.verify_mpx()
+
+    def verify_mpx(self):
+        for reg in self.MPX_REGULAR_REGS:
+            self.expect('register read ' + reg,
+                        substrs = [reg + ' = {0xffffffffffffffff 0xffffffffffffffff}'])
+        for reg in self.MPX_CONFIG_REGS:
+            self.expect('register read ' + reg,
+                        substrs = [reg + ' = {0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff}'])
+
+    def verify_avx(self):
+        for reg in self.AVX_REGS:
+            self.expect('register read ' + reg, substrs = [reg + ' = ' + self.YMM_VALUE])
Index: lldb/packages/Python/lldbsuite/test/commands/register/register/intel_xtended_registers/mpx_offset_intersection/Makefile
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/commands/register/register/intel_xtended_registers/mpx_offset_intersection/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
  • [Lldb-commits] [PATCH] ... Guilherme Andrade via Phabricator via lldb-commits

Reply via email to