From 60650f2e2f40dc992f12647ee001ef87eae13f2e Mon Sep 17 00:00:00 2001 From: Walfred Tedeschi Date: Thu, 5 Sep 2013 09:09:23 +0000 Subject: [PATCH] Add MPX registers tests. 2013-11-20 Walfred Tedeschi * common/i386-gcc-cpuid.h (bit_MPX): Synchronize with gcc file. testsuite/ * gdb.arch/i386-mpx.c: New file * gdb.arch/i386-mpx.exp: New file. Change-Id: Ica4c9ee823c8210ca876e31f27dcd8583b660a9f Signed-off-by: Walfred Tedeschi --- gdb/ChangeLog | 4 + gdb/common/i386-gcc-cpuid.h | 8 +- gdb/testsuite/ChangeLog | 5 ++ gdb/testsuite/gdb.arch/i386-mpx.c | 92 +++++++++++++++++++++++ gdb/testsuite/gdb.arch/i386-mpx.exp | 142 ++++++++++++++++++++++++++++++++++++ 5 files changed, 250 insertions(+), 1 deletion(-) create mode 100644 gdb/testsuite/gdb.arch/i386-mpx.c create mode 100644 gdb/testsuite/gdb.arch/i386-mpx.exp diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ff812f4..55eac28 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,9 @@ 2013-11-20 Walfred Tedeschi + * common/i386-gcc-cpuid.h (bit_MPX): Synchronize with gcc file. + +2013-11-20 Walfred Tedeschi + * python/lib/gdb/command/bound_register.py: New file. * gdb/data-directory/Makefile.in: copy bond_register.py to the right path to be initialized at gdb startup. diff --git a/gdb/common/i386-gcc-cpuid.h b/gdb/common/i386-gcc-cpuid.h index e045ba8..dafb21c 100644 --- a/gdb/common/i386-gcc-cpuid.h +++ b/gdb/common/i386-gcc-cpuid.h @@ -75,8 +75,14 @@ #define bit_AVX2 (1 << 5) #define bit_BMI2 (1 << 8) #define bit_RTM (1 << 11) +#define bit_AVX512F (1 << 16) +#define bit_MPX (1 << 14) #define bit_RDSEED (1 << 18) #define bit_ADX (1 << 19) +#define bit_AVX512PF (1 << 26) +#define bit_AVX512ER (1 << 27) +#define bit_AVX512CD (1 << 28) +#define bit_SHA (1 << 29) /* Extended State Enumeration Sub-leaf (%eax == 13, %ecx == 1) */ #define bit_XSAVEOPT (1 << 0) @@ -207,7 +213,7 @@ __get_cpuid_max (unsigned int __ext, unsigned int *__sig) { unsigned int __eax, __ebx, __ecx, __edx; -#ifdef __i386__ +#ifndef __x86_64__ /* See if we can use cpuid. On AMD64 we always can. */ #if __GNUC__ >= 3 __asm__ ("pushf{l|d}\n\t" diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 871c2c8..560f674 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,10 +1,15 @@ 2013-11-20 Walfred Tedeschi + * gdb.arch/i386-mpx.c: New file + * gdb.arch/i386-mpx.exp: New file. + 2013-11-20 Walfred Tedeschi * gdb.python/py-pp-maint.exp: Consider new pretty-print added for bnd registers. +2013-11-20 Walfred Tedeschi + * gdb.xml/maint_print_struct.xml (bitfield): Added bitfield having start and end equal 0. diff --git a/gdb/testsuite/gdb.arch/i386-mpx.c b/gdb/testsuite/gdb.arch/i386-mpx.c new file mode 100644 index 0000000..db7cb3b --- /dev/null +++ b/gdb/testsuite/gdb.arch/i386-mpx.c @@ -0,0 +1,92 @@ +/* Test program for MPX registers. + + Copyright 2013 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include +#include "i386-cpuid.h" + +#ifndef NOINLINE +#define NOINLINE __attribute__ ((noinline)) +#endif + +unsigned int have_mpx (void) NOINLINE; + +unsigned int NOINLINE +have_mpx (void) +{ + unsigned int eax, ebx, ecx, edx; + + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) + return 0; + + if ((ecx & bit_OSXSAVE) == bit_OSXSAVE) + { + if (__get_cpuid_max (0, NULL) < 7) + return 0; + + __cpuid_count (7, 0, eax, ebx, ecx, edx); + + if ((ebx & bit_MPX) == bit_MPX) + return 1; + else + return 0; + } +} + +int +main (int argc, char **argv) +{ + if (have_mpx ()) + { +#ifdef __x86_64__ + asm ("mov $10, %rax\n\t" + "mov $9, %rdx\n\t" + "bndmk (%rax,%rdx), %bnd0\n\t" + "mov $20, %rax\n\t" + "mov $9, %rdx\n\t" + "bndmk (%rax,%rdx), %bnd1\n\t" + "mov $30, %rax\n\t" + "mov $9, %rdx\n\t" + "bndmk (%rax,%rdx), %bnd2\n\t" + "mov $40, %rax\n\t" + "mov $9, %rdx\n\t" + "bndmk (%rax,%rdx), %bnd3\n\t" + "bndstx %bnd3, (%rax) \n\t" + "nop\n\t" + ); +#else + asm ("mov $10, %eax\n\t" + "mov $9, %edx\n\t" + "bndmk (%eax,%edx), %bnd0\n\t" + "mov $20, %eax\n\t" + "mov $9, %edx\n\t" + "bndmk (%eax,%edx), %bnd1\n\t" + "mov $30, %eax\n\t" + "mov $9, %edx\n\t" + "bndmk (%eax,%edx), %bnd2\n\t" + "mov $40, %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"); /* break here. */ + } + return 0; +} diff --git a/gdb/testsuite/gdb.arch/i386-mpx.exp b/gdb/testsuite/gdb.arch/i386-mpx.exp new file mode 100644 index 0000000..ff1c2eb --- /dev/null +++ b/gdb/testsuite/gdb.arch/i386-mpx.exp @@ -0,0 +1,142 @@ +# Copyright 2013 Free Software Foundation, Inc. +# +# Contributed by Intel Corp. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +if { ![istarget i?86-*-*] && ![istarget x86_64-*-* ] } { + verbose "Skipping x86 MPX tests." + return +} + +standard_testfile + +set comp_flags "-fmpx -I${srcdir}/../common" + +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ + [list debug nowarnings additional_flags=${comp_flags}]] } { + return -1 +} + +if ![runto_main] { + untested "could not run to main" + return -1 +} + +send_gdb "print have_mpx ()\r" +gdb_expect { + -re ".. = 1\r\n$gdb_prompt " { + pass "check whether processor supports MPX" + } + -re ".. = 0\r\n$gdb_prompt " { + verbose "processor does not support MPX; skipping MPX tests" + return + } + -re ".*$gdb_prompt $" { + fail "check whether processor supports MPX" + } + timeout { + fail "check whether processor supports MPX (timeout)" + } +} + +# Test bndcfg register and bndstatus at startup +set test_string "\\\{raw = 0x\[0-9a-f\]+, config = \\\{base = \[0-9\]+,\ +reserved = \[0-9\]+, preserved = \[0-9\]+, enabled = \[0-9\]+\\\}\\\}" + +gdb_test "print \$bndcfgu" $test_string "bndcfgu formating" +gdb_test "print \$bndcfgu.config.enabled" "= 1" "test if bndstatus is enabled" +gdb_test "print \$bndstatus" "\\\{raw = 0x0, status = \\\{bde = 0, error = 0\\\}\\\}" \ + "bndstatus formating" +gdb_test "print \$bndstatus.raw" "= \\\(void \\\*\\\) 0x0" "bndstatus is zero by startup" + +# Read values from pseudo registers. +gdb_breakpoint [ gdb_get_line_number "break here" ] +gdb_continue_to_breakpoint "break here" ".*break here.*" + +set test_string ".*\\\{lbound = 0xa, ubound = 0x13\\\}.*" +gdb_test "info register bnd0" ".*bnd0$test_string" "Pure bnd0 register" + +set test_string ".*\\\{lbound = 0x14, ubound = 0x1d\\\}.*" +gdb_test "info register bnd1" ".*bnd1$test_string" "Pure bnd1 register" + +set test_string ".*\\\{lbound = 0x1e, ubound = 0x27\\\}.*" +gdb_test "info register bnd2" ".*bnd2$test_string" "Pure bnd2 register" + +set test_string ".*\\\{lbound = 0x28, ubound = 0x31\\\}.*" +gdb_test "info register bnd3" ".*bnd3$test_string" "Pure bnd3 register" + +# Read value from registers bndrs. + +set test_string ".*\\\{lbound = 0xa, ubound_raw = 0x\[f\]+ec\\\}.*" +gdb_test "info register bnd0raw" ".*bnd0$test_string" "Pure bnd0r register" + +set test_string ".*\\\{lbound = 0x14, ubound_raw = 0x\[f\]+e2\\\}.*" +gdb_test "info register bnd1raw" ".*bnd1$test_string" "Pure bnd1r register" + +set test_string ".*\\\{lbound = 0x1e, ubound_raw = 0x\[f\]+d8\\\}.*" +gdb_test "info register bnd2raw" ".*bnd2$test_string" "Pure bnd2r register" + +set test_string ".*\\\{lbound = 0x28, ubound_raw = 0x\[f\]+ce\\\}.*" +gdb_test "info register bnd3raw" ".*bnd3$test_string" "Pure bnd3r register" + +# Setting fields on bnds +set test_string ".*\\\{lbound = 0xa, ubound = 0x400\\\}.*" +gdb_test "print \$bnd0.ubound = 0x400" "= \\\(void \\\*\\\) 0x400" "set value for bnd0.ubound" +gdb_test "print \$bnd0" "$test_string" "after setting bnd0.ubound" +set test_string ".*\\\{lbound = 0xa, ubound_raw = 0x\[f\]+bff\\\}.*" +gdb_test "print /x \$bnd0raw" "$test_string" "bnd0raw after set bnd0.ubound" + +set test_string ".*\\\{lbound = 0x1, ubound = 0x400\\\}.*" +gdb_test "print \$bnd0.lbound = 0x1" "= \\\(void \\\*\\\) 0x1" "set value for bnd0.lbound" +gdb_test "print \$bnd0" "$test_string" "after setting bnd0.lbound" +set test_string ".*\\\{lbound = 0x1, ubound_raw = 0x\[f\]+bff\\\}.*" +gdb_test "print /x \$bnd0raw" "$test_string" "bnd0raw after set bnd0.lbound" + +# Setting fields on bnd0raw. +set test_string ".*\\\{lbound = 0x1, ubound_raw = 0x600\\\}.*" +gdb_test "print /x \$bnd0raw.ubound_raw = 0x600" "= 0x600" "set value for bnd0raw.ubound" +gdb_test "print /x \$bnd0raw" "$test_string" "bnd0raw after setting bnd0raw.ubound" +set test_string ".*\\\{lbound = 0x1, ubound = 0x\[f\]+9ff\\\}.*" +gdb_test "print /x \$bnd0" "$test_string" "bnd0 after set bnd0raw.ubound" + +set test_string ".*\\\{lbound = 0x100, ubound_raw = 0x600\\\}.*" +gdb_test "print /x \$bnd0raw.lbound = 0x100" "= 0x100" "set value for bnd0raw.lbound" +gdb_test "print /x \$bnd0raw" "$test_string" "bnd0raw after setting bnd0raw.lbound" +set test_string ".*\\\{lbound = 0x100, ubound = 0x\[f\]+9ff\\\}.*" +gdb_test "print /x \$bnd0" "$test_string" "bnd0 after set bnd0raw.lbound" + +# Set full value bnd raw +set test_string ".*\\\{lbound = 0x10, ubound_raw = 0x\[f\]+cff\\\}.*" +gdb_test "print /x \$bnd0raw = {0x10, ~0x300}" "$test_string" "set full value for bnd0raw" +set test_string ".*\\\{lbound = 0x10, ubound = 0x300\\\}.*" +gdb_test "print /x \$bnd0" "$test_string" "bnd0raw after setting full bnd0raw" + +# Set full value bnd +set test_string ".*\\\{lbound = 0x10, ubound = 0x300\\\}.*" +gdb_test "print /x \$bnd0 = {0x10, 0x300}" "$test_string" "set full value for bnd0" +set test_string ".*\\\{lbound = 0x10, ubound_raw = 0x\[f\]+cff\\\}.*" +gdb_test "print /x \$bnd0raw" "$test_string" "bnd0raw after setting full bnd0" + +# Test bndcfg register and bndstatus after a failure on bndstr +gdb_test "print \$bndstatus.status.error" "= 2" "bndstatus error is 2\ +after a failure on allocating an entry" + +# Going to test the python extension for lenght. +if { [skip_python_tests] } { continue } +# Verify if size is right +set test_string ".*\\\: size 17.*" +gdb_test "print /x \$bnd0 = {0x10, 0x20}" "$test_string" "verify size for bnd0" + +send_gdb "quit\n" -- 2.7.4