/* Target-dependent code for GNU/Linux i386.
- Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ Copyright (C) 2000-2017 Free Software Foundation, Inc.
This file is part of GDB.
#include "i386-tdep.h"
#include "i386-linux-tdep.h"
#include "linux-tdep.h"
+#include "utils.h"
#include "glibc-tdep.h"
#include "solib-svr4.h"
#include "symtab.h"
#include "features/i386/i386-linux.c"
#include "features/i386/i386-mmx-linux.c"
#include "features/i386/i386-mpx-linux.c"
+#include "features/i386/i386-avx-mpx-linux.c"
#include "features/i386/i386-avx-linux.c"
-#include "features/i386/i386-avx512-linux.c"
+#include "features/i386/i386-avx-avx512-linux.c"
+#include "features/i386/i386-avx-mpx-avx512-pku-linux.c"
/* Return non-zero, when the register is in the corresponding register
group. Put the LINUX_ORIG_EAX register in the system group. */
return gdb_sys_no_syscall;
}
+/* Value of the sigcode in case of a boundary fault. */
+
+#define SIG_CODE_BONDARY_FAULT 3
+
+/* i386 GNU/Linux implementation of the handle_segmentation_fault
+ gdbarch hook. Displays information related to MPX bound
+ violations. */
+void
+i386_linux_handle_segmentation_fault (struct gdbarch *gdbarch,
+ struct ui_out *uiout)
+{
+ /* -Wmaybe-uninitialized */
+ CORE_ADDR lower_bound = 0, upper_bound = 0, access = 0;
+ int is_upper;
+ long sig_code = 0;
+
+ if (!i386_mpx_enabled ())
+ return;
+
+ TRY
+ {
+ /* Sigcode evaluates if the actual segfault is a boundary violation. */
+ sig_code = parse_and_eval_long ("$_siginfo.si_code\n");
+
+ lower_bound
+ = parse_and_eval_long ("$_siginfo._sifields._sigfault._addr_bnd._lower");
+ upper_bound
+ = parse_and_eval_long ("$_siginfo._sifields._sigfault._addr_bnd._upper");
+ access
+ = parse_and_eval_long ("$_siginfo._sifields._sigfault.si_addr");
+ }
+ CATCH (exception, RETURN_MASK_ALL)
+ {
+ return;
+ }
+ END_CATCH
+
+ /* If this is not a boundary violation just return. */
+ if (sig_code != SIG_CODE_BONDARY_FAULT)
+ return;
+
+ is_upper = (access > upper_bound ? 1 : 0);
+
+ uiout->text ("\n");
+ if (is_upper)
+ uiout->field_string ("sigcode-meaning", _("Upper bound violation"));
+ else
+ uiout->field_string ("sigcode-meaning", _("Lower bound violation"));
+
+ uiout->text (_(" while accessing address "));
+ uiout->field_fmt ("bound-access", "%s", paddress (gdbarch, access));
+
+ uiout->text (_("\nBounds: [lower = "));
+ uiout->field_fmt ("lower-bound", "%s", paddress (gdbarch, lower_bound));
+
+ uiout->text (_(", upper = "));
+ uiout->field_fmt ("upper-bound", "%s", paddress (gdbarch, upper_bound));
+
+ uiout->text (_("]"));
+}
+
/* Parse the arguments of current system call instruction and record
the values of the registers and memory that will be changed into
"record_arch_list". This instruction is "int 0x80" (Linux
-1, -1, /* MPX registers BNDCFGU, BNDSTATUS. */
-1, -1, -1, -1, -1, -1, -1, -1, /* k0 ... k7 (AVX512) */
-1, -1, -1, -1, -1, -1, -1, -1, /* zmm0 ... zmm7 (AVX512) */
+ -1, /* PKRU register */
11 * 4, /* "orig_eax" */
};
switch ((xcr0 & X86_XSTATE_ALL_MASK))
{
- case X86_XSTATE_MPX_AVX512_MASK:
- case X86_XSTATE_AVX512_MASK:
- return tdesc_i386_avx512_linux;
+ case X86_XSTATE_AVX_MPX_AVX512_PKU_MASK:
+ return tdesc_i386_avx_mpx_avx512_pku_linux;
+ case X86_XSTATE_AVX_AVX512_MASK:
+ return tdesc_i386_avx_avx512_linux;
case X86_XSTATE_MPX_MASK:
return tdesc_i386_mpx_linux;
+ case X86_XSTATE_AVX_MPX_MASK:
+ return tdesc_i386_avx_mpx_linux;
case X86_XSTATE_AVX_MASK:
return tdesc_i386_avx_linux;
case X86_XSTATE_SSE_MASK:
i386_linux_get_syscall_number);
set_gdbarch_get_siginfo_type (gdbarch, x86_linux_get_siginfo_type);
+ set_gdbarch_handle_segmentation_fault (gdbarch,
+ i386_linux_handle_segmentation_fault);
}
/* Provide a prototype to silence -Wmissing-prototypes. */
initialize_tdesc_i386_mmx_linux ();
initialize_tdesc_i386_avx_linux ();
initialize_tdesc_i386_mpx_linux ();
- initialize_tdesc_i386_avx512_linux ();
+ initialize_tdesc_i386_avx_mpx_linux ();
+ initialize_tdesc_i386_avx_avx512_linux ();
+ initialize_tdesc_i386_avx_mpx_avx512_pku_linux ();
}