* mmix.h (R_MMIX_PUSHJ_STUBBABLE): New reloc number.
[deliverable/binutils-gdb.git] / gdb / x86-64-tdep.c
index a93af05dc8ade471cb149763e0172673c377be5a..351b11512c36d3e61f52721929680c0392b001ab 100644 (file)
@@ -32,6 +32,7 @@
 #include "gdbcore.h"
 #include "objfiles.h"
 #include "regcache.h"
+#include "regset.h"
 #include "symfile.h"
 
 #include "gdb_assert.h"
@@ -144,7 +145,7 @@ x86_64_register_type (struct gdbarch *gdbarch, int regnum)
 static int x86_64_dwarf_regmap[] =
 {
   /* General Purpose Registers RAX, RDX, RCX, RBX, RSI, RDI.  */
-  X86_64_RAX_REGNUM, X86_64_RDX_REGNUM, 3, 2, 
+  X86_64_RAX_REGNUM, X86_64_RDX_REGNUM, 2, 1,
   4, X86_64_RDI_REGNUM,
 
   /* Frame Pointer Register RBP.  */
@@ -172,7 +173,7 @@ static int x86_64_dwarf_regmap[] =
   X86_64_XMM0_REGNUM + 14, X86_64_XMM0_REGNUM + 15,
 
   /* Floating Point Registers 0-7.  */
-  X86_64_ST0_REGNUM + 0, X86_64_ST0_REGNUM + 1,        
+  X86_64_ST0_REGNUM + 0, X86_64_ST0_REGNUM + 1,
   X86_64_ST0_REGNUM + 2, X86_64_ST0_REGNUM + 3,
   X86_64_ST0_REGNUM + 4, X86_64_ST0_REGNUM + 5,
   X86_64_ST0_REGNUM + 6, X86_64_ST0_REGNUM + 7
@@ -613,6 +614,7 @@ x86_64_push_arguments (struct regcache *regcache, int nargs,
   int stack_values_count = 0;
   int *stack_values;
   stack_values = alloca (nargs * sizeof (int));
+
   for (i = 0; i < nargs; i++)
     {
       enum x86_64_reg_class class[MAX_CLASSES];
@@ -756,7 +758,7 @@ x86_64_store_return_value (struct type *type, struct regcache *regcache,
   int len = TYPE_LENGTH (type);
 
   /* First handle long doubles.  */
-  if (TYPE_CODE_FLT == TYPE_CODE (type)  && len == 16)
+  if (TYPE_CODE_FLT == TYPE_CODE (type) && len == 16)
     {
       ULONGEST fstat;
       char buf[FPU_REG_RAW_SIZE];
@@ -794,8 +796,8 @@ x86_64_store_return_value (struct type *type, struct regcache *regcache,
   /* XXX: What about complex floating point types?  */
   else
     {
-      int low_size = REGISTER_RAW_SIZE (0);
-      int high_size = REGISTER_RAW_SIZE (1);
+      int low_size = register_size (current_gdbarch, X86_64_RAX_REGNUM);
+      int high_size = register_size (current_gdbarch, X86_64_RDX_REGNUM);
 
       if (len <= low_size)
         regcache_cooked_write_part (regcache, 0, 0, len, valbuf);
@@ -1077,7 +1079,7 @@ static const struct frame_unwind x86_64_frame_unwind =
 };
 
 static const struct frame_unwind *
-x86_64_frame_p (CORE_ADDR pc)
+x86_64_frame_sniffer (struct frame_info *next_frame)
 {
   return &x86_64_frame_unwind;
 }
@@ -1149,8 +1151,9 @@ static const struct frame_unwind x86_64_sigtramp_frame_unwind =
 };
 
 static const struct frame_unwind *
-x86_64_sigtramp_frame_p (CORE_ADDR pc)
+x86_64_sigtramp_frame_sniffer (struct frame_info *next_frame)
 {
+  CORE_ADDR pc = frame_pc_unwind (next_frame);
   char *name;
 
   find_pc_partial_function (pc, &name, NULL, NULL);
@@ -1194,12 +1197,65 @@ x86_64_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
   return frame_id_build (fp + 16, frame_pc_unwind (next_frame));
 }
 
+/* 16 byte align the SP per frame requirements.  */
+
+static CORE_ADDR
+x86_64_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
+{
+  return sp & -(CORE_ADDR)16;
+}
+\f
+
+/* Supply register REGNUM from the floating-point register set REGSET
+   to register cache REGCACHE.  If REGNUM is -1, do this for all
+   registers in REGSET.  */
+
+static void
+x86_64_supply_fpregset (const struct regset *regset, struct regcache *regcache,
+                       int regnum, const void *fpregs, size_t len)
+{
+  const struct gdbarch_tdep *tdep = regset->descr;
+
+  gdb_assert (len == tdep->sizeof_fpregset);
+  x86_64_supply_fxsave (regcache, regnum, fpregs);
+}
+
+/* Return the appropriate register set for the core section identified
+   by SECT_NAME and SECT_SIZE.  */
+
+static const struct regset *
+x86_64_regset_from_core_section (struct gdbarch *gdbarch,
+                                const char *sect_name, size_t sect_size)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (strcmp (sect_name, ".reg2") == 0 && sect_size == tdep->sizeof_fpregset)
+    {
+      if (tdep->fpregset == NULL)
+       {
+         tdep->fpregset = XMALLOC (struct regset);
+         tdep->fpregset->descr = tdep;
+         tdep->fpregset->supply_regset = x86_64_supply_fpregset;
+       }
+
+      return tdep->fpregset;
+    }
+
+  return i386_regset_from_core_section (gdbarch, sect_name, sect_size);
+}
+\f
+
 void
 x86_64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  /* The x86-64 has 16 SSE registers.  */
+  /* AMD64 generally uses `fxsave' instead of `fsave' for saving its
+     floating-point registers.  */
+  tdep->sizeof_fpregset = I387_SIZEOF_FXSAVE;
+
+  /* AMD64 has an FPU and 16 SSE registers.  */
+  tdep->st0_regnum = X86_64_ST0_REGNUM;
   tdep->num_xmm_regs = 16;
 
   /* This is what all the fuss is about.  */
@@ -1237,6 +1293,8 @@ x86_64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* Call dummy code.  */
   set_gdbarch_push_dummy_call (gdbarch, x86_64_push_dummy_call);
+  set_gdbarch_frame_align (gdbarch, x86_64_frame_align);
+  set_gdbarch_frame_red_zone_size (gdbarch, 128);
 
   set_gdbarch_convert_register_p (gdbarch, x86_64_convert_register_p);
   set_gdbarch_register_to_value (gdbarch, i387_register_to_value);
@@ -1252,6 +1310,7 @@ x86_64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* Avoid wiring in the MMX registers for now.  */
   set_gdbarch_num_pseudo_regs (gdbarch, 0);
+  tdep->mm0_regnum = -1;
 
   set_gdbarch_unwind_dummy_id (gdbarch, x86_64_unwind_dummy_id);
 
@@ -1260,14 +1319,18 @@ x86_64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
      in the future.  */
   set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section);
 
-  frame_unwind_append_predicate (gdbarch, x86_64_sigtramp_frame_p);
-  frame_unwind_append_predicate (gdbarch, x86_64_frame_p);
+  frame_unwind_append_sniffer (gdbarch, x86_64_sigtramp_frame_sniffer);
+  frame_unwind_append_sniffer (gdbarch, x86_64_frame_sniffer);
   frame_base_set_default (gdbarch, &x86_64_frame_base);
+
+  /* If we have a register mapping, enable the generic core file support.  */
+  if (tdep->gregset_reg_offset)
+    set_gdbarch_regset_from_core_section (gdbarch,
+                                         x86_64_regset_from_core_section);
 }
 \f
 
-#define I387_FISEG_REGNUM FISEG_REGNUM
-#define I387_FOSEG_REGNUM FOSEG_REGNUM
+#define I387_ST0_REGNUM X86_64_ST0_REGNUM
 
 /* The 64-bit FXSAVE format differs from the 32-bit format in the
    sense that the instruction pointer and data pointer are simply
@@ -1276,24 +1339,30 @@ x86_64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
    bits of these pointers (instead of just the 16-bits of the segment
    selector).  */
 
-/* Fill GDB's register array with the floating-point and SSE register
-   values in *FXSAVE.  This function masks off any of the reserved
-   bits in *FXSAVE.  */
+/* Fill register REGNUM in REGCACHE with the appropriate
+   floating-point or SSE register value from *FXSAVE.  If REGNUM is
+   -1, do this for all registers.  This function masks off any of the
+   reserved bits in *FXSAVE.  */
 
 void
-x86_64_supply_fxsave (char *fxsave)
+x86_64_supply_fxsave (struct regcache *regcache, int regnum,
+                     const void *fxsave)
 {
-  i387_supply_fxsave (fxsave);
+  i387_supply_fxsave (regcache, regnum, fxsave);
 
   if (fxsave)
     {
-      supply_register (I387_FISEG_REGNUM, fxsave + 12);
-      supply_register (I387_FOSEG_REGNUM, fxsave + 20);
+      const char *regs = fxsave;
+
+      if (regnum == -1 || regnum == I387_FISEG_REGNUM)
+       regcache_raw_supply (regcache, I387_FISEG_REGNUM, regs + 12);
+      if (regnum == -1 || regnum == I387_FOSEG_REGNUM)
+       regcache_raw_supply (regcache, I387_FOSEG_REGNUM, regs + 20);
     }
 }
 
 /* Fill register REGNUM (if it is a floating-point or SSE register) in
-   *FXSAVE with the value in GDB's register array.  If REGNUM is -1, do
+   *FXSAVE with the value in GDB's register cache.  If REGNUM is -1, do
    this for all registers.  This function doesn't touch any of the
    reserved bits in *FXSAVE.  */
 
This page took 0.026668 seconds and 4 git commands to generate.