[Lldb-commits] [lldb] e46c664 - [lldb] Fix offset intersection bug between MPX and AVX registers
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Thu Oct 31 02:57:26 PDT 2019
Author: Guilherme Andrade
Date: 2019-10-31T10:58:17+01:00
New Revision: e46c6644db8432584e82ef7ddfc9d0f36543f205
URL: https://github.com/llvm/llvm-project/commit/e46c6644db8432584e82ef7ddfc9d0f36543f205
DIFF: https://github.com/llvm/llvm-project/commit/e46c6644db8432584e82ef7ddfc9d0f36543f205.diff
LOG: [lldb] Fix offset intersection bug between MPX and AVX registers
Summary:
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.
Reviewers: labath
Reviewed By: labath
Subscribers: JDevlieghere, lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D68874
Added:
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
Modified:
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
Removed:
################################################################################
diff --git a/lldb/packages/Python/lldbsuite/test/commands/register/register/intel_xtended_registers/mpx_offset_intersection/Makefile b/lldb/packages/Python/lldbsuite/test/commands/register/register/intel_xtended_registers/mpx_offset_intersection/Makefile
new file mode 100644
index 000000000000..99998b20bcb0
--- /dev/null
+++ b/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
diff --git a/lldb/packages/Python/lldbsuite/test/commands/register/register/intel_xtended_registers/mpx_offset_intersection/TestMPXOffsetIntersection.py b/lldb/packages/Python/lldbsuite/test/commands/register/register/intel_xtended_registers/mpx_offset_intersection/TestMPXOffsetIntersection.py
new file mode 100644
index 000000000000..cca163576684
--- /dev/null
+++ b/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])
diff --git a/lldb/packages/Python/lldbsuite/test/commands/register/register/intel_xtended_registers/mpx_offset_intersection/main.cpp b/lldb/packages/Python/lldbsuite/test/commands/register/register/intel_xtended_registers/mpx_offset_intersection/main.cpp
new file mode 100644
index 000000000000..0285cfdaad0b
--- /dev/null
+++ b/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;
+}
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
index 3ae215e7573d..3186b6cf39ac 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
@@ -34,7 +34,7 @@ Status NativeRegisterContextLinux::ReadRegisterRaw(uint32_t reg_index,
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 @@ NativeRegisterContextLinux::WriteRegisterRaw(uint32_t reg_index,
"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() {
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
index 82894852c13c..3b98310c1963 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
@@ -60,6 +60,10 @@ class NativeRegisterContextLinux : public NativeRegisterContextRegisterInfo {
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.
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
index 49f1d44b39d2..0818630db625 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
@@ -1213,4 +1213,11 @@ uint32_t NativeRegisterContextLinux_x86_64::NumSupportedHardwareWatchpoints() {
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__)
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
index 6031ddb0a7a8..58b749025c56 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
@@ -75,6 +75,8 @@ class NativeRegisterContextLinux_x86_64 : public NativeRegisterContextLinux {
Status WriteFPR() override;
+ uint32_t GetPtraceOffset(uint32_t reg_index) override;
+
private:
// Private member types.
enum class XStateType { Invalid, FXSAVE, XSAVE };
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
index 4a3b3c73fd6b..af3027afa73c 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
+++ b/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
More information about the lldb-commits
mailing list