*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / amd64-tdep.c
index 2ce8efc5ed3ea54b5958cf890eea7ef2f9e2d05c..647edcd97b90844879118211ab71004b6a533678 100644 (file)
@@ -1,6 +1,8 @@
 /* Target-dependent code for AMD64.
 
-   Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
    Contributed by Jiri Smid, SuSE Labs.
 
    This file is part of GDB.
@@ -17,8 +19,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 #include "arch-utils.h"
@@ -55,7 +57,7 @@ struct amd64_register_info
   struct type **type;
 };
 
-static struct amd64_register_info amd64_register_info[] =
+static struct amd64_register_info const amd64_register_info[] =
 {
   { "rax", &builtin_type_int64 },
   { "rbx", &builtin_type_int64 },
@@ -76,7 +78,7 @@ static struct amd64_register_info amd64_register_info[] =
   { "r14", &builtin_type_int64 },
   { "r15", &builtin_type_int64 },
   { "rip", &builtin_type_void_func_ptr },
-  { "eflags", &builtin_type_int32 },
+  { "eflags", &i386_eflags_type },
   { "cs", &builtin_type_int32 },
   { "ss", &builtin_type_int32 },
   { "ds", &builtin_type_int32 },
@@ -103,28 +105,27 @@ static struct amd64_register_info amd64_register_info[] =
   { "fop", &builtin_type_int32 },
 
   /* %xmm0 is register number 40.  */
-  { "xmm0", &builtin_type_v4sf },
-  { "xmm1", &builtin_type_v4sf },
-  { "xmm2", &builtin_type_v4sf },
-  { "xmm3", &builtin_type_v4sf },
-  { "xmm4", &builtin_type_v4sf },
-  { "xmm5", &builtin_type_v4sf },
-  { "xmm6", &builtin_type_v4sf },
-  { "xmm7", &builtin_type_v4sf },
-  { "xmm8", &builtin_type_v4sf },
-  { "xmm9", &builtin_type_v4sf },
-  { "xmm10", &builtin_type_v4sf },
-  { "xmm11", &builtin_type_v4sf },
-  { "xmm12", &builtin_type_v4sf },
-  { "xmm13", &builtin_type_v4sf },
-  { "xmm14", &builtin_type_v4sf },
-  { "xmm15", &builtin_type_v4sf },
-  { "mxcsr", &builtin_type_int32 }
+  { "xmm0", &i386_sse_type },
+  { "xmm1", &i386_sse_type },
+  { "xmm2", &i386_sse_type },
+  { "xmm3", &i386_sse_type },
+  { "xmm4", &i386_sse_type },
+  { "xmm5", &i386_sse_type },
+  { "xmm6", &i386_sse_type },
+  { "xmm7", &i386_sse_type },
+  { "xmm8", &i386_sse_type },
+  { "xmm9", &i386_sse_type },
+  { "xmm10", &i386_sse_type },
+  { "xmm11", &i386_sse_type },
+  { "xmm12", &i386_sse_type },
+  { "xmm13", &i386_sse_type },
+  { "xmm14", &i386_sse_type },
+  { "xmm15", &i386_sse_type },
+  { "mxcsr", &i386_mxcsr_type }
 };
 
 /* Total number of registers.  */
-#define AMD64_NUM_REGS \
-  (sizeof (amd64_register_info) / sizeof (amd64_register_info[0]))
+#define AMD64_NUM_REGS ARRAY_SIZE (amd64_register_info)
 
 /* Return the name of register REGNUM.  */
 
@@ -186,7 +187,35 @@ static int amd64_dwarf_regmap[] =
   AMD64_ST0_REGNUM + 0, AMD64_ST0_REGNUM + 1,
   AMD64_ST0_REGNUM + 2, AMD64_ST0_REGNUM + 3,
   AMD64_ST0_REGNUM + 4, AMD64_ST0_REGNUM + 5,
-  AMD64_ST0_REGNUM + 6, AMD64_ST0_REGNUM + 7
+  AMD64_ST0_REGNUM + 6, AMD64_ST0_REGNUM + 7,
+  
+  /* Control and Status Flags Register.  */
+  AMD64_EFLAGS_REGNUM,
+
+  /* Selector Registers.  */
+  AMD64_ES_REGNUM,
+  AMD64_CS_REGNUM,
+  AMD64_SS_REGNUM,
+  AMD64_DS_REGNUM,
+  AMD64_FS_REGNUM,
+  AMD64_GS_REGNUM,
+  -1,
+  -1,
+
+  /* Segment Base Address Registers.  */
+  -1,
+  -1,
+  -1,
+  -1,
+
+  /* Special Selector Registers.  */
+  -1,
+  -1,
+
+  /* Floating Point Control Registers.  */
+  AMD64_MXCSR_REGNUM,
+  AMD64_FCTRL_REGNUM,
+  AMD64_FSTAT_REGNUM
 };
 
 static const int amd64_dwarf_regmap_len =
