Skip to content

Commit

Permalink
Fix for rL280668, Intel(R) Memory Protection Extensions (Intel(R) MPX…
Browse files Browse the repository at this point in the history
…) support.

Summary: Signed-off-by: Valentina Giusti <valentina.giusti@intel.com>

Reviewers: dvlahovski, granata.enrico, clayborg, labath

Subscribers: lldb-commits

Differential Revision: https://reviews.llvm.org/D24255

llvm-svn: 280942
  • Loading branch information
Valentina Giusti committed Sep 8, 2016
1 parent 4d1e4d7 commit cda0ae4
Show file tree
Hide file tree
Showing 17 changed files with 639 additions and 21 deletions.
@@ -0,0 +1,7 @@
LEVEL = ../../../make

CXX_SOURCES := main.cpp

CFLAGS_EXTRAS += -mmpx -fcheck-pointer-bounds -fuse-ld=bfd

include $(LEVEL)/Makefile.rules
@@ -0,0 +1,74 @@
"""
Test the MPX registers.
"""

from __future__ import print_function


import os
import sys
import time
import re
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil


class RegisterCommandsTestCase(TestBase):

mydir = TestBase.compute_mydir(__file__)

def setUp(self):
TestBase.setUp(self)
self.has_teardown = False

def tearDown(self):
self.dbg.GetSelectedTarget().GetProcess().Destroy()
TestBase.tearDown(self)

@skipIf(compiler="clang")
@skipIf(oslist=["linux"], compiler="gcc", compiler_version=["<", "5"]) #GCC version >= 5 supports MPX.
@skipIf(oslist=no_match(['linux']))
@skipIf(archs=no_match(['i386', 'x86_64']))
def test_mpx_registers_with_example_code(self):
"""Test MPX registers with example code."""
self.build()
self.mpx_registers_with_example_code()

def mpx_registers_with_example_code(self):
"""Test MPX registers after running example code."""
self.line = line_number('main.cpp', '// Set a break point here.')

exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)

lldbutil.run_break_set_by_file_and_line(self, "main.cpp", self.line, num_expected_locations=1)
self.runCmd("run", RUN_SUCCEEDED)

target = self.dbg.GetSelectedTarget()
process = target.GetProcess()

if (process.GetState() == lldb.eStateExited):
self.skipTest("HW doesn't support MPX feature.")
else:
self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
substrs = ["stop reason = breakpoint 1."])

if self.getArchitecture() == 'x86_64':
self.expect("register read -s 3",
substrs = ['bnd0 = {0x0000000000000010 0xffffffffffffffe6}',
'bnd1 = {0x0000000000000020 0xffffffffffffffd6}',
'bnd2 = {0x0000000000000030 0xffffffffffffffc6}',
'bnd3 = {0x0000000000000040 0xffffffffffffffb6}',
'bndcfgu = {0x01 0x80 0xb5 0x76 0xff 0x7f 0x00 0x00}',
'bndstatus = {0x02 0x80 0xb5 0x76 0xff 0x7f 0x00 0x00}'])
if self.getArchitecture() == 'i386':
self.expect("register read -s 3",
substrs = ['bnd0 = {0x0000000000000010 0x00000000ffffffe6}',
'bnd1 = {0x0000000000000020 0x00000000ffffffd6}',
'bnd2 = {0x0000000000000030 0x00000000ffffffc6}',
'bnd3 = {0x0000000000000040 0x00000000ffffffb6}',
'bndcfgu = {0x01 0xd0 0x7d 0xf7 0x00 0x00 0x00 0x00}',
'bndstatus = {0x02 0xd0 0x7d 0xf7 0x00 0x00 0x00 0x00}'])

@@ -0,0 +1,69 @@
//===-- main.cpp ------------------------------------------------*- C++ -*-===//
////
//// The LLVM Compiler Infrastructure
////
//// This file is distributed under the University of Illinois Open Source
//// License. See LICENSE.TXT for details.
////
////===----------------------------------------------------------------------===//
//

#include <cpuid.h>
#include <cstddef>

