gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / amd64-linux-tdep.c
index 850ca20cb938b77e88210a04cd9d38da31734ae2..ef19be275f3e16c4ec16fe52c1d47d5fdf10e081 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for GNU/Linux x86-64.
 
-   Copyright (C) 2001-2014 Free Software Foundation, Inc.
+   Copyright (C) 2001-2020 Free Software Foundation, Inc.
    Contributed by Jiri Smid, SuSE Labs.
 
    This file is part of GDB.
@@ -20,7 +20,9 @@
 
 #include "defs.h"
 #include "arch-utils.h"
+#include "displaced-stepping.h"
 #include "frame.h"
+#include "gdbarch.h"
 #include "gdbcore.h"
 #include "regcache.h"
 #include "osabi.h"
 #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"
-#include "x86-xstate.h"
+#include "gdbsupport/x86-xstate.h"
+#include "inferior.h"
 
 #include "amd64-tdep.h"
 #include "solib-svr4.h"
 #include "xml-syscall.h"
 #include "glibc-tdep.h"
-
-#include "features/i386/amd64-linux.c"
-#include "features/i386/amd64-avx-linux.c"
-#include "features/i386/amd64-mpx-linux.c"
-#include "features/i386/amd64-avx512-linux.c"
-
-#include "features/i386/x32-linux.c"
-#include "features/i386/x32-avx-linux.c"
-#include "features/i386/x32-avx512-linux.c"
+#include "arch/amd64.h"
+#include "target-descriptions.h"
+#include "observable.h"
 
 /* The syscall's XML filename for i386.  */
 #define XML_SYSCALL_FILENAME_AMD64 "syscalls/amd64-linux.xml"
 #include "record-full.h"
 #include "linux-record.h"
 
-/* Supported register note sections.  */
-static struct core_regset_section amd64_linux_regset_sections[] =
-{
-  { ".reg", 27 * 8, "general-purpose" },
-  { ".reg2", 512, "floating-point" },
-  { ".reg-xstate", X86_XSTATE_MAX_SIZE, "XSAVE extended state" },
-  { NULL, 0 }
-};
-
 /* Mapping between the general-purpose registers in `struct user'
    format and GDB's register cache layout.  */
 
@@ -109,6 +99,10 @@ int amd64_linux_gregset_reg_offset[] =
   -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,                          /* PKEYS register pkru  */
+
+  /* End of hardware registers */
+  21 * 8, 22 * 8,                    /* fs_base and gs_base.  */
   15 * 8                             /* "orig_rax" */
 };
 \f
@@ -232,9 +226,9 @@ amd64_linux_sigcontext_addr (struct frame_info *this_frame)
 
 static LONGEST
 amd64_linux_get_syscall_number (struct gdbarch *gdbarch,
-                                ptid_t ptid)
+                               thread_info *thread)
 {
-  struct regcache *regcache = get_thread_regcache (ptid);
+  struct regcache *regcache = get_thread_regcache (thread);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   /* The content of a register.  */
   gdb_byte buf[8];
@@ -244,7 +238,7 @@ amd64_linux_get_syscall_number (struct gdbarch *gdbarch,
   /* Getting the system call number from the register.
      When dealing with x86_64 architecture, this information
      is stored at %rax register.  */
-  regcache_cooked_read (regcache, AMD64_LINUX_ORIG_RAX_REGNUM, buf);
+  regcache->cooked_read (AMD64_LINUX_ORIG_RAX_REGNUM, buf);
 
   ret = extract_signed_integer (buf, 8, byte_order);
 
@@ -290,7 +284,9 @@ static int
 amd64_linux_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
                                 struct reggroup *group)
 { 
-  if (regnum == AMD64_LINUX_ORIG_RAX_REGNUM)
+  if (regnum == AMD64_LINUX_ORIG_RAX_REGNUM
+      || regnum == AMD64_FSBASE_REGNUM
+      || regnum == AMD64_GSBASE_REGNUM)
     return (group == system_reggroup
             || group == save_reggroup
             || group == restore_reggroup);
@@ -371,6 +367,9 @@ amd64_all_but_ip_registers_record (struct regcache *regcache)
 static enum gdb_syscall
 amd64_canonicalize_syscall (enum amd64_syscall syscall_number)
 {
+  DIAGNOSTIC_PUSH
+  DIAGNOSTIC_IGNORE_SWITCH_DIFFERENT_ENUM_TYPES
+
   switch (syscall_number) {
   case amd64_sys_read:
   case amd64_x32_sys_read:
@@ -1002,7 +1001,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:
@@ -1436,8 +1435,10 @@ amd64_canonicalize_syscall (enum amd64_syscall syscall_number)
     return gdb_sys_move_pages;
 
   default:
-    return -1;
+    return gdb_sys_no_syscall;
   }
+
+  DIAGNOSTIC_POP
 }
 
 /* Parse the arguments of current system call instruction and record
@@ -1458,7 +1459,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);
 
@@ -1493,9 +1494,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"), 
@@ -1573,6 +1575,35 @@ amd64_linux_record_signal (struct gdbarch *gdbarch,
   return 0;
 }
 
+const target_desc *
+amd64_linux_read_description (uint64_t xcr0_features_bit, bool is_x32)
+{
+  static target_desc *amd64_linux_tdescs \
+    [2/*AVX*/][2/*MPX*/][2/*AVX512*/][2/*PKRU*/] = {};
+  static target_desc *x32_linux_tdescs[2/*AVX*/][2/*AVX512*/] = {};
+
+  target_desc **tdesc;
+
+  if (is_x32)
+    {
+      tdesc = &x32_linux_tdescs[(xcr0_features_bit & X86_XSTATE_AVX) ? 1 : 0 ]
+       [(xcr0_features_bit & X86_XSTATE_AVX512) ? 1 : 0];
+    }
+  else
+    {
+      tdesc = &amd64_linux_tdescs[(xcr0_features_bit & X86_XSTATE_AVX) ? 1 : 0]
+       [(xcr0_features_bit & X86_XSTATE_MPX) ? 1 : 0]
+       [(xcr0_features_bit & X86_XSTATE_AVX512) ? 1 : 0]
+       [(xcr0_features_bit & X86_XSTATE_PKRU) ? 1 : 0];
+    }
+
+  if (*tdesc == NULL)
+    *tdesc = amd64_create_target_description (xcr0_features_bit, is_x32,
+                                             true, true);
+
+  return *tdesc;
+}
+
 /* Get Linux/x86 target description from core dump.  */
 
 static const struct target_desc *