@@ -200,11 +229,11 @@ amd64_dwarf_reg_to_regnum (int reg)
 {
   int regnum = -1;
 
-  if (reg >= 0 || reg < amd64_dwarf_regmap_len)
+  if (reg >= 0 && reg < amd64_dwarf_regmap_len)
     regnum = amd64_dwarf_regmap[reg];
 
   if (regnum == -1)
-    warning ("Unmapped DWARF Register #%d encountered\n", reg);
+    warning (_("Unmapped DWARF Register #%d encountered."), reg);
 
   return regnum;
 }
@@ -375,7 +404,7 @@ amd64_classify (struct type *type, enum amd64_reg_class class[2])
      range types, used by languages such as Ada, are also in the INTEGER
      class.  */
   if ((code == TYPE_CODE_INT || code == TYPE_CODE_ENUM
-       || code == TYPE_CODE_RANGE
+       || code == TYPE_CODE_BOOL || code == TYPE_CODE_RANGE
        || code == TYPE_CODE_PTR || code == TYPE_CODE_REF)
       && (len == 1 || len == 2 || len == 4 || len == 8))
     class[0] = AMD64_INTEGER;
@@ -406,7 +435,7 @@ amd64_classify (struct type *type, enum amd64_reg_class class[2])
 static enum return_value_convention
 amd64_return_value (struct gdbarch *gdbarch, struct type *type,
                    struct regcache *regcache,
-                   void *readbuf, const void *writebuf)
+                   gdb_byte *readbuf, const gdb_byte *writebuf)
 {
   enum amd64_reg_class class[2];
   int len = TYPE_LENGTH (type);
@@ -503,10 +532,10 @@ amd64_return_value (struct gdbarch *gdbarch, struct type *type,
 
       if (readbuf)
        regcache_raw_read_part (regcache, regnum, offset, min (len, 8),
-                               (char *) readbuf + i * 8);
+                               readbuf + i * 8);
       if (writebuf)
        regcache_raw_write_part (regcache, regnum, offset, min (len, 8),
-                                (const char *) writebuf + i * 8);
+                                writebuf + i * 8);
     }
 
   return RETURN_VALUE_REGISTER_CONVENTION;
