binutils-gdb/gdb/testsuite/gdb.arch
Tom de Vries 346e7e1923 [gdb/testsuite] Update gdb.arch/i386-mpx-call.exp for -m32
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.
2020-12-11 18:26:40 +01:00
..
aarch64-atomic-inst.c
aarch64-atomic-inst.exp
aarch64-brk-patterns.c
aarch64-brk-patterns.exp
aarch64-dbreg-contents.c
aarch64-dbreg-contents.exp
aarch64-fp.c
aarch64-fp.exp
aarch64-pauth.c
aarch64-pauth.exp
aarch64-prologue.c
aarch64-prologue.exp
aarch64-sighandler-regs.c
aarch64-sighandler-regs.exp
aarch64-tagged-pointer.c
aarch64-tagged-pointer.exp
aix-sighandle.c
aix-sighandle.exp
alpha-step.c
alpha-step.exp
altivec-abi.c
altivec-abi.exp
altivec-regs.c
altivec-regs.exp
amd64-break-on-asm-line.exp
amd64-break-on-asm-line.S
amd64-byte.exp
amd64-disp-step-avx.exp gdb: move displaced stepping logic to gdbarch, allow starting concurrent displaced steps 2020-12-04 16:43:55 -05:00
amd64-disp-step-avx.S
amd64-disp-step.exp
amd64-disp-step.S
amd64-dword.exp
amd64-entry-value-inline.c
amd64-entry-value-inline.exp
amd64-entry-value-inline.S
amd64-entry-value-param-dwarf5.c
amd64-entry-value-param-dwarf5.exp
amd64-entry-value-param-dwarf5.S
amd64-entry-value-param.c
amd64-entry-value-param.exp
amd64-entry-value-param.S
amd64-entry-value-paramref.cc
amd64-entry-value-paramref.exp
amd64-entry-value-paramref.S
amd64-entry-value.cc
amd64-entry-value.exp
amd64-entry-value.s
amd64-eval.cc
amd64-eval.exp
amd64-gs_base.c
amd64-gs_base.exp [gdb/testsuite] Simplify gdb.arch/amd64-gs_base.exp 2020-12-08 09:29:40 +01:00
amd64-i386-address.exp
amd64-i386-address.S
amd64-init-x87-values.exp
amd64-init-x87-values.S
amd64-invalid-stack-middle.c
amd64-invalid-stack-middle.exp
amd64-invalid-stack-middle.S
amd64-invalid-stack-top.c
amd64-invalid-stack-top.exp
amd64-optimout-repeat.c
amd64-optimout-repeat.exp
amd64-optimout-repeat.S
amd64-osabi.exp
amd64-prologue-skip.exp
amd64-prologue-skip.S
amd64-prologue-xmm.c
amd64-prologue-xmm.exp
amd64-prologue-xmm.s
amd64-pseudo.c
amd64-stap-optional-prefix.exp
amd64-stap-optional-prefix.S
amd64-stap-special-operands.exp
amd64-stap-three-arg-disp.c
amd64-stap-three-arg-disp.S
amd64-stap-triplet.c
amd64-stap-triplet.S
amd64-stap-wrong-subexp.exp
amd64-stap-wrong-subexp.S
amd64-tailcall-cxx1.cc
amd64-tailcall-cxx1.S
amd64-tailcall-cxx2.cc
amd64-tailcall-cxx2.S
amd64-tailcall-cxx.exp
amd64-tailcall-noret.c
amd64-tailcall-noret.exp
amd64-tailcall-noret.S
amd64-tailcall-ret.c
amd64-tailcall-ret.exp
amd64-tailcall-ret.S
amd64-tailcall-self.c
amd64-tailcall-self.exp
amd64-tailcall-self.S
amd64-word.exp
arc-analyze-prologue.exp
arc-analyze-prologue.S
arc-decode-insn.exp
arc-decode-insn.S
arc-tdesc-cpu.exp
arc-tdesc-cpu.xml
arm-bl-branch-dest.c
arm-bl-branch-dest.exp
arm-cmse-sgstubs.c
arm-cmse-sgstubs.exp
arm-disassembler-options.exp
arm-disp-step.exp
arm-disp-step.S
arm-neon.c
arm-neon.exp
arm-single-step-kernel-helper.c
arm-single-step-kernel-helper.exp
avr-flash-qualifier.c
avr-flash-qualifier.exp
cordic.ko.bz2
cordic.ko.debug.bz2
disp-step-insn-reloc.exp
e500-abi.c
e500-abi.exp
e500-prologue.c
e500-prologue.exp
e500-regs.c
e500-regs.exp
ftrace-insn-reloc.exp
gdb1291.exp
gdb1291.s
gdb1431.exp
gdb1431.s
gdb1558.c
gdb1558.exp
i386-avx512.c
i386-avx512.exp
i386-avx.c
i386-avx.exp
i386-biarch-core.core.bz2
i386-biarch-core.exp
i386-bp_permanent.c
i386-bp_permanent.exp
i386-byte.exp
i386-cfi-notcurrent.exp
i386-cfi-notcurrent.S
i386-disp-step.exp
i386-disp-step.S
i386-dr3-watch.c
i386-dr3-watch.exp
i386-float.exp
i386-float.S
i386-gnu-cfi-asm.S
i386-gnu-cfi.c
i386-gnu-cfi.exp
i386-mpx-call.c
i386-mpx-call.exp [gdb/testsuite] Update gdb.arch/i386-mpx-call.exp for -m32 2020-12-11 18:26:40 +01:00
i386-mpx-map.c
i386-mpx-map.exp
i386-mpx-sigsegv.c
i386-mpx-sigsegv.exp
i386-mpx-simple_segv.c
i386-mpx-simple_segv.exp
i386-mpx.c
i386-mpx.exp
i386-permbkpt.exp
i386-permbkpt.S
i386-pkru.c
i386-pkru.exp
i386-prologue-skip-cf-protection.c
i386-prologue-skip-cf-protection.exp
i386-prologue.c
i386-prologue.exp
i386-pseudo.c
i386-signal.c
i386-signal.exp
i386-size-overlap.c
i386-size-overlap.exp
i386-size.c
i386-size.exp
i386-sse-stack-align.c
i386-sse-stack-align.exp
i386-sse-stack-align.S
i386-sse.c
i386-sse.exp
i386-stap-eval-lang-ada.c
i386-stap-eval-lang-ada.exp
i386-stap-eval-lang-ada.S
i386-unwind.c
i386-unwind.exp
i386-word.exp
ia64-breakpoint-shadow.exp
ia64-breakpoint-shadow.S
insn-reloc.c
iwmmxt-regs.c
iwmmxt-regs.exp
mips16-thunks-inmain.c
mips16-thunks-main.c
mips16-thunks-sin.c
mips16-thunks-sinfrob16.c
mips16-thunks-sinfrob.c
mips16-thunks-sinmain.c
mips16-thunks-sinmips16.c
mips16-thunks.exp
mips-disassembler-options.exp
mips-disassembler-options.s
mips-fcr.c
mips-fcr.exp
mips-fpregset-core.c
mips-fpregset-core.exp
mips-octeon-bbit.c
mips-octeon-bbit.exp
pa64-nullify.s
pa-nullify.exp
pa-nullify.s
powerpc-aix-prologue.c
powerpc-aix-prologue.exp
powerpc-altivec2.exp
powerpc-altivec2.s
powerpc-altivec3.exp
powerpc-altivec3.s
powerpc-altivec.exp
powerpc-altivec.s
powerpc-d128-regs.c
powerpc-d128-regs.exp
powerpc-disassembler-options.exp
powerpc-fpscr-gcore.exp
powerpc-htm-regs.c
powerpc-htm-regs.exp
powerpc-power7.exp
powerpc-power7.s
powerpc-power8.exp
powerpc-power8.s
powerpc-power9.exp
powerpc-power9.s
powerpc-ppr-dscr.c
powerpc-ppr-dscr.exp
powerpc-prologue-frame.c
powerpc-prologue-frame.exp
powerpc-prologue-frame.S
powerpc-prologue.c
powerpc-prologue.exp
powerpc-stackless.exp
powerpc-stackless.S
powerpc-tar.c
powerpc-tar.exp
powerpc-vector-regs.c
powerpc-vector-regs.exp
powerpc-vsx2.exp
powerpc-vsx2.s
powerpc-vsx3.exp
powerpc-vsx3.s
powerpc-vsx-gcore.exp
powerpc-vsx.exp
powerpc-vsx.s
ppc64-atomic-inst.exp
ppc64-atomic-inst.S
ppc64-isa207-atomic-inst.c
ppc64-isa207-atomic-inst.exp
ppc64-isa207-atomic-inst.S
ppc64-symtab-cordic.exp
ppc-dfp.c
ppc-dfp.exp
ppc-fp.c
ppc-fp.exp
ppc-longdouble.c
ppc-longdouble.exp
pr25124.exp
pr25124.S
riscv-bp-infcall.c
riscv-bp-infcall.exp
riscv-reg-aliases.c
riscv-reg-aliases.exp
riscv-tdesc-loading-01.xml
riscv-tdesc-loading-02.xml
riscv-tdesc-loading-03.xml
riscv-tdesc-loading-04.xml
riscv-tdesc-loading.exp
riscv-tdesc-regs-32.xml
riscv-tdesc-regs-64.xml
riscv-tdesc-regs.c
riscv-tdesc-regs.exp gdb/riscv: remove csr aliases created with DECLARE_CSR_ALIAS 2020-12-02 17:47:39 +00:00
riscv-unwind-long-insn-6.s
riscv-unwind-long-insn-8.s
riscv-unwind-long-insn.c
riscv-unwind-long-insn.exp
s390-disassembler-options.exp
s390-multiarch.c
s390-multiarch.exp
s390-stackless.exp
s390-stackless.S
s390-tdbregs.c
s390-tdbregs.exp
s390-vregs.exp
s390-vregs.S
sparc64-adi.c
sparc64-adi.exp
sparc64-regs.exp
sparc64-regs.S
sparc-sysstep.c
sparc-sysstep.exp
thumb2-it.exp
thumb2-it.S
thumb-bx-pc.exp
thumb-bx-pc.S
thumb-prologue.c
thumb-prologue.exp
thumb-singlestep.exp
thumb-singlestep.S
vsx-regs.c
vsx-regs.exp
x86-avx512bf16.c
x86-avx512bf16.exp