mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-03-13 13:49:00 +08:00
When running test-case gdb.arch/i386-mpx-call.exp with target board unix/-m32, we run into: ... (gdb) continue^M Continuing.^M (gdb) FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd0: continue to a bnd violation ... Let's look first for reference at -m64, where the test passes. The test-case uses -mmpx -fcheck-pointer-bounds to generate pointer checks in the exec. Effectively, -fcheck-pointer-bounds modifies the calling ABI: a call passes pointer bounds as well as arguments. The call to upper (with four pointer arguments and an int argument, passed in 5 registers) is modified like this: ... lea -0xa0(%rbp),%rcx lea -0x80(%rbp),%rdx lea -0x60(%rbp),%rsi lea -0x40(%rbp),%rax mov $0x0,%r8d + bndmov -0x110(%rbp),%bnd3 + bndmov -0x100(%rbp),%bnd2 + bndmov -0xf0(%rbp),%bnd1 + bndmov -0xe0(%rbp),%bnd0 mov %rax,%rdi - callq <upper> + bnd callq <upper> ... passsing the four pointer bounds in bounds registers BND0-3. The top-level mechanism of the test is as follows: - run the exec to after all mallocs are done, such that all pointer variables are valid - do inferior calls, similar to those present in the program The inferior call mechanism doesn't differentiate between a call to a function compiled with -fcheck-pointer-bounds, and one without. It merely resets the bound registers to all-allowed state (see amd64_push_dummy_call), to make sure the checks don't trigger during the inferior call. [ This is the same as what happens when executing a call without bnd prefix when the BNDPRESERVE bit of the BNDCFG register is set to 0, a provision for calling an instrumented function using a non-instrumented call. ] First, two inferior calls are done (default_run and verify_default_values) with the bound registers unmodified by the test. So, the memory accesses are performed with the bounds registers set by amd64_push_dummy_call to all-allowed, and the bounds checks do not trigger. Then we try to do an inferior call with modified bounds registers, set to none-allowed. In order to do that, we set a breakpoint at *upper before doing the inferior call. Once we hit the breakpoint during the inferior call, the bounds registers are set to none-allowed, and we continue expecting to run into an triggered bounds check, which takes the shape of a sigsegv. Back to -m32. Here, the pointer arguments are passed in memory rather than registers, so with -fcheck-pointer-bounds, the pointer bounds are placed in the Bounds Table using bndstx: ... movl $0x0,0x10(%eax) lea -0x70(%ebp),%edx mov %edx,0xc(%eax) lea -0x5c(%ebp),%edx mov %edx,0x8(%eax) lea -0x48(%ebp),%edx mov %edx,0x4(%eax) lea -0x34(%ebp),%edx mov %edx,(%eax) lea 0xc(%eax),%edx mov 0xc(%eax),%ecx bndmov -0xa8(%ebp),%bnd1 bndstx %bnd1,(%edx,%ecx,1) lea 0x8(%eax),%edx mov 0x8(%eax),%ecx bndmov -0xa0(%ebp),%bnd3 bndstx %bnd3,(%edx,%ecx,1) lea 0x4(%eax),%edx mov 0x4(%eax),%ecx bndmov -0x98(%ebp),%bnd1 bndstx %bnd1,(%edx,%ecx,1) mov (%eax),%edx bndmov -0x90(%ebp),%bnd3 bndstx %bnd3,(%eax,%edx,1) bnd call 804893f <upper> ... Again, the bounds registers are reset at the start of the inferior call by amd64_push_dummy_call, and modified by the test-case, but neither has any effect. The code in upper reads the pointer bounds from the Bounds Table, not from the bounds registers. Note that for a test.c with an out-of-bounds access: ... $ cat test.c void foo (int *a) { volatile int v = a[1]; } int main (void) { int a; foo (&a); return 0; } $ gcc test.c -mmpx -fcheck-pointer-bounds -g -m32 $ ./a.out Saw a #BR! status 1 at 0x804848d ... and inferior call foo (&a) right before "bnd call foo" (at the point that the bounds for a are setup in the bounds table) doesn't trigger a bounds violation: ... (gdb) call foo (&a) (gdb) ... This is because the bounds table doesn't associate a pointer with bounds, but rather a pair of pointer and pointer location. So, the bound is setup for &a, with as location the pushed argument in the frame. The inferior call however executes in a dummy frame, so the bound is checked for &a with as location the pushed argument in the dummy frame, which is different, so the bounds check doesn't trigger. In conclusion, this is expected behaviour. Update the test-case to not expect to override effective pointer bounds using the bounds registers when the bounds passing is done via the Bounds Table. Tested on x86_64-linux. gdb/testsuite/ChangeLog: 2020-12-11 Tom de Vries <tdevries@suse.de> PR testsuite/26991 * gdb.arch/i386-mpx-call.exp: Don't expect to trigger bounds violations by setting bounds registers if the bounds are passed in the Bounds Table.
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
README for GNU development tools This directory contains various GNU compilers, assemblers, linkers, debuggers, etc., plus their support routines, definitions, and documentation. If you are receiving this as part of a GDB release, see the file gdb/README. If with a binutils release, see binutils/README; if with a libg++ release, see libg++/README, etc. That'll give you info about this package -- supported targets, how to use it, how to report bugs, etc. It is now possible to automatically configure and build a variety of tools with one command. To build all of the tools contained herein, run the ``configure'' script here, e.g.: ./configure make To install them (by default in /usr/local/bin, /usr/local/lib, etc), then do: make install (If the configure script can't determine your type of computer, give it the name as an argument, for instance ``./configure sun4''. You can use the script ``config.sub'' to test whether a name is recognized; if it is, config.sub translates it to a triplet specifying CPU, vendor, and OS.) If you have more than one compiler on your system, it is often best to explicitly set CC in the environment before running configure, and to also set CC when running make. For example (assuming sh/bash/ksh): CC=gcc ./configure make A similar example using csh: setenv CC gcc ./configure make Much of the code and documentation enclosed is copyright by the Free Software Foundation, Inc. See the file COPYING or COPYING.LIB in the various directories, for a description of the GNU General Public License terms under which you can copy the files. REPORTING BUGS: Again, see gdb/README, binutils/README, etc., for info on where and how to report problems.
Description
Languages
C
51.3%
Makefile
22.7%
Assembly
12.5%
C++
5.9%
Roff
1.4%
Other
5.6%