@@ -1583,30 +1614,259 @@ amd64_linux_core_read_description (struct gdbarch *gdbarch,
   /* Linux/x86-64.  */
   uint64_t xcr0 = i386_linux_core_read_xcr0 (abfd);
 
-  switch (xcr0 & X86_XSTATE_ALL_MASK)
+  return amd64_linux_read_description (xcr0 & X86_XSTATE_ALL_MASK,
+                                      gdbarch_ptr_bit (gdbarch) == 32);
+}
+
+/* Similar to amd64_supply_fpregset, but use XSAVE extended state.  */
+
+static void
+amd64_linux_supply_xstateregset (const struct regset *regset,
+                                struct regcache *regcache, int regnum,
+                                const void *xstateregs, size_t len)
+{
+  amd64_supply_xsave (regcache, regnum, xstateregs);
+}
+
+/* Similar to amd64_collect_fpregset, but use XSAVE extended state.  */
+
+static void
+amd64_linux_collect_xstateregset (const struct regset *regset,
+                                 const struct regcache *regcache,
+                                 int regnum, void *xstateregs, size_t len)
+{
+  amd64_collect_xsave (regcache, regnum, xstateregs, 1);
+}
+
+static const struct regset amd64_linux_xstateregset =
+  {
+    NULL,
+    amd64_linux_supply_xstateregset,
+    amd64_linux_collect_xstateregset
+  };
+
+/* Iterate over core file register note sections.  */
+
+static void
+amd64_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
+                                         iterate_over_regset_sections_cb *cb,
+                                         void *cb_data,
+                                         const struct regcache *regcache)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  cb (".reg", 27 * 8, 27 * 8, &i386_gregset, NULL, cb_data);
+  cb (".reg2", 512, 512, &amd64_fpregset, NULL, cb_data);
+  cb (".reg-xstate", X86_XSTATE_SIZE (tdep->xcr0), 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 expr_builder *builder,
+                                  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 (builder, OP_REGISTER);
+      str.ptr = regname;
+      str.length = strlen (regname);
+      write_exp_string (builder, str);
+      write_exp_elt_opcode (builder, 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 (builder, OP_LONG);
+      write_exp_elt_type (builder, builtin_type (gdbarch)->builtin_long);
+      write_exp_elt_longcst (builder, narg - 6);
+      write_exp_elt_opcode (builder, OP_LONG);
+
+      /* Register: SP.  */
+      write_exp_elt_opcode (builder, OP_REGISTER);
+      str.ptr = regname;
+      str.length = strlen (regname);
+      write_exp_string (builder, str);
+      write_exp_elt_opcode (builder, OP_REGISTER);
+
+      write_exp_elt_opcode (builder, BINOP_ADD);
+
+      /* Cast to long. */
+      write_exp_elt_opcode (builder, UNOP_CAST);
+      write_exp_elt_type (builder,
+                         lookup_pointer_type (builtin_type (gdbarch)->builtin_long));
+      write_exp_elt_opcode (builder, UNOP_CAST);
+
+      write_exp_elt_opcode (builder, UNOP_IND);
+    }
+}
+
+struct amd64_linux_per_inferior
+{
+  amd64_linux_per_inferior (gdb::array_view<CORE_ADDR> disp_step_buffer_addrs)
+    : disp_step_buf_mgr (disp_step_buffer_addrs)
+  {}
+
+  multiple_displaced_buffer_manager disp_step_buf_mgr;
+};
+
+static const inferior_key<amd64_linux_per_inferior>
+  amd64_linux_per_inferior_data;
+
+/* Get the per-inferior AMD64/Linux data for INF.  */
+
+static amd64_linux_per_inferior *
+get_amd64_linux_per_inferior (inferior *inf, gdbarch *arch)
+{
+  amd64_linux_per_inferior *per_inf = amd64_linux_per_inferior_data.get (inf);
+
+  if (per_inf == nullptr)
     {
-    case X86_XSTATE_MPX_AVX512_MASK:
-    case X86_XSTATE_AVX512_MASK:
-      if (gdbarch_ptr_bit (gdbarch) == 32)
-       return tdesc_x32_avx512_linux;
-      else
-       return tdesc_amd64_avx512_linux;
-    case X86_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 X86_XSTATE_AVX_MASK:
-      if (gdbarch_ptr_bit (gdbarch) == 32)
-       return tdesc_x32_avx_linux;
-      else
-       return tdesc_amd64_avx_linux;
-    default:
-      if (gdbarch_ptr_bit (gdbarch) == 32)
-       return tdesc_x32_linux;
-      else
-       return tdesc_amd64_linux;
+      std::vector<CORE_ADDR> buffers;
+#if 0
+      /* Alternative implementation that maps some pages in the inferior,
+         allowing to have many buffers.  */
+      CORE_ADDR displaced_step_mmap = gdbarch_infcall_mmap (arch, 16384, GDB_MMAP_PROT_READ | GDB_MMAP_PROT_EXEC);
+      gdb_assert (displaced_step_mmap != 0);
+
+      for (int i = 0; i < 1024; i++)
+       buffers.push_back (displaced_step_mmap + 16 * i);
+
+#else
+      /* Figure out where the displaced step buffers are.  */
+      CORE_ADDR addr = linux_displaced_step_location (arch);
+      buffers.push_back (addr);
+      buffers.push_back (addr + gdbarch_max_insn_length (arch));
+#endif
+      per_inf = amd64_linux_per_inferior_data.emplace (inf, buffers);
     }
+
+  CORE_ADDR addr = per_inf->disp_step_buf_mgr.first_buf_addr ();
+  CORE_ADDR cur_addr = linux_displaced_step_location (arch);
+  gdb_assert (addr == cur_addr);
+
+  return per_inf;
+}
+
+/* Implementation of the gdbarch_displaced_step_prepare method. */
+
+static displaced_step_prepare_status
+amd64_linux_displaced_step_prepare (gdbarch *arch, thread_info *thread)
+{
+  amd64_linux_per_inferior *per_inferior
+    = get_amd64_linux_per_inferior (thread->inf, arch);
+
+
+  return per_inferior->disp_step_buf_mgr.prepare (thread);
+}
+
+/* Implementation of the gdbarch_displaced_step_finish method. */
+
+static displaced_step_finish_status
+amd64_linux_displaced_step_finish (gdbarch *arch, thread_info *thread,
+                                  gdb_signal sig)
+{
+  amd64_linux_per_inferior *per_inferior
+    = get_amd64_linux_per_inferior (thread->inf, arch);
+
+  return per_inferior->disp_step_buf_mgr.finish (arch, thread, sig);
 }
 
 static void