int
main(int argc, char const *argv[])
{
unsigned int rax, rbx, rcx, rdx;

// Check if XSAVE is enabled.
if (!__get_cpuid(1, &rax, &rbx, &rcx, &rdx) || (rcx & bit_OSXSAVE) != bit_OSXSAVE)
return -1;

// Check if MPX is enabled.
if (__get_cpuid_max(0, NULL) > 7)
{
__cpuid_count(7, 0, rax, rbx, rcx, rdx);
if ((rbx & bit_MPX) != bit_MPX)
return -1;
}
else
return -1;

// Run MPX test code.
#if defined(__x86_64__)
asm("mov $16, %rax\n\t"
"mov $9, %rdx\n\t"
"bndmk (%rax,%rdx), %bnd0\n\t"
"mov $32, %rax\n\t"
"mov $9, %rdx\n\t"
"bndmk (%rax,%rdx), %bnd1\n\t"
"mov $48, %rax\n\t"
"mov $9, %rdx\n\t"
"bndmk (%rax,%rdx), %bnd2\n\t"
"mov $64, %rax\n\t"
"mov $9, %rdx\n\t"
"bndmk (%rax,%rdx), %bnd3\n\t"
"bndstx %bnd3, (%rax) \n\t"
"nop\n\t");
#endif
#if defined(__i386__)
asm("mov $16, %eax\n\t"
"mov $9, %edx\n\t"
"bndmk (%eax,%edx), %bnd0\n\t"
"mov $32, %eax\n\t"
"mov $9, %edx\n\t"
"bndmk (%eax,%edx), %bnd1\n\t"
"mov $48, %eax\n\t"
"mov $9, %edx\n\t"
"bndmk (%eax,%edx), %bnd2\n\t"
"mov $64, %eax\n\t"
"mov $9, %edx\n\t"
"bndmk (%eax,%edx), %bnd3\n\t"
"bndstx %bnd3, (%eax)\n\t"
"nop\n\t");
#endif
asm("nop\n\t"); // Set a break point here.

return 0;
}
@@ -1,4 +1,4 @@
LEVEL = ../../make
LEVEL = ../../../make

CXX_SOURCES := main.cpp a.cpp

Expand Down
Expand Up @@ -43,13 +43,14 @@ def test_register_commands(self):
if self.getArchitecture() in ['amd64', 'i386', 'x86_64']:
self.runCmd("register read xmm0")
self.runCmd("register read ymm15") # may be available
self.runCmd("register read bnd0") # may be available
elif self.getArchitecture() in ['arm']:
self.runCmd("register read s0")
self.runCmd("register read q15") # may be available

self.expect(
"register read -s 3",
substrs=['invalid register set index: 3'],
"register read -s 4",
substrs=['invalid register set index: 4'],
error=True)

@skipIfiOSSimulator
Expand Down Expand Up @@ -354,12 +355,14 @@ def fp_register_write(self):
' = 0'])

has_avx = False
has_mpx = False
# Returns an SBValueList.
registerSets = currentFrame.GetRegisters()
for registerSet in registerSets:
if 'advanced vector extensions' in registerSet.GetName().lower():
has_avx = True
break
if 'memory protection extension' in registerSet.GetName().lower():
has_mpx = True

if has_avx:
new_value = "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x09 0x0a 0x2f 0x2f 0x2f 0x2f 0x0e 0x0f 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0c 0x0d 0x0e 0x0f}"
Expand All @@ -369,6 +372,21 @@ def fp_register_write(self):
else:
self.runCmd("register read ymm0")

if has_mpx:
# Test write and read for bnd0.
new_value_w = "{0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10}"
self.runCmd("register write bnd0 \'" + new_value_w + "\'")
new_value_r = "{0x0807060504030201 0x100f0e0d0c0b0a09}"
self.expect("register read bnd0", substrs = ['bnd0 = ', new_value_r])
self.expect("expr $bnd0", substrs = ['vector_type'])

# Test write and for bndstatus.
new_value = "{0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08}"
self.write_and_read(currentFrame, "bndstatus", new_value)
self.expect("expr $bndstatus", substrs = ['vector_type'])
else:
self.runCmd("register read bnd0")

