/* Target-dependent code for GNU/Linux x86-64.
- Copyright (C) 2001, 2003-2012 Free Software Foundation, Inc.
+ Copyright (C) 2001-2013 Free Software Foundation, Inc.
Contributed by Jiri Smid, SuSE Labs.
This file is part of GDB.
#include "linux-tdep.h"
#include "i386-xstate.h"
-#include "gdb_string.h"
+#include <string.h>
#include "amd64-tdep.h"
#include "solib-svr4.h"
#include "features/i386/amd64-linux.c"
#include "features/i386/amd64-avx-linux.c"
+#include "features/i386/amd64-mpx-linux.c"
#include "features/i386/x32-linux.c"
#include "features/i386/x32-avx-linux.c"
/* The syscall's XML filename for i386. */
#define XML_SYSCALL_FILENAME_AMD64 "syscalls/amd64-linux.xml"
-#include "record.h"
+#include "record-full.h"
#include "linux-record.h"
/* Supported register note sections. */
-1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, /* MPX registers BND0 ... BND3. */
+ -1, -1, /* MPX registers BNDCFGU and BNDSTATUS. */
15 * 8 /* "orig_rax" */
};
\f
#define LINUX_SIGTRAMP_INSN1 0x0f /* syscall */
#define LINUX_SIGTRAMP_OFFSET1 7
-static const gdb_byte linux_sigtramp_code[] =
+static const gdb_byte amd64_linux_sigtramp_code[] =
{
/* mov $__NR_rt_sigreturn, %rax */
LINUX_SIGTRAMP_INSN0, 0xc7, 0xc0, 0x0f, 0x00, 0x00, 0x00,
LINUX_SIGTRAMP_INSN1, 0x05
};
-#define LINUX_SIGTRAMP_LEN (sizeof linux_sigtramp_code)
+static const gdb_byte amd64_x32_linux_sigtramp_code[] =
+{
+ /* mov $__NR_rt_sigreturn, %rax. */
+ LINUX_SIGTRAMP_INSN0, 0xc7, 0xc0, 0x01, 0x02, 0x00, 0x40,
+ /* syscall */
+ LINUX_SIGTRAMP_INSN1, 0x05
+};
+
+#define LINUX_SIGTRAMP_LEN (sizeof amd64_linux_sigtramp_code)
/* If PC is in a sigtramp routine, return the address of the start of
the routine. Otherwise, return 0. */
static CORE_ADDR
amd64_linux_sigtramp_start (struct frame_info *this_frame)
{
+ struct gdbarch *gdbarch;
+ const gdb_byte *sigtramp_code;
CORE_ADDR pc = get_frame_pc (this_frame);
gdb_byte buf[LINUX_SIGTRAMP_LEN];
return 0;
}
- if (memcmp (buf, linux_sigtramp_code, LINUX_SIGTRAMP_LEN) != 0)
+ gdbarch = get_frame_arch (this_frame);
+ if (gdbarch_ptr_bit (gdbarch) == 32)
+ sigtramp_code = amd64_x32_linux_sigtramp_code;
+ else
+ sigtramp_code = amd64_linux_sigtramp_code;
+ if (memcmp (buf, sigtramp_code, LINUX_SIGTRAMP_LEN) != 0)
return 0;
return pc;
static int
amd64_all_but_ip_registers_record (struct regcache *regcache)
{
- if (record_arch_list_add_reg (regcache, AMD64_RAX_REGNUM))
+ if (record_full_arch_list_add_reg (regcache, AMD64_RAX_REGNUM))
return -1;
- if (record_arch_list_add_reg (regcache, AMD64_RCX_REGNUM))
+ if (record_full_arch_list_add_reg (regcache, AMD64_RCX_REGNUM))
return -1;
- if (record_arch_list_add_reg (regcache, AMD64_RDX_REGNUM))
+ if (record_full_arch_list_add_reg (regcache, AMD64_RDX_REGNUM))
return -1;
- if (record_arch_list_add_reg (regcache, AMD64_RBX_REGNUM))
+ if (record_full_arch_list_add_reg (regcache, AMD64_RBX_REGNUM))
return -1;
- if (record_arch_list_add_reg (regcache, AMD64_RSP_REGNUM))
+ if (record_full_arch_list_add_reg (regcache, AMD64_RSP_REGNUM))
return -1;
- if (record_arch_list_add_reg (regcache, AMD64_RBP_REGNUM))
+ if (record_full_arch_list_add_reg (regcache, AMD64_RBP_REGNUM))
return -1;
- if (record_arch_list_add_reg (regcache, AMD64_RSI_REGNUM))
+ if (record_full_arch_list_add_reg (regcache, AMD64_RSI_REGNUM))
return -1;
- if (record_arch_list_add_reg (regcache, AMD64_RDI_REGNUM))
+ if (record_full_arch_list_add_reg (regcache, AMD64_RDI_REGNUM))
return -1;
- if (record_arch_list_add_reg (regcache, AMD64_R8_REGNUM))
+ if (record_full_arch_list_add_reg (regcache, AMD64_R8_REGNUM))
return -1;
- if (record_arch_list_add_reg (regcache, AMD64_R9_REGNUM))
+ if (record_full_arch_list_add_reg (regcache, AMD64_R9_REGNUM))
return -1;
- if (record_arch_list_add_reg (regcache, AMD64_R10_REGNUM))
+ if (record_full_arch_list_add_reg (regcache, AMD64_R10_REGNUM))
return -1;
- if (record_arch_list_add_reg (regcache, AMD64_R11_REGNUM))
+ if (record_full_arch_list_add_reg (regcache, AMD64_R11_REGNUM))
return -1;
- if (record_arch_list_add_reg (regcache, AMD64_R12_REGNUM))
+ if (record_full_arch_list_add_reg (regcache, AMD64_R12_REGNUM))
return -1;
- if (record_arch_list_add_reg (regcache, AMD64_R13_REGNUM))
+ if (record_full_arch_list_add_reg (regcache, AMD64_R13_REGNUM))
return -1;
- if (record_arch_list_add_reg (regcache, AMD64_R14_REGNUM))
+ if (record_full_arch_list_add_reg (regcache, AMD64_R14_REGNUM))
return -1;
- if (record_arch_list_add_reg (regcache, AMD64_R15_REGNUM))
+ if (record_full_arch_list_add_reg (regcache, AMD64_R15_REGNUM))
return -1;
- if (record_arch_list_add_reg (regcache, AMD64_EFLAGS_REGNUM))
+ if (record_full_arch_list_add_reg (regcache, AMD64_EFLAGS_REGNUM))
return -1;
return 0;
/* 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 "syscall".
+ "record_full_arch_list". This instruction is "syscall".
Return -1 if something wrong. */
regcache_raw_read_unsigned (regcache,
amd64_linux_record_tdep.arg2,
&addr);
- if (record_arch_list_add_mem (addr,
- amd64_linux_record_tdep.size_ulong))
+ if (record_full_arch_list_add_mem
+ (addr, amd64_linux_record_tdep.size_ulong))
return -1;
}
goto record_regs;
record_regs:
/* Record the return value of the system call. */
- if (record_arch_list_add_reg (regcache, AMD64_RCX_REGNUM))
+ if (record_full_arch_list_add_reg (regcache, AMD64_RCX_REGNUM))
return -1;
- if (record_arch_list_add_reg (regcache, AMD64_R11_REGNUM))
+ if (record_full_arch_list_add_reg (regcache, AMD64_R11_REGNUM))
return -1;
return 0;
if (amd64_all_but_ip_registers_record (regcache))
return -1;
- if (record_arch_list_add_reg (regcache, AMD64_RIP_REGNUM))
+ if (record_full_arch_list_add_reg (regcache, AMD64_RIP_REGNUM))
return -1;
/* Record the change in the stack. */
/* This is for frame_size.
sp -= sizeof (struct rt_sigframe); */
rsp -= AMD64_LINUX_frame_size;
- if (record_arch_list_add_mem (rsp, AMD64_LINUX_redzone
+ if (record_full_arch_list_add_mem (rsp, AMD64_LINUX_redzone
+ AMD64_LINUX_xstate
+ AMD64_LINUX_frame_size))
return -1;
- if (record_arch_list_add_end ())
+ if (record_full_arch_list_add_end ())
return -1;
return 0;
bfd *abfd)
{
/* Linux/x86-64. */
- uint64_t xcr0 = i386_linux_core_read_xcr0 (gdbarch, target, abfd);
- switch ((xcr0 & I386_XSTATE_AVX_MASK))
+ uint64_t xcr0 = i386_linux_core_read_xcr0 (abfd);
+
+ switch (xcr0 & I386_XSTATE_ALL_MASK)
{
+ case I386_XSTATE_MPX_MASK:
+ if (gdbarch_ptr_bit (gdbarch) == 32)
+ return tdesc_x32_avx_linux; /* No x32 MPX falling back to AVX. */
+ else
+ return tdesc_amd64_mpx_linux;
case I386_XSTATE_AVX_MASK:
if (gdbarch_ptr_bit (gdbarch) == 32)
return tdesc_x32_avx_linux;
/* Initialize the Linux target description. */
initialize_tdesc_amd64_linux ();
initialize_tdesc_amd64_avx_linux ();
+ initialize_tdesc_amd64_mpx_linux ();
initialize_tdesc_x32_linux ();
initialize_tdesc_x32_avx_linux ();
}