@@ -1629,7 +1889,7 @@ amd64_linux_init_abi_common(struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->register_reggroup_p = amd64_linux_register_reggroup_p;
 
   /* Functions for 'catch syscall'.  */
-  set_xml_syscall_file_name (XML_SYSCALL_FILENAME_AMD64);
+  set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_AMD64);
   set_gdbarch_get_syscall_number (gdbarch,
                                   amd64_linux_get_syscall_number);
 
@@ -1643,8 +1903,9 @@ amd64_linux_init_abi_common(struct gdbarch_info info, struct gdbarch *gdbarch)
   /* GNU/Linux uses the dynamic linker included in the GNU C Library.  */
   set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
 
-  /* Install supported register note sections.  */
-  set_gdbarch_core_regset_sections (gdbarch, amd64_linux_regset_sections);
+  /* Iterate over core file register note sections.  */
+  set_gdbarch_iterate_over_regset_sections
+    (gdbarch, amd64_linux_iterate_over_regset_sections);
 
   set_gdbarch_core_read_description (gdbarch,
                                     amd64_linux_core_read_description);
@@ -1653,23 +1914,22 @@ amd64_linux_init_abi_common(struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_displaced_step_copy_insn (gdbarch,
                                         amd64_displaced_step_copy_insn);
   set_gdbarch_displaced_step_fixup (gdbarch, amd64_displaced_step_fixup);
-  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);
+  set_gdbarch_displaced_step_prepare (gdbarch, amd64_linux_displaced_step_prepare);
+  set_gdbarch_displaced_step_finish (gdbarch, amd64_linux_displaced_step_finish);
 
   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
 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 = info.tdesc_data;
   const struct tdesc_feature *feature;
   int valid_p;
 
