Author: valentinagiusti Date: Thu Oct 6 13:05:12 2016 New Revision: 283474
URL: http://llvm.org/viewvc/llvm-project?rev=283474&view=rev Log: Add bound violation handling for Intel(R) Memory Protection Extensions (Intel(R) MPX) Summary: This patch adds support for handling the SIGSEGV signal with 'si_code == SEGV_BNDERR', which is thrown when a bound violation is caught by the Intel(R) MPX technology. Differential Revision: https://reviews.llvm.org/D25329 Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/register/intel_xtended_registers/mpx_bound_violation/ lldb/trunk/packages/Python/lldbsuite/test/functionalities/register/intel_xtended_registers/mpx_bound_violation/Makefile lldb/trunk/packages/Python/lldbsuite/test/functionalities/register/intel_xtended_registers/mpx_bound_violation/TestBoundViolation.py lldb/trunk/packages/Python/lldbsuite/test/functionalities/register/intel_xtended_registers/mpx_bound_violation/main.cpp Modified: lldb/trunk/source/Plugins/Process/Linux/NativeThreadLinux.cpp lldb/trunk/source/Plugins/Process/POSIX/CrashReason.cpp lldb/trunk/source/Plugins/Process/POSIX/CrashReason.h Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/register/intel_xtended_registers/mpx_bound_violation/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/register/intel_xtended_registers/mpx_bound_violation/Makefile?rev=283474&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/register/intel_xtended_registers/mpx_bound_violation/Makefile (added) +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/register/intel_xtended_registers/mpx_bound_violation/Makefile Thu Oct 6 13:05:12 2016 @@ -0,0 +1,7 @@ +LEVEL = ../../../../make + +CXX_SOURCES := main.cpp + +CFLAGS_EXTRAS += -mmpx -fcheck-pointer-bounds -fuse-ld=bfd + +include $(LEVEL)/Makefile.rules Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/register/intel_xtended_registers/mpx_bound_violation/TestBoundViolation.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/register/intel_xtended_registers/mpx_bound_violation/TestBoundViolation.py?rev=283474&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/register/intel_xtended_registers/mpx_bound_violation/TestBoundViolation.py (added) +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/register/intel_xtended_registers/mpx_bound_violation/TestBoundViolation.py Thu Oct 6 13:05:12 2016 @@ -0,0 +1,57 @@ +""" +Test the Intel(R) MPX bound violation signal. +""" + +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__) + + @skipIf(compiler="clang") + @skipIf(oslist=no_match(['linux'])) + @skipIf(archs=no_match(['i386', 'x86_64'])) + @skipIf(oslist=["linux"], compiler="gcc", compiler_version=["<", "5"]) #GCC version >= 5 supports Intel(R) MPX. + def test_mpx_boundary_violation(self): + """Test Intel(R) MPX bound violation signal.""" + self.build() + self.mpx_boundary_violation() + + def mpx_boundary_violation(self): + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + self.runCmd("run", RUN_SUCCEEDED) + + target = self.dbg.GetSelectedTarget() + process = target.GetProcess() + + if (process.GetState() == lldb.eStateExited): + self.skipTest("Intel(R) MPX is not supported.") + + if (process.GetState() == lldb.eStateStopped): + self.expect("thread backtrace", STOPPED_DUE_TO_SIGNAL, + substrs = ['stop reason = signal SIGSEGV: upper bound violation', + 'fault address:', 'lower bound:', 'upper bound:']) + + self.runCmd("continue") + + if (process.GetState() == lldb.eStateStopped): + self.expect("thread backtrace", STOPPED_DUE_TO_SIGNAL, + substrs = ['stop reason = signal SIGSEGV: lower bound violation', + 'fault address:', 'lower bound:', 'upper bound:']) + + self.runCmd("continue") + self.assertTrue(process.GetState() == lldb.eStateExited, + PROCESS_EXITED) Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/register/intel_xtended_registers/mpx_bound_violation/main.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/register/intel_xtended_registers/mpx_bound_violation/main.cpp?rev=283474&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/register/intel_xtended_registers/mpx_bound_violation/main.cpp (added) +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/register/intel_xtended_registers/mpx_bound_violation/main.cpp Thu Oct 6 13:05:12 2016 @@ -0,0 +1,40 @@ +//===-- 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 <cstddef> +#include <sys/prctl.h> + +static void violate_upper_bound(int *ptr, int size) +{ + int i; + i = *(ptr + size); +} + +static void violate_lower_bound (int *ptr, int size) +{ + int i; + i = *(ptr - size); +} + +int +main(int argc, char const *argv[]) +{ + unsigned int rax, rbx, rcx, rdx; + int array[5]; + + // This call returns 0 only if the CPU and the kernel support Intel(R) MPX. + if (prctl(PR_MPX_ENABLE_MANAGEMENT, 0, 0, 0, 0) != 0) + return -1; + + violate_upper_bound(array, 5); + violate_lower_bound(array, 5); + + return 0; +} Modified: lldb/trunk/source/Plugins/Process/Linux/NativeThreadLinux.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeThreadLinux.cpp?rev=283474&r1=283473&r2=283474&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeThreadLinux.cpp (original) +++ lldb/trunk/source/Plugins/Process/Linux/NativeThreadLinux.cpp Thu Oct 6 13:05:12 2016 @@ -316,8 +316,7 @@ void NativeThreadLinux::SetStoppedBySign (info->si_signo == SIGBUS && info->si_code == SI_KERNEL) ? CrashReason::eInvalidAddress : GetCrashReason(*info); - m_stop_description = GetCrashReasonString( - reason, reinterpret_cast<uintptr_t>(info->si_addr)); + m_stop_description = GetCrashReasonString(reason, *info); break; } } Modified: lldb/trunk/source/Plugins/Process/POSIX/CrashReason.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/CrashReason.cpp?rev=283474&r1=283473&r2=283474&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/POSIX/CrashReason.cpp (original) +++ lldb/trunk/source/Plugins/Process/POSIX/CrashReason.cpp Thu Oct 6 13:05:12 2016 @@ -9,6 +9,8 @@ #include "CrashReason.h" +#include "llvm/Support/raw_ostream.h" + #include <sstream> namespace { @@ -19,6 +21,23 @@ void AppendFaultAddr(std::string &str, l str += ss.str(); } +void AppendBounds(std::string &str, lldb::addr_t lower_bound, + lldb::addr_t upper_bound, lldb::addr_t addr) { + llvm::raw_string_ostream stream(str); + if ((unsigned long)addr < lower_bound) + stream << ": lower bound violation "; + else + stream << ": upper bound violation "; + stream << "(fault address: 0x"; + stream.write_hex(addr); + stream << ", lower bound: 0x"; + stream.write_hex(lower_bound); + stream << ", upper bound: 0x"; + stream.write_hex(upper_bound); + stream << ")"; + stream.flush(); +} + CrashReason GetCrashReasonForSIGSEGV(const siginfo_t &info) { assert(info.si_signo == SIGSEGV); @@ -34,6 +53,11 @@ CrashReason GetCrashReasonForSIGSEGV(con return CrashReason::eInvalidAddress; case SEGV_ACCERR: return CrashReason::ePrivilegedAddress; +#ifndef SEGV_BNDERR +#define SEGV_BNDERR 3 +#endif + case SEGV_BNDERR: + return CrashReason::eBoundViolation; } assert(false && "unexpected si_code for SIGSEGV"); @@ -109,7 +133,7 @@ CrashReason GetCrashReasonForSIGBUS(cons } } -std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr) { +std::string GetCrashReasonString(CrashReason reason, const siginfo_t &info) { std::string str; switch (reason) { @@ -119,11 +143,20 @@ std::string GetCrashReasonString(CrashRe case CrashReason::eInvalidAddress: str = "signal SIGSEGV: invalid address"; - AppendFaultAddr(str, fault_addr); + AppendFaultAddr(str, reinterpret_cast<lldb::addr_t>(info.si_addr)); break; case CrashReason::ePrivilegedAddress: str = "signal SIGSEGV: address access protected"; - AppendFaultAddr(str, fault_addr); + AppendFaultAddr(str, reinterpret_cast<lldb::addr_t>(info.si_addr)); + break; + case CrashReason::eBoundViolation: + str = "signal SIGSEGV"; +// Make sure that siginfo_t has the bound fields available. +#if defined(si_lower) && defined(si_upper) + AppendBounds(str, reinterpret_cast<lldb::addr_t>(info.si_lower), + reinterpret_cast<lldb::addr_t>(info.si_upper), + reinterpret_cast<lldb::addr_t>(info.si_addr)); +#endif break; case CrashReason::eIllegalOpcode: str = "signal SIGILL: illegal instruction"; @@ -207,6 +240,9 @@ const char *CrashReasonAsString(CrashRea case CrashReason::ePrivilegedAddress: str = "ePrivilegedAddress"; break; + case CrashReason::eBoundViolation: + str = "eBoundViolation"; + break; // SIGILL crash reasons. case CrashReason::eIllegalOpcode: Modified: lldb/trunk/source/Plugins/Process/POSIX/CrashReason.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/CrashReason.h?rev=283474&r1=283473&r2=283474&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/POSIX/CrashReason.h (original) +++ lldb/trunk/source/Plugins/Process/POSIX/CrashReason.h Thu Oct 6 13:05:12 2016 @@ -22,6 +22,7 @@ enum class CrashReason { // SIGSEGV crash reasons. eInvalidAddress, ePrivilegedAddress, + eBoundViolation, // SIGILL crash reasons. eIllegalOpcode, @@ -49,7 +50,7 @@ enum class CrashReason { eFloatSubscriptRange }; -std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr); +std::string GetCrashReasonString(CrashReason reason, const siginfo_t &info); const char *CrashReasonAsString(CrashReason reason); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits