X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Famd64-linux-tdep.c;h=3f2a92bdf575d7b4ee51be9eb2d0ad3ae2111379;hb=ad43e107eb233dcef8e76da6328aa4e4d74afd84;hp=27a356002fe7d2075bd3dcb43ffdf2685c67cd1a;hpb=458c8db89f7e9913da6fa67c3df73404375c436b;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c index 27a356002f..3f2a92bdf5 100644 --- a/gdb/amd64-linux-tdep.c +++ b/gdb/amd64-linux-tdep.c @@ -1,6 +1,6 @@ /* Target-dependent code for GNU/Linux x86-64. - Copyright (C) 2001-2014 Free Software Foundation, Inc. + Copyright (C) 2001-2016 Free Software Foundation, Inc. Contributed by Jiri Smid, SuSE Labs. This file is part of GDB. @@ -28,6 +28,8 @@ #include "gdbtypes.h" #include "reggroups.h" #include "regset.h" +#include "parser-defs.h" +#include "user-regs.h" #include "amd64-linux-tdep.h" #include "i386-linux-tdep.h" #include "linux-tdep.h" @@ -41,6 +43,7 @@ #include "features/i386/amd64-linux.c" #include "features/i386/amd64-avx-linux.c" #include "features/i386/amd64-mpx-linux.c" +#include "features/i386/amd64-avx-mpx-linux.c" #include "features/i386/amd64-avx512-linux.c" #include "features/i386/x32-linux.c" @@ -993,7 +996,7 @@ amd64_canonicalize_syscall (enum amd64_syscall syscall_number) case amd64_sys_arch_prctl: case amd64_x32_sys_arch_prctl: - return -1; /* Note */ + return gdb_sys_no_syscall; /* Note */ case amd64_sys_adjtimex: case amd64_x32_sys_adjtimex: @@ -1427,7 +1430,7 @@ amd64_canonicalize_syscall (enum amd64_syscall syscall_number) return gdb_sys_move_pages; default: - return -1; + return gdb_sys_no_syscall; } } @@ -1449,7 +1452,7 @@ amd64_linux_syscall_record_common (struct regcache *regcache, { int ret; ULONGEST syscall_native; - enum gdb_syscall syscall_gdb = -1; + enum gdb_syscall syscall_gdb = gdb_sys_no_syscall; regcache_raw_read_unsigned (regcache, AMD64_RAX_REGNUM, &syscall_native); @@ -1484,9 +1487,10 @@ amd64_linux_syscall_record_common (struct regcache *regcache, break; } - syscall_gdb = amd64_canonicalize_syscall (syscall_native); + syscall_gdb + = amd64_canonicalize_syscall ((enum amd64_syscall) syscall_native); - if (syscall_gdb < 0) + if (syscall_gdb == gdb_sys_no_syscall) { printf_unfiltered (_("Process record and replay target doesn't " "support syscall number %s\n"), @@ -1587,6 +1591,11 @@ amd64_linux_core_read_description (struct gdbarch *gdbarch, return tdesc_x32_avx_linux; /* No x32 MPX falling back to AVX. */ else return tdesc_amd64_mpx_linux; + case X86_XSTATE_AVX_MPX_MASK: + if (gdbarch_ptr_bit (gdbarch) == 32) + return tdesc_x32_avx_linux; /* No x32 MPX falling back to AVX. */ + else + return tdesc_amd64_avx_mpx_linux; case X86_XSTATE_AVX_MASK: if (gdbarch_ptr_bit (gdbarch) == 32) return tdesc_x32_avx_linux; @@ -1639,10 +1648,147 @@ amd64_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, cb (".reg", 27 * 8, &i386_gregset, NULL, cb_data); cb (".reg2", 512, &amd64_fpregset, NULL, cb_data); - cb (".reg-xstate", regcache ? X86_XSTATE_MAX_SIZE : 0, + cb (".reg-xstate", X86_XSTATE_SIZE (tdep->xcr0), &amd64_linux_xstateregset, "XSAVE extended state", cb_data); } +/* The instruction sequences used in x86_64 machines for a + disabled is-enabled probe. */ + +const gdb_byte amd64_dtrace_disabled_probe_sequence_1[] = { + /* xor %rax, %rax */ 0x48, 0x33, 0xc0, + /* nop */ 0x90, + /* nop */ 0x90 +}; + +const gdb_byte amd64_dtrace_disabled_probe_sequence_2[] = { + /* xor %rax, %rax */ 0x48, 0x33, 0xc0, + /* ret */ 0xc3, + /* nop */ 0x90 +}; + +/* The instruction sequence used in x86_64 machines for enabling a + DTrace is-enabled probe. */ + +const gdb_byte amd64_dtrace_enable_probe_sequence[] = { + /* mov $0x1, %eax */ 0xb8, 0x01, 0x00, 0x00, 0x00 +}; + +/* The instruction sequence used in x86_64 machines for disabling a + DTrace is-enabled probe. */ + +const gdb_byte amd64_dtrace_disable_probe_sequence[] = { + /* xor %rax, %rax; nop; nop */ 0x48, 0x33, 0xC0, 0x90, 0x90 +}; + +/* Implementation of `gdbarch_dtrace_probe_is_enabled', as defined in + gdbarch.h. */ + +static int +amd64_dtrace_probe_is_enabled (struct gdbarch *gdbarch, CORE_ADDR addr) +{ + gdb_byte buf[5]; + + /* This function returns 1 if the instructions at ADDR do _not_ + follow any of the amd64_dtrace_disabled_probe_sequence_* + patterns. + + Note that ADDR is offset 3 bytes from the beginning of these + sequences. */ + + read_code (addr - 3, buf, 5); + return (memcmp (buf, amd64_dtrace_disabled_probe_sequence_1, 5) != 0 + && memcmp (buf, amd64_dtrace_disabled_probe_sequence_2, 5) != 0); +} + +/* Implementation of `gdbarch_dtrace_enable_probe', as defined in + gdbarch.h. */ + +static void +amd64_dtrace_enable_probe (struct gdbarch *gdbarch, CORE_ADDR addr) +{ + /* Note also that ADDR is offset 3 bytes from the beginning of + amd64_dtrace_enable_probe_sequence. */ + + write_memory (addr - 3, amd64_dtrace_enable_probe_sequence, 5); +} + +/* Implementation of `gdbarch_dtrace_disable_probe', as defined in + gdbarch.h. */ + +static void +amd64_dtrace_disable_probe (struct gdbarch *gdbarch, CORE_ADDR addr) +{ + /* Note also that ADDR is offset 3 bytes from the beginning of + amd64_dtrace_disable_probe_sequence. */ + + write_memory (addr - 3, amd64_dtrace_disable_probe_sequence, 5); +} + +/* Implementation of `gdbarch_dtrace_parse_probe_argument', as defined + in gdbarch.h. */ + +static void +amd64_dtrace_parse_probe_argument (struct gdbarch *gdbarch, + struct parser_state *pstate, + int narg) +{ + struct stoken str; + + /* DTrace probe arguments can be found on the ABI-defined places for + regular arguments at the current PC. The probe abstraction + currently supports up to 12 arguments for probes. */ + + if (narg < 6) + { + static const int arg_reg_map[6] = + { + AMD64_RDI_REGNUM, /* Arg 1. */ + AMD64_RSI_REGNUM, /* Arg 2. */ + AMD64_RDX_REGNUM, /* Arg 3. */ + AMD64_RCX_REGNUM, /* Arg 4. */ + AMD64_R8_REGNUM, /* Arg 5. */ + AMD64_R9_REGNUM /* Arg 6. */ + }; + int regno = arg_reg_map[narg]; + const char *regname = user_reg_map_regnum_to_name (gdbarch, regno); + + write_exp_elt_opcode (pstate, OP_REGISTER); + str.ptr = regname; + str.length = strlen (regname); + write_exp_string (pstate, str); + write_exp_elt_opcode (pstate, OP_REGISTER); + } + else + { + /* Additional arguments are passed on the stack. */ + const char *regname = user_reg_map_regnum_to_name (gdbarch, AMD64_RSP_REGNUM); + + /* Displacement. */ + write_exp_elt_opcode (pstate, OP_LONG); + write_exp_elt_type (pstate, builtin_type (gdbarch)->builtin_long); + write_exp_elt_longcst (pstate, narg - 6); + write_exp_elt_opcode (pstate, OP_LONG); + + /* Register: SP. */ + write_exp_elt_opcode (pstate, OP_REGISTER); + str.ptr = regname; + str.length = strlen (regname); + write_exp_string (pstate, str); + write_exp_elt_opcode (pstate, OP_REGISTER); + + write_exp_elt_opcode (pstate, BINOP_ADD); + + /* Cast to long. */ + write_exp_elt_opcode (pstate, UNOP_CAST); + write_exp_elt_type (pstate, + lookup_pointer_type (builtin_type (gdbarch)->builtin_long)); + write_exp_elt_opcode (pstate, UNOP_CAST); + + write_exp_elt_opcode (pstate, UNOP_IND); + } +} + static void amd64_linux_init_abi_common(struct gdbarch_info info, struct gdbarch *gdbarch) { @@ -1691,12 +1837,14 @@ amd64_linux_init_abi_common(struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_displaced_step_free_closure (gdbarch, simple_displaced_step_free_closure); set_gdbarch_displaced_step_location (gdbarch, - displaced_step_at_entry_point); - - set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type); + linux_displaced_step_location); set_gdbarch_process_record (gdbarch, i386_process_record); set_gdbarch_process_record_signal (gdbarch, amd64_linux_record_signal); + + set_gdbarch_get_siginfo_type (gdbarch, x86_linux_get_siginfo_type); + set_gdbarch_handle_segmentation_fault (gdbarch, + i386_linux_handle_segmentation_fault); } static void @@ -1704,7 +1852,8 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); const struct target_desc *tdesc = info.target_desc; - struct tdesc_arch_data *tdesc_data = (void *) info.tdep_info; + struct tdesc_arch_data *tdesc_data + = (struct tdesc_arch_data *) info.tdep_info; const struct tdesc_feature *feature; int valid_p; @@ -1748,10 +1897,10 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) amd64_linux_record_tdep.size_ustat = 32; /* ADM64 doesn't need this size because it doesn't have sys_sigaction but sys_rt_sigaction. */ - amd64_linux_record_tdep.size_old_sigaction = 152; + amd64_linux_record_tdep.size_old_sigaction = 32; /* ADM64 doesn't need this size because it doesn't have sys_sigpending but sys_rt_sigpending. */ - amd64_linux_record_tdep.size_old_sigset_t = 128; + amd64_linux_record_tdep.size_old_sigset_t = 8; amd64_linux_record_tdep.size_rlimit = 16; amd64_linux_record_tdep.size_rusage = 144; amd64_linux_record_tdep.size_timeval = 16; @@ -1763,8 +1912,8 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) but sys_getresuid. */ amd64_linux_record_tdep.size_old_uid_t = 2; amd64_linux_record_tdep.size_fd_set = 128; - amd64_linux_record_tdep.size_dirent = 280; - amd64_linux_record_tdep.size_dirent64 = 280; + /* ADM64 doesn't need this size because it doesn't have sys_readdir. */ + amd64_linux_record_tdep.size_old_dirent = 280; amd64_linux_record_tdep.size_statfs = 120; amd64_linux_record_tdep.size_statfs64 = 120; amd64_linux_record_tdep.size_sockaddr = 16; @@ -1791,8 +1940,8 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) amd64_linux_record_tdep.size_NFS_FHSIZE = 32; amd64_linux_record_tdep.size_knfsd_fh = 132; amd64_linux_record_tdep.size_TASK_COMM_LEN = 16; - amd64_linux_record_tdep.size_sigaction = 152; - amd64_linux_record_tdep.size_sigset_t = 128; + amd64_linux_record_tdep.size_sigaction = 32; + amd64_linux_record_tdep.size_sigset_t = 8; amd64_linux_record_tdep.size_siginfo_t = 128; amd64_linux_record_tdep.size_cap_user_data_t = 8; amd64_linux_record_tdep.size_stack_t = 24; @@ -1808,8 +1957,7 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) amd64_linux_record_tdep.size_epoll_event = 12; amd64_linux_record_tdep.size_itimerspec = 32; amd64_linux_record_tdep.size_mq_attr = 64; - amd64_linux_record_tdep.size_siginfo = 128; - amd64_linux_record_tdep.size_termios = 60; + amd64_linux_record_tdep.size_termios = 36; amd64_linux_record_tdep.size_termios2 = 44; amd64_linux_record_tdep.size_pid_t = 4; amd64_linux_record_tdep.size_winsize = 8; @@ -1818,6 +1966,7 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) amd64_linux_record_tdep.size_hayes_esp_config = 12; amd64_linux_record_tdep.size_size_t = 8; amd64_linux_record_tdep.size_iovec = 16; + amd64_linux_record_tdep.size_time_t = 8; /* These values are the second argument of system call "sys_fcntl" and "sys_fcntl64". They are obtained from Linux Kernel source. */ @@ -1907,14 +2056,21 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* GNU/Linux uses SVR4-style shared libraries. */ set_solib_svr4_fetch_link_map_offsets (gdbarch, svr4_lp64_fetch_link_map_offsets); + + /* Register DTrace handlers. */ + set_gdbarch_dtrace_parse_probe_argument (gdbarch, amd64_dtrace_parse_probe_argument); + set_gdbarch_dtrace_probe_is_enabled (gdbarch, amd64_dtrace_probe_is_enabled); + set_gdbarch_dtrace_enable_probe (gdbarch, amd64_dtrace_enable_probe); + set_gdbarch_dtrace_disable_probe (gdbarch, amd64_dtrace_disable_probe); } static void -amd64_x32_linux_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch) +amd64_x32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); const struct target_desc *tdesc = info.target_desc; - struct tdesc_arch_data *tdesc_data = (void *) info.tdep_info; + struct tdesc_arch_data *tdesc_data + = (struct tdesc_arch_data *) info.tdep_info; const struct tdesc_feature *feature; int valid_p; @@ -1958,10 +2114,10 @@ amd64_x32_linux_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch) amd64_x32_linux_record_tdep.size_ustat = 32; /* ADM64 doesn't need this size because it doesn't have sys_sigaction but sys_rt_sigaction. */ - amd64_x32_linux_record_tdep.size_old_sigaction = 152; + amd64_x32_linux_record_tdep.size_old_sigaction = 16; /* ADM64 doesn't need this size because it doesn't have sys_sigpending but sys_rt_sigpending. */ - amd64_x32_linux_record_tdep.size_old_sigset_t = 128; + amd64_x32_linux_record_tdep.size_old_sigset_t = 4; amd64_x32_linux_record_tdep.size_rlimit = 16; amd64_x32_linux_record_tdep.size_rusage = 144; amd64_x32_linux_record_tdep.size_timeval = 16; @@ -1973,8 +2129,8 @@ amd64_x32_linux_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch) but sys_getresuid. */ amd64_x32_linux_record_tdep.size_old_uid_t = 2; amd64_x32_linux_record_tdep.size_fd_set = 128; - amd64_x32_linux_record_tdep.size_dirent = 280; - amd64_x32_linux_record_tdep.size_dirent64 = 280; + /* ADM64 doesn't need this size because it doesn't have sys_readdir. */ + amd64_x32_linux_record_tdep.size_old_dirent = 268; amd64_x32_linux_record_tdep.size_statfs = 120; amd64_x32_linux_record_tdep.size_statfs64 = 120; amd64_x32_linux_record_tdep.size_sockaddr = 16; @@ -1984,7 +2140,7 @@ amd64_x32_linux_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch) = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT; amd64_x32_linux_record_tdep.size_ulong = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT; - amd64_x32_linux_record_tdep.size_msghdr = 56; + amd64_x32_linux_record_tdep.size_msghdr = 28; amd64_x32_linux_record_tdep.size_itimerval = 32; amd64_x32_linux_record_tdep.size_stat = 144; amd64_x32_linux_record_tdep.size_old_utsname = 325; @@ -2001,11 +2157,11 @@ amd64_x32_linux_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch) amd64_x32_linux_record_tdep.size_NFS_FHSIZE = 32; amd64_x32_linux_record_tdep.size_knfsd_fh = 132; amd64_x32_linux_record_tdep.size_TASK_COMM_LEN = 16; - amd64_x32_linux_record_tdep.size_sigaction = 152; - amd64_x32_linux_record_tdep.size_sigset_t = 128; + amd64_x32_linux_record_tdep.size_sigaction = 20; + amd64_x32_linux_record_tdep.size_sigset_t = 8; amd64_x32_linux_record_tdep.size_siginfo_t = 128; amd64_x32_linux_record_tdep.size_cap_user_data_t = 8; - amd64_x32_linux_record_tdep.size_stack_t = 24; + amd64_x32_linux_record_tdep.size_stack_t = 12; amd64_x32_linux_record_tdep.size_off_t = 8; amd64_x32_linux_record_tdep.size_stat64 = 144; amd64_x32_linux_record_tdep.size_gid_t = 4; @@ -2018,16 +2174,16 @@ amd64_x32_linux_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch) amd64_x32_linux_record_tdep.size_epoll_event = 12; amd64_x32_linux_record_tdep.size_itimerspec = 32; amd64_x32_linux_record_tdep.size_mq_attr = 64; - amd64_x32_linux_record_tdep.size_siginfo = 128; - amd64_x32_linux_record_tdep.size_termios = 60; + amd64_x32_linux_record_tdep.size_termios = 36; amd64_x32_linux_record_tdep.size_termios2 = 44; amd64_x32_linux_record_tdep.size_pid_t = 4; amd64_x32_linux_record_tdep.size_winsize = 8; amd64_x32_linux_record_tdep.size_serial_struct = 72; amd64_x32_linux_record_tdep.size_serial_icounter_struct = 80; amd64_x32_linux_record_tdep.size_hayes_esp_config = 12; - amd64_x32_linux_record_tdep.size_size_t = 8; - amd64_x32_linux_record_tdep.size_iovec = 16; + amd64_x32_linux_record_tdep.size_size_t = 4; + amd64_x32_linux_record_tdep.size_iovec = 8; + amd64_x32_linux_record_tdep.size_time_t = 8; /* These values are the second argument of system call "sys_fcntl" and "sys_fcntl64". They are obtained from Linux Kernel source. */ @@ -2134,6 +2290,7 @@ _initialize_amd64_linux_tdep (void) initialize_tdesc_amd64_linux (); initialize_tdesc_amd64_avx_linux (); initialize_tdesc_amd64_mpx_linux (); + initialize_tdesc_amd64_avx_mpx_linux (); initialize_tdesc_amd64_avx512_linux (); initialize_tdesc_x32_linux ();