@@ -1679,15 +1939,14 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->gregset_num_regs = ARRAY_SIZE (amd64_linux_gregset_reg_offset);
   tdep->sizeof_gregset = 27 * 8;
 
-  amd64_init_abi (info, gdbarch);
+  amd64_init_abi (info, gdbarch,
+                 amd64_linux_read_description (X86_XSTATE_SSE_MASK, false));
+
+  const target_desc *tdesc = tdep->tdesc;
 
   /* Reserve a number for orig_rax.  */
   set_gdbarch_num_regs (gdbarch, AMD64_LINUX_NUM_REGS);
 
-  if (! tdesc_has_registers (tdesc))
-    tdesc = tdesc_amd64_linux;
-  tdep->tdesc = tdesc;
-
   feature = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.linux");
   if (feature == NULL)
     return;
@@ -1713,10 +1972,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;
@@ -1728,8 +1987,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;
@@ -1756,8 +2015,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;
@@ -1773,8 +2032,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;
@@ -1783,6 +2041,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.  */
@@ -1872,14 +2131,19 @@ 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 = info.tdesc_data;
   const struct tdesc_feature *feature;
   int valid_p;
 
@@ -1889,14 +2153,14 @@ amd64_x32_linux_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->gregset_num_regs = ARRAY_SIZE (amd64_linux_gregset_reg_offset);
   tdep->sizeof_gregset = 27 * 8;
 
-  amd64_x32_init_abi (info, gdbarch);
+  amd64_x32_init_abi (info, gdbarch,
+                     amd64_linux_read_description (X86_XSTATE_SSE_MASK,
+                                                   true));
 
   /* Reserve a number for orig_rax.  */
   set_gdbarch_num_regs (gdbarch, AMD64_LINUX_NUM_REGS);
 
-  if (! tdesc_has_registers (tdesc))
-    tdesc = tdesc_x32_linux;
-  tdep->tdesc = tdesc;
+  const target_desc *tdesc = tdep->tdesc;
 
   feature = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.linux");
   if (feature == NULL)
@@ -1923,10 +2187,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;
@@ -1938,8 +2202,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;
@@ -1949,7 +2213,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;
@@ -1966,11 +2230,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;
@@ -1983,16 +2247,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.  */
@@ -2082,26 +2346,28 @@ amd64_x32_linux_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
   set_solib_svr4_fetch_link_map_offsets
     (gdbarch, svr4_ilp32_fetch_link_map_offsets);
 }
-\f
 
-/* Provide a prototype to silence -Wmissing-prototypes.  */
-extern void _initialize_amd64_linux_tdep (void);
+static void
+amd64_linux_inferior_appeared (inferior *inf)
+{
+  amd64_linux_per_inferior_data.clear (inf);
+}
+
+static void
+amd64_linux_inferior_execd (inferior *inf)
+{
+  amd64_linux_per_inferior_data.clear (inf);
+}
 
+void _initialize_amd64_linux_tdep ();
 void
-_initialize_amd64_linux_tdep (void)
+_initialize_amd64_linux_tdep ()
 {
   gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
                          GDB_OSABI_LINUX, amd64_linux_init_abi);
   gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x64_32,
                          GDB_OSABI_LINUX, amd64_x32_linux_init_abi);
 
-  /* Initialize the Linux target description.  */
-  initialize_tdesc_amd64_linux ();
-  initialize_tdesc_amd64_avx_linux ();
-  initialize_tdesc_amd64_mpx_linux ();
-  initialize_tdesc_amd64_avx512_linux ();
-
-  initialize_tdesc_x32_linux ();
-  initialize_tdesc_x32_avx_linux ();
-  initialize_tdesc_x32_avx512_linux ();
+  gdb::observers::inferior_appeared.attach (amd64_linux_inferior_appeared);
+  gdb::observers::inferior_execd.attach (amd64_linux_inferior_execd);
 }
This page took 0.032992 seconds and 4 git commands to generate.