@@ -548,7 +577,7 @@ amd64_push_arguments (struct regcache *regcache, int nargs,
 
   for (i = 0; i < nargs; i++)
     {
-      struct type *type = VALUE_TYPE (args[i]);
+      struct type *type = value_type (args[i]);
       int len = TYPE_LENGTH (type);
       enum amd64_reg_class class[2];
       int needed_integer_regs = 0;
@@ -581,8 +610,8 @@ amd64_push_arguments (struct regcache *regcache, int nargs,
       else
        {
          /* The argument will be passed in registers.  */
-         char *valbuf = VALUE_CONTENTS (args[i]);
-         char buf[8];
+         const gdb_byte *valbuf = value_contents (args[i]);
+         gdb_byte buf[8];
 
          gdb_assert (len <= 16);
 
@@ -629,8 +658,8 @@ amd64_push_arguments (struct regcache *regcache, int nargs,
   /* Write out the arguments to the stack.  */
   for (i = 0; i < num_stack_args; i++)
     {
-      struct type *type = VALUE_TYPE (stack_args[i]);
-      char *valbuf = VALUE_CONTENTS (stack_args[i]);
+      struct type *type = value_type (stack_args[i]);
+      const gdb_byte *valbuf = value_contents (stack_args[i]);
       int len = TYPE_LENGTH (type);
 
       write_memory (sp + element * 8, valbuf, len);
@@ -646,12 +675,12 @@ amd64_push_arguments (struct regcache *regcache, int nargs,
 }
 
 static CORE_ADDR
-amd64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
+amd64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                       struct regcache *regcache, CORE_ADDR bp_addr,
                       int nargs, struct value **args,  CORE_ADDR sp,
                       int struct_return, CORE_ADDR struct_addr)
 {
-  char buf[8];
+  gdb_byte buf[8];
 
   /* Pass arguments.  */
   sp = amd64_push_arguments (regcache, nargs, args, sp, struct_return);
@@ -740,9 +769,9 @@ static CORE_ADDR
 amd64_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
                        struct amd64_frame_cache *cache)
 {
-  static unsigned char proto[3] = { 0x48, 0x89, 0xe5 };
-  unsigned char buf[3];
-  unsigned char op;
+  static gdb_byte proto[3] = { 0x48, 0x89, 0xe5 }; /* movq %rsp, %rbp */
+  gdb_byte buf[3];
+  gdb_byte op;
 
   if (current_pc <= pc)
     return current_pc;
@@ -795,7 +824,7 @@ static struct amd64_frame_cache *
 amd64_frame_cache (struct frame_info *next_frame, void **this_cache)
 {
   struct amd64_frame_cache *cache;
-  char buf[8];
+  gdb_byte buf[8];
   int i;
 
   if (*this_cache)
@@ -862,7 +891,7 @@ static void
 amd64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
                           int regnum, int *optimizedp,
                           enum lval_type *lvalp, CORE_ADDR *addrp,
-                          int *realnump, void *valuep)
+                          int *realnump, gdb_byte *valuep)
 {
   struct amd64_frame_cache *cache =
     amd64_frame_cache (next_frame, this_cache);
@@ -898,8 +927,12 @@ amd64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
       return;
     }
 
-  frame_register_unwind (next_frame, regnum,
-                        optimizedp, lvalp, addrp, realnump, valuep);
+  *optimizedp = 0;
+  *lvalp = lval_register;
+  *addrp = 0;
+  *realnump = regnum;
+  if (valuep)
+    frame_unwind_register (next_frame, (*realnump), valuep);
 }
 
 static const struct frame_unwind amd64_frame_unwind =
@@ -928,7 +961,7 @@ amd64_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache)
   struct amd64_frame_cache *cache;
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
   CORE_ADDR addr;
-  char buf[8];
+  gdb_byte buf[8];
   int i;
 
   if (*this_cache)
@@ -965,7 +998,7 @@ amd64_sigtramp_frame_prev_register (struct frame_info *next_frame,
                                    void **this_cache,
                                    int regnum, int *optimizedp,
                                    enum lval_type *lvalp, CORE_ADDR *addrp,
-                                   int *realnump, void *valuep)
+                                   int *realnump, gdb_byte *valuep)
 {
   /* Make sure we've initialized the cache.  */
   amd64_sigtramp_frame_cache (next_frame, this_cache);
@@ -1030,7 +1063,7 @@ static const struct frame_base amd64_frame_base =
 static struct frame_id
 amd64_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
-  char buf[8];
+  gdb_byte buf[8];
   CORE_ADDR fp;
 
   frame_unwind_register (next_frame, AMD64_RBP_REGNUM, buf);
@@ -1048,9 +1081,9 @@ amd64_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
 }
 \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.  */
+/* Supply register REGNUM from the buffer specified by FPREGS and LEN
+   in the floating-point register set REGSET to register cache
+   REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
 
 static void
 amd64_supply_fpregset (const struct regset *regset, struct regcache *regcache,
@@ -1062,6 +1095,22 @@ amd64_supply_fpregset (const struct regset *regset, struct regcache *regcache,
   amd64_supply_fxsave (regcache, regnum, fpregs);
 }
 
+/* Collect register REGNUM from the register cache REGCACHE and store
+   it in the buffer specified by FPREGS and LEN as described by the
+   floating-point register set REGSET.  If REGNUM is -1, do this for
+   all registers in REGSET.  */
+
+static void
+amd64_collect_fpregset (const struct regset *regset,
+                       const struct regcache *regcache,
+                       int regnum, void *fpregs, size_t len)
+{
+  const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
+
+  gdb_assert (len == tdep->sizeof_fpregset);
+  amd64_collect_fxsave (regcache, regnum, fpregs);
+}
+
 /* Return the appropriate register set for the core section identified
    by SECT_NAME and SECT_SIZE.  */
 
@@ -1074,7 +1123,8 @@ amd64_regset_from_core_section (struct gdbarch *gdbarch,
   if (strcmp (sect_name, ".reg2") == 0 && sect_size == tdep->sizeof_fpregset)
     {
       if (tdep->fpregset == NULL)
-        tdep->fpregset = regset_alloc (gdbarch, amd64_supply_fpregset, NULL);
+       tdep->fpregset = regset_alloc (gdbarch, amd64_supply_fpregset,
+                                      amd64_collect_fpregset);
 
       return tdep->fpregset;
     }
@@ -1148,11 +1198,6 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   set_gdbarch_unwind_dummy_id (gdbarch, amd64_unwind_dummy_id);
 
-  /* FIXME: kettenis/20021026: This is ELF-specific.  Fine for now,
-     since all supported AMD64 targets are ELF, but that might change
-     in the future.  */
-  set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section);
-
   frame_unwind_append_sniffer (gdbarch, amd64_sigtramp_frame_sniffer);
   frame_unwind_append_sniffer (gdbarch, amd64_frame_sniffer);
   frame_base_set_default (gdbarch, &amd64_frame_base);
@@ -1186,7 +1231,7 @@ amd64_supply_fxsave (struct regcache *regcache, int regnum,
 
   if (fxsave && gdbarch_ptr_bit (get_regcache_arch (regcache)) == 64)
     {
-      const char *regs = fxsave;
+      const gdb_byte *regs = fxsave;
 
       if (regnum == -1 || regnum == I387_FISEG_REGNUM)
        regcache_raw_supply (regcache, I387_FISEG_REGNUM, regs + 12);
@@ -1204,7 +1249,7 @@ void
 amd64_collect_fxsave (const struct regcache *regcache, int regnum,
                      void *fxsave)
 {
-  char *regs = fxsave;
+  gdb_byte *regs = fxsave;
 
   i387_collect_fxsave (regcache, regnum, fxsave);
 
This page took 0.029625 seconds and 4 git commands to generate.