def convenience_registers(self):
"""Test convenience registers."""
self.common_setup()
Expand Down
79 changes: 78 additions & 1 deletion lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
Expand Up @@ -104,7 +104,12 @@ enum dwarf_regnums {
dwarf_mm4,
dwarf_mm5,
dwarf_mm6,
dwarf_mm7
dwarf_mm7,

dwarf_bnd0 = 101,
dwarf_bnd1,
dwarf_bnd2,
dwarf_bnd3
};

static RegisterInfo g_register_infos[] = {
Expand Down Expand Up @@ -703,6 +708,78 @@ static RegisterInfo g_register_infos[] = {
nullptr,
nullptr,
nullptr,
0},
{"bnd0",
nullptr,
16,
0,
eEncodingVector,
eFormatVectorOfUInt64,
{dwarf_bnd0, dwarf_bnd0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM },
nullptr,
nullptr,
nullptr,
0},
{"bnd1",
nullptr,
16,
0,
eEncodingVector,
eFormatVectorOfUInt64,
{dwarf_bnd1, dwarf_bnd1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM },
nullptr,
nullptr,
nullptr,
0},
{"bnd2",
nullptr,
16,
0,
eEncodingVector,
eFormatVectorOfUInt64,
{dwarf_bnd2, dwarf_bnd2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM },
nullptr,
nullptr,
nullptr,
0},
{"bnd3",
nullptr,
16,
0,
eEncodingVector,
eFormatVectorOfUInt64,
{dwarf_bnd3, dwarf_bnd3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM },
nullptr,
nullptr,
nullptr,
0},
{"bndcfgu",
nullptr,
8,
0,
eEncodingVector,
eFormatVectorOfUInt8,
{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
nullptr,
nullptr,
nullptr,
0},
{"bndstatus",
nullptr,
8,
0,
eEncodingVector,
eFormatVectorOfUInt8,
{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
nullptr,
nullptr,
nullptr,
0}};

static const uint32_t k_num_register_infos =
Expand Down
78 changes: 77 additions & 1 deletion lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
Expand Up @@ -94,7 +94,11 @@ enum dwarf_regnums {
dwarf_ymm12,
dwarf_ymm13,
dwarf_ymm14,
dwarf_ymm15
dwarf_ymm15,
dwarf_bnd0 = 126,
dwarf_bnd1,
dwarf_bnd2,
dwarf_bnd3
};

static RegisterInfo g_register_infos[] = {
Expand Down Expand Up @@ -979,6 +983,78 @@ static RegisterInfo g_register_infos[] = {
nullptr,
nullptr,
nullptr,
0},
{"bnd0",
nullptr,
16,
0,
eEncodingVector,
eFormatVectorOfUInt64,
{dwarf_bnd0, dwarf_bnd0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM},
nullptr,
nullptr,
nullptr,
0},
{"bnd1",
nullptr,
16,
0,
eEncodingVector,
eFormatVectorOfUInt64,
{dwarf_bnd1, dwarf_bnd1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM},
nullptr,
nullptr,
nullptr,
0},
{"bnd2",
nullptr,
16,
0,
eEncodingVector,
eFormatVectorOfUInt64,
{dwarf_bnd2, dwarf_bnd2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM},
nullptr,
nullptr,
nullptr,
0},
{"bnd3",
nullptr,
16,
0,
eEncodingVector,
eFormatVectorOfUInt64,
{dwarf_bnd3, dwarf_bnd3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM},
nullptr,
nullptr,
nullptr,
0},
{"bndcfgu",
nullptr,
8,
0,
eEncodingVector,
eFormatVectorOfUInt8,
{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
nullptr,
nullptr,
nullptr,
0},
{"bndstatus",
nullptr,
8,
0,
eEncodingVector,
eFormatVectorOfUInt8,
{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
nullptr,
nullptr,
nullptr,
0}};

static const uint32_t k_num_register_infos =
Expand Down

0 comments on commit cda0ae4

Please sign in to comment.