]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Merge with mainline.
authorMichal Ludvig <mludvig@suse.cz>
Wed, 3 Jul 2002 06:00:29 +0000 (06:00 +0000)
committerMichal Ludvig <mludvig@suse.cz>
Wed, 3 Jul 2002 06:00:29 +0000 (06:00 +0000)
gdb/ChangeLog
gdb/dwarf2cfi.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.asm/asm-source.exp
gdb/x86-64-linux-nat.c
gdb/x86-64-tdep.c
gdb/x86-64-tdep.h

index a91540f3440dd737e657fbd0adc500c818200306..d5294f3a6112234547cbba176e35937b682325d3 100644 (file)
@@ -1,3 +1,48 @@
+2002-07-03  Michal Ludvig  <mludvig@suse.cz>
+
+       Merge from mainline:
+
+       2002-06-21  Michal Ludvig  <mludvig@suse.cz>
+       * dwarf2cfi.c (read_encoded_pointer): Don't handle pointer 
+       encoding anymore.
+       (pointer_encoding, enum ptr_encoding): New.
+       (execute_cfa_program): Take care about pointer encoding.        
+       (dwarf2_build_frame_info): Only call parse_frame_info for 
+       .debug_frame and .eh_frame.
+       (parse_frame_info): New, derived from former dwarf2_build_frame_info.
+       fixed augmentation handling, added relative addressing, 
+       ignore duplicate FDEs. Added comments.
+       * dwarf2cfi.c: Reindented.
+       
+       2002-06-20  Michal Ludvig  <mludvig@suse.cz>
+       * x86-64-tdep.c (x86_64_register_nr2name): Rename to 
+       x86_64_register_name. Return type changed to 'const char *'.
+       (x86_64_register_name2nr): Rename to x86_64_register_number.
+       (x86_64_gdbarch_init): Update to reflect the change.
+       * x86-64-tdep.h: Ditto.
+       * x86-64-linux-nat.c (x86_64_fxsave_offset)
+       (supply_fpregset): Ditto.
+
+       2002-06-11  Michal Ludvig  <mludvig@suse.cz>
+       * dwarf2cfi.c (unwind_tmp_obstack_init): New.
+       (unwind_tmp_obstack_free, parse_frame_info)
+       (update_context, cfi_read_fp, cfi_write_fp)
+       (cfi_frame_chain, cfi_init_extra_frame_info)
+       (cfi_virtual_frame_pointer): Use the above function.
+       * x86-64-tdep.c (x86_64_skip_prologue): Fix to work on functions
+       without debug information too.
+
+       2002-06-07  Michal Ludvig  <mludvig@suse.cz>
+       * x86-64-linux-nat.c (x86_64_fxsave_offset): New.
+       (supply_fpregset, fill_fpregset): Don't call i387_*_fxsave,
+       better do the things actually here.
+       * x86-64-tdep.c (x86_64_register_name2nr): New.
+       (x86_64_register_name): Renamed to x86_64_register_nr2name.
+       (x86_64_gdbarch_init): Respect the above change.
+       * x86-64-tdep.h (x86_64_register_name2nr)
+       (x86_64_register_nr2name): Add prototypes.
+       * config/i386/x86-64linux.mt (TDEPFILES): Remove i387-tdep.o.
+
 2002-06-28  Andrew Cagney  <ac131313@redhat.com>
 
        * Makefile.in (objfiles_h): Add $(bcache_h).
index 783d1c014e0eea20efa3cbe314e8d4097edddfad..442ae70e54039fbc652190b9102ab3c7954fc053 100644 (file)
@@ -34,7 +34,7 @@
    Frame Descriptors.  */
 struct cie_unit
 {
-  /* Offset of this unit in dwarf_frame_buffer.  */
+  /* Offset of this unit in .debug_frame or .eh_frame.  */
   ULONGEST offset;
 
   /* A null-terminated string that identifies the augmentation to this CIE or
@@ -176,6 +176,15 @@ struct frame_state
   struct objfile *objfile;
 };
 
+enum ptr_encoding
+{
+  PE_absptr = DW_EH_PE_absptr,
+  PE_pcrel = DW_EH_PE_pcrel,
+  PE_textrel = DW_EH_PE_textrel,
+  PE_datarel = DW_EH_PE_datarel,
+  PE_funcrel = DW_EH_PE_funcrel
+};
+
 #define UNWIND_CONTEXT(fi) ((struct context *) (fi->context))
 \f
 
@@ -188,8 +197,6 @@ extern file_ptr dwarf_frame_offset;
 extern unsigned int dwarf_frame_size;
 extern file_ptr dwarf_eh_frame_offset;
 extern unsigned int dwarf_eh_frame_size;
-
-static char *dwarf_frame_buffer;
 \f
 
 extern char *dwarf2_read_section (struct objfile *objfile, file_ptr offset,
@@ -201,26 +208,28 @@ static void fde_chunks_need_space ();
 
 static struct context *context_alloc ();
 static struct frame_state *frame_state_alloc ();
+static void unwind_tmp_obstack_init ();
 static void unwind_tmp_obstack_free ();
 static void context_cpy (struct context *dst, struct context *src);
 
-static unsigned int read_1u (bfd *abfd, char **p);
-static int read_1s (bfd *abfd, char **p);
-static unsigned int read_2u (bfd *abfd, char **p);
-static int read_2s (bfd *abfd, char **p);
-static unsigned int read_4u (bfd *abfd, char **p);
-static int read_4s (bfd *abfd, char **p);
-static ULONGEST read_8u (bfd *abfd, char **p);
-static LONGEST read_8s (bfd *abfd, char **p);
-
-static ULONGEST read_uleb128 (bfd *abfd, char **p);
-static LONGEST read_sleb128 (bfd *abfd, char **p);
-static CORE_ADDR read_pointer (bfd *abfd, char **p);
-static CORE_ADDR read_encoded_pointer (bfd *abfd, char **p,
+static unsigned int read_1u (bfd * abfd, char **p);
+static int read_1s (bfd * abfd, char **p);
+static unsigned int read_2u (bfd * abfd, char **p);
+static int read_2s (bfd * abfd, char **p);
+static unsigned int read_4u (bfd * abfd, char **p);
+static int read_4s (bfd * abfd, char **p);
+static ULONGEST read_8u (bfd * abfd, char **p);
+static LONGEST read_8s (bfd * abfd, char **p);
+
+static ULONGEST read_uleb128 (bfd * abfd, char **p);
+static LONGEST read_sleb128 (bfd * abfd, char **p);
+static CORE_ADDR read_pointer (bfd * abfd, char **p);
+static CORE_ADDR read_encoded_pointer (bfd * abfd, char **p,
                                       unsigned char encoding);
+static enum ptr_encoding pointer_encoding (unsigned char encoding);
 
-static LONGEST read_initial_length (bfd *abfd, char *buf, int *bytes_read);
-static ULONGEST read_length (bfd *abfd, char *buf, int *bytes_read,
+static LONGEST read_initial_length (bfd * abfd, char *buf, int *bytes_read);
+static ULONGEST read_length (bfd * abfd, char *buf, int *bytes_read,
                             int dwarf64);
 
 static int is_cie (ULONGEST cie_id, int dwarf64);
@@ -235,11 +244,12 @@ static void frame_state_for (struct context *context, struct frame_state *fs);
 static void get_reg (char *reg, struct context *context, int regnum);
 static CORE_ADDR execute_stack_op (struct objfile *objfile,
                                   char *op_ptr, char *op_end,
-                                  struct context *context, CORE_ADDR initial);
+                                  struct context *context,
+                                  CORE_ADDR initial);
 static void update_context (struct context *context, struct frame_state *fs,
                            int chain);
-
 \f
+
 /* Memory allocation functions.  */
 static struct fde_unit *
 fde_unit_alloc (void)
@@ -301,17 +311,23 @@ frame_state_alloc ()
   fs = (struct frame_state *) obstack_alloc (&unwind_tmp_obstack,
                                             sizeof (struct frame_state));
   memset (fs, 0, sizeof (struct frame_state));
-  fs->regs.reg = (struct frame_state_reg *)  obstack_alloc (&unwind_tmp_obstack,
-                                                           regs_size);
+  fs->regs.reg =
+    (struct frame_state_reg *) obstack_alloc (&unwind_tmp_obstack, regs_size);
   memset (fs->regs.reg, 0, regs_size);
   return fs;
 }
 
+static void
+unwind_tmp_obstack_init ()
+{
+  obstack_init (&unwind_tmp_obstack);
+}
+
 static void
 unwind_tmp_obstack_free ()
 {
   obstack_free (&unwind_tmp_obstack, NULL);
-  obstack_init (&unwind_tmp_obstack);
+  unwind_tmp_obstack_init ();
 }
 
 static void
@@ -334,92 +350,92 @@ context_cpy (struct context *dst, struct context *src)
   dreg = dst->reg;
   *dst = *src;
   dst->reg = dreg;
-  
+
   memcpy (dst->reg, src->reg, regs_size);
 }
 
 static unsigned int
-read_1u (bfd *abfd, char **p)
+read_1u (bfd * abfd, char **p)
 {
   unsigned ret;
 
-  ret= bfd_get_8 (abfd, (bfd_byte *) *p);
-  (*p) ++;
+  ret = bfd_get_8 (abfd, (bfd_byte *) * p);
+  (*p)++;
   return ret;
 }
 
 static int
-read_1s (bfd *abfd, char **p)
+read_1s (bfd * abfd, char **p)
 {
   int ret;
 
-  ret= bfd_get_signed_8 (abfd, (bfd_byte *) *p);
-  (*p) ++;
+  ret = bfd_get_signed_8 (abfd, (bfd_byte *) * p);
+  (*p)++;
   return ret;
 }
 
 static unsigned int
-read_2u (bfd *abfd, char **p)
+read_2u (bfd * abfd, char **p)
 {
   unsigned ret;
 
-  ret= bfd_get_16 (abfd, (bfd_byte *) *p);
-  (*p) ++;
+  ret = bfd_get_16 (abfd, (bfd_byte *) * p);
+  (*p)++;
   return ret;
 }
 
 static int
-read_2s (bfd *abfd, char **p)
+read_2s (bfd * abfd, char **p)
 {
   int ret;
 
-  ret= bfd_get_signed_16 (abfd, (bfd_byte *) *p);
+  ret = bfd_get_signed_16 (abfd, (bfd_byte *) * p);
   (*p) += 2;
   return ret;
 }
 
 static unsigned int
-read_4u (bfd *abfd, char **p)
+read_4u (bfd * abfd, char **p)
 {
   unsigned int ret;
 
-  ret= bfd_get_32 (abfd, (bfd_byte *) *p);
+  ret = bfd_get_32 (abfd, (bfd_byte *) * p);
   (*p) += 4;
   return ret;
 }
 
 static int
-read_4s (bfd *abfd, char **p)
+read_4s (bfd * abfd, char **p)
 {
   int ret;
 
-  ret= bfd_get_signed_32 (abfd, (bfd_byte *) *p);
+  ret = bfd_get_signed_32 (abfd, (bfd_byte *) * p);
   (*p) += 4;
   return ret;
 }
 
 static ULONGEST
-read_8u (bfd *abfd, char **p)
+read_8u (bfd * abfd, char **p)
 {
   ULONGEST ret;
 
-  ret = bfd_get_64 (abfd, (bfd_byte *) *p);
+  ret = bfd_get_64 (abfd, (bfd_byte *) * p);
   (*p) += 8;
   return ret;
 }
 
 static LONGEST
-read_8s (bfd *abfd, char **p)
+read_8s (bfd * abfd, char **p)
 {
   LONGEST ret;
 
-  ret = bfd_get_signed_64 (abfd, (bfd_byte *) *p);
+  ret = bfd_get_signed_64 (abfd, (bfd_byte *) * p);
   (*p) += 8;
   return ret;
 }
 
 static ULONGEST
-read_uleb128 (bfd *abfd, char **p)
+read_uleb128 (bfd * abfd, char **p)
 {
   ULONGEST ret;
   int i, shift;
@@ -430,8 +446,8 @@ read_uleb128 (bfd *abfd, char **p)
   i = 0;
   while (1)
     {
-      byte = bfd_get_8 (abfd, (bfd_byte *) *p);
-      (*p) ++;
+      byte = bfd_get_8 (abfd, (bfd_byte *) * p);
+      (*p)++;
       ret |= ((unsigned long) (byte & 127) << shift);
       if ((byte & 128) == 0)
        {
@@ -443,7 +459,7 @@ read_uleb128 (bfd *abfd, char **p)
 }
 
 static LONGEST
-read_sleb128 (bfd *abfd, char **p)
+read_sleb128 (bfd * abfd, char **p)
 {
   LONGEST ret;
   int i, shift, size, num_read;
@@ -456,8 +472,8 @@ read_sleb128 (bfd *abfd, char **p)
   i = 0;
   while (1)
     {
-      byte = bfd_get_8 (abfd, (bfd_byte *) *p);
-      (*p) ++;
+      byte = bfd_get_8 (abfd, (bfd_byte *) * p);
+      (*p)++;
       ret |= ((long) (byte & 127) << shift);
       shift += 7;
       if ((byte & 128) == 0)
@@ -473,7 +489,7 @@ read_sleb128 (bfd *abfd, char **p)
 }
 
 static CORE_ADDR
-read_pointer (bfd *abfd, char **p)
+read_pointer (bfd * abfd, char **p)
 {
   switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
     {
@@ -486,8 +502,11 @@ read_pointer (bfd *abfd, char **p)
     }
 }
 
+/* This functions only reads appropriate amount of data from *p 
+ * and returns the resulting value. Calling function must handle
+ * different encoding possibilities itself!  */
 static CORE_ADDR
-read_encoded_pointer (bfd *abfd, char **p, unsigned char encoding)
+read_encoded_pointer (bfd * abfd, char **p, unsigned char encoding)
 {
   CORE_ADDR ret;
 
@@ -529,22 +548,33 @@ read_encoded_pointer (bfd *abfd, char **p, unsigned char encoding)
                      "read_encoded_pointer: unknown pointer encoding");
     }
 
-  if (ret != 0)
-    switch (encoding & 0xf0)
-      {
-      case DW_EH_PE_absptr:
-       break;
-      case DW_EH_PE_pcrel:
-       ret += (CORE_ADDR) *p;
-       break;
-      case DW_EH_PE_textrel:
-      case DW_EH_PE_datarel:
-      case DW_EH_PE_funcrel:
-      default:
-       internal_error (__FILE__, __LINE__,
-                       "read_encoded_pointer: unknown pointer encoding");
-      }
+  return ret;
+}
+
+/* Variable 'encoding' carries 3 different flags:
+ * - encoding & 0x0f : size of the address (handled in read_encoded_pointer())
+ * - encoding & 0x70 : type (absolute, relative, ...)
+ * - encoding & 0x80 : indirect flag (DW_EH_PE_indirect == 0x80).  */
+enum ptr_encoding
+pointer_encoding (unsigned char encoding)
+{
+  int ret;
+
+  if (encoding & DW_EH_PE_indirect)
+    warning ("CFI: Unsupported pointer encoding: DW_EH_PE_indirect");
 
+  switch (encoding & 0x70)
+    {
+    case DW_EH_PE_absptr:
+    case DW_EH_PE_pcrel:
+    case DW_EH_PE_textrel:
+    case DW_EH_PE_datarel:
+    case DW_EH_PE_funcrel:
+      ret = encoding & 0x70;
+      break;
+    default:
+      internal_error (__FILE__, __LINE__, "CFI: unknown pointer encoding");
+    }
   return ret;
 }
 
@@ -584,8 +614,8 @@ read_length (bfd * abfd, char *buf, int *bytes_read, int dwarf64)
 }
 
 static void
-execute_cfa_program ( struct objfile *objfile, char *insn_ptr, char *insn_end,
-                     struct context *context, struct frame_state *fs)
+execute_cfa_program (struct objfile *objfile, char *insn_ptr, char *insn_end,
+                    struct context *context, struct frame_state *fs)
 {
   struct frame_state_regs *unused_rs = NULL;
 
@@ -604,7 +634,7 @@ execute_cfa_program ( struct objfile *objfile, char *insn_ptr, char *insn_end,
        {
          reg = insn & 0x3f;
          uoffset = read_uleb128 (objfile->obfd, &insn_ptr);
-         offset = (long) uoffset * fs->data_align;
+         offset = (long) uoffset *fs->data_align;
          fs->regs.reg[reg].how = REG_SAVED_OFFSET;
          fs->regs.reg[reg].loc.offset = offset;
        }
@@ -619,6 +649,10 @@ execute_cfa_program ( struct objfile *objfile, char *insn_ptr, char *insn_end,
          case DW_CFA_set_loc:
            fs->pc = read_encoded_pointer (objfile->obfd, &insn_ptr,
                                           fs->addr_encoding);
+
+           if (pointer_encoding (fs->addr_encoding) != PE_absptr)
+             warning ("CFI: DW_CFA_set_loc uses relative addressing");
+
            break;
 
          case DW_CFA_advance_loc1:
@@ -806,13 +840,13 @@ frame_state_for (struct context *context, struct frame_state *fs)
 
   if (fde == NULL)
     return;
-  
+
   fs->pc = fde->initial_location;
 
   if (fde->cie_ptr)
-  {
+    {
       cie = fde->cie_ptr;
-      
+
       fs->code_align = cie->code_align;
       fs->data_align = cie->data_align;
       fs->retaddr_column = cie->ra;
@@ -823,11 +857,10 @@ frame_state_for (struct context *context, struct frame_state *fs)
                           cie->data + cie->data_length, context, fs);
       execute_cfa_program (cie->objfile, fde->data,
                           fde->data + fde->data_length, context, fs);
-  }
+    }
   else
-       internal_error (__FILE__, __LINE__,
-               "%s(): Internal error: fde->cie_ptr==NULL !", 
-               __func__);
+    internal_error (__FILE__, __LINE__,
+                   "%s(): Internal error: fde->cie_ptr==NULL !", __func__);
 }
 
 static void
@@ -854,8 +887,7 @@ get_reg (char *reg, struct context *context, int regnum)
              REGISTER_RAW_SIZE (regnum));
       break;
     default:
-      internal_error (__FILE__, __LINE__,
-                     "get_reg: unknown register rule");
+      internal_error (__FILE__, __LINE__, "get_reg: unknown register rule");
     }
 }
 
@@ -1208,8 +1240,8 @@ execute_stack_op (struct objfile *objfile,
              case DW_OP_ne:
                result = (LONGEST) first != (LONGEST) second;
                break;
-             default:  /* This label is here just to avoid warning.  */
-               break; 
+             default:          /* This label is here just to avoid warning.  */
+               break;
              }
          }
          break;
@@ -1255,8 +1287,11 @@ update_context (struct context *context, struct frame_state *fs, int chain)
   CORE_ADDR cfa;
   long i;
 
+  unwind_tmp_obstack_init ();
+
   orig_context = context_alloc ();
   context_cpy (orig_context, context);
+
   /* Compute this frame's CFA.  */
   switch (fs->cfa_how)
     {
@@ -1267,9 +1302,9 @@ update_context (struct context *context, struct frame_state *fs, int chain)
 
     case CFA_EXP:
       /* ??? No way of knowing what register number is the stack pointer
-        to do the same sort of handling as above.  Assume that if the
-        CFA calculation is so complicated as to require a stack program
-        that this will not be a problem.  */
+         to do the same sort of handling as above.  Assume that if the
+         CFA calculation is so complicated as to require a stack program
+         that this will not be a problem.  */
       {
        char *exp = fs->cfa_exp;
        ULONGEST len;
@@ -1371,39 +1406,46 @@ compare_fde_unit (const void *a, const void *b)
 }
 
 /*  Build the cie_chunks and fde_chunks tables from informations
-    in .debug_frame section.  */
-void
-dwarf2_build_frame_info (struct objfile *objfile)
+    found in .debug_frame and .eh_frame sections.  */
+/* We can handle both of these sections almost in the same way, however there
+   are some exceptions:
+   - CIE ID is -1 in debug_frame, but 0 in eh_frame
+   - eh_frame may contain some more information that are used only by gcc 
+     (eg. personality pointer, LSDA pointer, ...). Most of them we can ignore.
+   - In debug_frame FDE's item cie_id contains offset of it's parent CIE.
+     In eh_frame FDE's item cie_id is a relative pointer to the parent CIE.
+     Anyway we don't need to bother with this, because we are smart enough 
+     to keep the pointer to the parent CIE of oncomming FDEs in 'last_cie'.
+   - Although debug_frame items can contain Augmentation as well as 
+     eh_frame ones, I have never seen them non-empty. Thus only in eh_frame 
+     we can encounter for example non-absolute pointers (Aug. 'R').  
+                                                              -- mludvig  */
+static void
+parse_frame_info (struct objfile *objfile, file_ptr frame_offset,
+                 unsigned int frame_size, int eh_frame)
 {
   bfd *abfd = objfile->obfd;
+  asection *curr_section_ptr;
   char *start = NULL;
   char *end = NULL;
-  int from_eh = 0;
-
-  obstack_init (&unwind_tmp_obstack);
-
-  dwarf_frame_buffer = 0;
+  char *frame_buffer = NULL;
+  char *curr_section_name, *aug_data;
+  struct cie_unit *last_cie = NULL;
+  int last_dup_fde = 0;
+  int aug_len, i;
+  CORE_ADDR curr_section_vma = 0;
 
-  if (dwarf_frame_offset)
-    {
-      dwarf_frame_buffer = dwarf2_read_section (objfile,
-                                               dwarf_frame_offset,
-                                               dwarf_frame_size);
+  unwind_tmp_obstack_init ();
 
-      start = dwarf_frame_buffer;
-      end = dwarf_frame_buffer + dwarf_frame_size;
-    }
-  else if (dwarf_eh_frame_offset)
-    {
-      dwarf_frame_buffer = dwarf2_read_section (objfile,
-                                               dwarf_eh_frame_offset,
-                                               dwarf_eh_frame_size);
+  frame_buffer = dwarf2_read_section (objfile, frame_offset, frame_size);
 
-      start = dwarf_frame_buffer;
-      end = dwarf_frame_buffer + dwarf_eh_frame_size;
+  start = frame_buffer;
+  end = frame_buffer + frame_size;
 
-      from_eh = 1;
-    }
+  curr_section_name = eh_frame ? ".eh_frame" : ".debug_frame";
+  curr_section_ptr = bfd_get_section_by_name (abfd, curr_section_name);
+  if (curr_section_ptr)
+    curr_section_vma = curr_section_ptr->vma;
 
   if (start)
     {
@@ -1411,9 +1453,8 @@ dwarf2_build_frame_info (struct objfile *objfile)
        {
          unsigned long length;
          ULONGEST cie_id;
-         ULONGEST unit_offset = start - dwarf_frame_buffer;
-         int bytes_read;
-         int dwarf64;
+         ULONGEST unit_offset = start - frame_buffer;
+         int bytes_read, dwarf64;
          char *block_end;
 
          length = read_initial_length (abfd, start, &bytes_read);
@@ -1421,10 +1462,16 @@ dwarf2_build_frame_info (struct objfile *objfile)
          dwarf64 = (bytes_read == 12);
          block_end = start + length;
 
+         if (length == 0)
+           {
+             start = block_end;
+             continue;
+           }
+
          cie_id = read_length (abfd, start, &bytes_read, dwarf64);
          start += bytes_read;
 
-         if ((from_eh && cie_id == 0) || is_cie (cie_id, dwarf64))
+         if ((eh_frame && cie_id == 0) || is_cie (cie_id, dwarf64))
            {
              struct cie_unit *cie = cie_unit_alloc ();
              char *aug;
@@ -1440,84 +1487,186 @@ dwarf2_build_frame_info (struct objfile *objfile)
              start++;          /* version */
 
              cie->augmentation = aug = start;
-             while (*start)
-               start++;
-             start++;          /* skip past NUL */
+             while (*start++); /* Skips last NULL as well */
 
              cie->code_align = read_uleb128 (abfd, &start);
              cie->data_align = read_sleb128 (abfd, &start);
              cie->ra = read_1u (abfd, &start);
 
+             /* Augmentation:
+                z      Indicates that a uleb128 is present to size the
+                augmentation section.
+                L      Indicates the encoding (and thus presence) of
+                an LSDA pointer in the FDE augmentation.
+                R      Indicates a non-default pointer encoding for
+                FDE code pointers.
+                P      Indicates the presence of an encoding + language
+                personality routine in the CIE augmentation.
+
+                [This info comes from GCC's dwarf2out.c]
+              */
              if (*aug == 'z')
                {
-                 int xtra = read_uleb128 (abfd, &start);
-                 start += xtra;
+                 aug_len = read_uleb128 (abfd, &start);
+                 aug_data = start;
+                 start += aug_len;
                  ++aug;
                }
 
+             cie->data = start;
+             cie->data_length = block_end - cie->data;
+
              while (*aug != '\0')
                {
                  if (aug[0] == 'e' && aug[1] == 'h')
                    {
-                     start += sizeof (void *);
-                     aug += 2;
+                     aug_data += sizeof (void *);
+                     aug++;
                    }
                  else if (aug[0] == 'R')
+                   cie->addr_encoding = *aug_data++;
+                 else if (aug[0] == 'P')
                    {
-                     cie->addr_encoding = *start++;
-                     aug += 1;
+                     CORE_ADDR pers_addr;
+                     int pers_addr_enc;
+
+                     pers_addr_enc = *aug_data++;
+                     /* We don't need pers_addr value and so we 
+                        don't care about it's encoding.  */
+                     pers_addr = read_encoded_pointer (abfd, &aug_data,
+                                                       pers_addr_enc);
                    }
-                 else if (aug[0] == 'P')
+                 else if (aug[0] == 'L' && eh_frame)
                    {
-                     CORE_ADDR ptr;
-                     ptr = read_encoded_pointer (abfd, &start,
-                                                 cie->addr_encoding);
-                     aug += 1;
+                     int lsda_addr_enc;
+
+                     /* Perhaps we should save this to CIE for later use?
+                        Do we need it for something in GDB?  */
+                     lsda_addr_enc = *aug_data++;
                    }
                  else
-                   warning ("%s(): unknown augmentation", __func__);
+                   warning ("CFI warning: unknown augmentation \"%c\""
+                            " in \"%s\" of\n"
+                            "\t%s", aug[0], curr_section_name,
+                            objfile->name);
+                 aug++;
                }
 
-             cie->data = start;
-             cie->data_length = block_end - start;
+             last_cie = cie;
            }
          else
            {
              struct fde_unit *fde;
              struct cie_unit *cie;
+             int dup = 0;
+             CORE_ADDR init_loc;
+
+             /* We assume that debug_frame is in order 
+                CIE,FDE,CIE,FDE,FDE,...  and thus the CIE for this FDE
+                should be stored in last_cie pointer. If not, we'll 
+                try to find it by the older way.  */
+             if (last_cie)
+               cie = last_cie;
+             else
+               {
+                 warning ("CFI: last_cie == NULL. "
+                          "Perhaps a malformed %s section in '%s'...?\n",
+                          curr_section_name, objfile->name);
 
-             fde_chunks_need_space ();
-             fde = fde_unit_alloc ();
+                 cie = cie_chunks;
+                 while (cie)
+                   {
+                     if (cie->objfile == objfile)
+                       {
+                         if (eh_frame &&
+                             (cie->offset ==
+                              (unit_offset + bytes_read - cie_id)))
+                           break;
+                         if (!eh_frame && (cie->offset == cie_id))
+                           break;
+                       }
+
+                     cie = cie->next;
+                   }
+                 if (!cie)
+                   error ("CFI: can't find CIE pointer");
+               }
 
-             fde_chunks.array[fde_chunks.elems++] = fde;
-             
-             fde->initial_location = read_pointer (abfd, &start)
-               + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
-             fde->address_range = read_pointer (abfd, &start);
+             init_loc = read_encoded_pointer (abfd, &start,
+                                              cie->addr_encoding);
 
-             cie = cie_chunks;
-             while(cie)
-             {
-               if (cie->objfile == objfile)
+             switch (pointer_encoding (cie->addr_encoding))
                {
-                 if (from_eh && (cie->offset == (unit_offset + bytes_read - cie_id)))
-                     break;
-                 if (!from_eh && (cie->offset == cie_id))
-                   break;
+               case PE_absptr:
+                 break;
+               case PE_pcrel:
+                 /* start-frame_buffer gives offset from 
+                    the beginning of actual section.  */
+                 init_loc += curr_section_vma + start - frame_buffer;
+                 break;
+               default:
+                 warning ("CFI: Unsupported pointer encoding\n");
                }
 
-               cie = cie->next;
-             }
-           
-             if (!cie)
-               error ("%s(): can't find CIE pointer", __func__);
-             fde->cie_ptr = cie;
+             /* For relocatable objects we must add an offset telling
+                where the section is actually mapped in the memory.  */
+             init_loc += ANOFFSET (objfile->section_offsets,
+                                   SECT_OFF_TEXT (objfile));
+
+             /* If we have both .debug_frame and .eh_frame present in 
+                a file, we must eliminate duplicate FDEs. For now we'll 
+                run through all entries in fde_chunks and check it one 
+                by one. Perhaps in the future we can implement a faster 
+                searching algorithm.  */
+             /* eh_frame==2 indicates, that this file has an already 
+                parsed .debug_frame too. When eh_frame==1 it means, that no
+                .debug_frame is present and thus we don't need to check for
+                duplicities. eh_frame==0 means, that we parse .debug_frame
+                and don't need to care about duplicate FDEs, because
+                .debug_frame is parsed first.  */
+             if (eh_frame == 2)
+               for (i = 0; eh_frame == 2 && i < fde_chunks.elems; i++)
+                 {
+                   /* We assume that FDEs in .debug_frame and .eh_frame 
+                      have the same order (if they are present, of course).
+                      If we find a duplicate entry for one FDE and save
+                      it's index to last_dup_fde it's very likely, that 
+                      we'll find an entry for the following FDE right after 
+                      the previous one. Thus in many cases we'll run this 
+                      loop only once.  */
+                   last_dup_fde = (last_dup_fde + i) % fde_chunks.elems;
+                   if (fde_chunks.array[last_dup_fde]->initial_location
+                       == init_loc)
+                     {
+                       dup = 1;
+                       break;
+                     }
+                 }
+
+             /* Allocate a new entry only if this FDE isn't a duplicate of
+                something we have already seen.   */
+             if (!dup)
+               {
+                 fde_chunks_need_space ();
+                 fde = fde_unit_alloc ();
 
-             if (cie->augmentation[0] == 'z')
-                 read_uleb128 (abfd, &start);
+                 fde_chunks.array[fde_chunks.elems++] = fde;
 
-             fde->data = start;
-             fde->data_length = block_end - start;
+                 fde->initial_location = init_loc;
+                 fde->address_range = read_encoded_pointer (abfd, &start,
+                                                            cie->
+                                                            addr_encoding);
+
+                 fde->cie_ptr = cie;
+
+                 /* Here we intentionally ignore augmentation data
+                    from FDE, because we don't need them.  */
+                 if (cie->augmentation[0] == 'z')
+                   start += read_uleb128 (abfd, &start);
+
+                 fde->data = start;
+                 fde->data_length = block_end - start;
+               }
            }
          start = block_end;
        }
@@ -1525,7 +1674,30 @@ dwarf2_build_frame_info (struct objfile *objfile)
             sizeof (struct fde_unit *), compare_fde_unit);
     }
 }
-\f
+
+/* We must parse both .debug_frame section and .eh_frame because 
+ * not all frames must be present in both of these sections. */
+void
+dwarf2_build_frame_info (struct objfile *objfile)
+{
+  int after_debug_frame = 0;
+
+  /* If we have .debug_frame then the parser is called with 
+     eh_frame==0 for .debug_frame and eh_frame==2 for .eh_frame, 
+     otherwise it's only called once for .eh_frame with argument 
+     eh_frame==1.  */
+
+  if (dwarf_frame_offset)
+    {
+      parse_frame_info (objfile, dwarf_frame_offset,
+                       dwarf_frame_size, 0 /* = debug_frame */ );
+      after_debug_frame = 1;
+    }
+
+  if (dwarf_eh_frame_offset)
+    parse_frame_info (objfile, dwarf_eh_frame_offset, dwarf_eh_frame_size,
+                     1 /* = eh_frame */  + after_debug_frame);
+}
 
 /* Return the frame address.  */
 CORE_ADDR
@@ -1535,6 +1707,8 @@ cfi_read_fp ()
   struct frame_state *fs;
   CORE_ADDR cfa;
 
+  unwind_tmp_obstack_init ();
+
   context = context_alloc ();
   fs = frame_state_alloc ();
 
@@ -1544,7 +1718,9 @@ cfi_read_fp ()
   update_context (context, fs, 0);
 
   cfa = context->cfa;
+
   unwind_tmp_obstack_free ();
+
   return cfa;
 }
 
@@ -1556,6 +1732,8 @@ cfi_write_fp (CORE_ADDR val)
   struct context *context;
   struct frame_state *fs;
 
+  unwind_tmp_obstack_init ();
+
   context = context_alloc ();
   fs = frame_state_alloc ();
 
@@ -1603,6 +1781,8 @@ cfi_frame_chain (struct frame_info *fi)
   struct frame_state *fs;
   CORE_ADDR cfa;
 
+  unwind_tmp_obstack_init ();
+
   context = context_alloc ();
   fs = frame_state_alloc ();
   context_cpy (context, UNWIND_CONTEXT (fi));
@@ -1619,7 +1799,7 @@ cfi_frame_chain (struct frame_info *fi)
 
   cfa = context->cfa;
   unwind_tmp_obstack_free ();
-  
+
   return cfa;
 }
 
@@ -1639,6 +1819,8 @@ cfi_init_extra_frame_info (int fromleaf, struct frame_info *fi)
 {
   struct frame_state *fs;
 
+  unwind_tmp_obstack_init ();
+
   fs = frame_state_alloc ();
   fi->context = frame_obstack_alloc (sizeof (struct context));
   UNWIND_CONTEXT (fi)->reg =
@@ -1658,6 +1840,7 @@ cfi_init_extra_frame_info (int fromleaf, struct frame_info *fi)
       frame_state_for (UNWIND_CONTEXT (fi), fs);
       update_context (UNWIND_CONTEXT (fi), fs, 0);
     }
+
   unwind_tmp_obstack_free ();
 }
 
@@ -1678,7 +1861,7 @@ cfi_get_ra (struct frame_info *fi)
 void
 cfi_get_saved_register (char *raw_buffer,
                        int *optimized,
-                       CORE_ADDR * addrp,
+                       CORE_ADDR *addrp,
                        struct frame_info *frame,
                        int regnum, enum lval_type *lval)
 {
@@ -1765,6 +1948,8 @@ cfi_virtual_frame_pointer (CORE_ADDR pc, int *frame_reg,
   struct context *context;
   struct frame_state *fs;
 
+  unwind_tmp_obstack_init ();
+
   context = context_alloc ();
   fs = frame_state_alloc ();
 
index 2b75520059aab3346af130482827e5e25eb460d4..85129570169042a39d6e192a951c5dfc0ffe9c17 100644 (file)
@@ -1,3 +1,11 @@
+2002-07-03  Michal Ludvig  <mludvig@suse.cz>
+
+       Merge from mainline:
+
+       2002-06-06  Michal Ludvig  <mludvig@suse.cz>
+       * gdb.asm/asm-source.exp: Add x86-64 target.
+       * gdb.asm/x86_64.inc: New.
+
 2002-02-24  Andrew Cagney  <ac131313@redhat.com>
 
        * testsuite/gdb.base/huge.c: Replace ``Linux'' with either
index 471b31a6df6237147c92ba990803ee5872f53f47..c0d4914f6fec0f4f85fcb568c1b12c6d952494c4 100644 (file)
@@ -47,6 +47,10 @@ if [istarget "d10v-*-*"] then {
 if [istarget "s390-*-*"] then {
     set asm-arch s390
 }
+if [istarget "x86_64-*-*"] then {
+    set asm-arch x86_64
+    set asm-flags "-gdwarf2 -I${srcdir}/${subdir} -I${objdir}/${subdir}"
+}
 if [istarget "i\[3456\]86-*-*"] then {
     set asm-arch i386
 }
index fd70572752449c70f7a2dc2c386b665cca986cee..7749b415114819525aaf178dd8105d80eb66be00 100644 (file)
@@ -25,7 +25,6 @@
 #include "inferior.h"
 #include "gdbcore.h"
 #include "regcache.h"
-#include "i387-nat.h"
 #include "gdb_assert.h"
 #include "x86-64-tdep.h"
 
@@ -158,7 +157,7 @@ fill_gregset (elf_gregset_t * gregsetp, int regno)
 
   for (i = 0; i < x86_64_num_gregs; i++)
     if ((regno == -1 || regno == i))
-      read_register_gen (i, regp + x86_64_regmap[i]);
+      read_register_gen (i, (char *) (regp + x86_64_regmap[i]));
 }
 
 /* Fetch all general-purpose registers from process/thread TID and
@@ -195,23 +194,73 @@ store_regs (int tid, int regno)
 
 /* Transfering floating-point registers between GDB, inferiors and cores.  */
 
-/* Fill GDB's register array with the floating-point register values in
-   *FPREGSETP.  */
+static void *
+x86_64_fxsave_offset (elf_fpregset_t * fxsave, int regnum)
+{
+  const char *reg_name;
+  int reg_index;
+
+  gdb_assert (x86_64_num_gregs - 1 < regnum && regnum < x86_64_num_regs);
+
+  reg_name = x86_64_register_name (regnum);
+
+  if (reg_name[0] == 's' && reg_name[1] == 't')
+    {
+      reg_index = reg_name[2] - '0';
+      return &fxsave->st_space[reg_index * 2];
+    }
+
+  if (reg_name[0] == 'x' && reg_name[1] == 'm' && reg_name[2] == 'm')
+    {
+      reg_index = reg_name[3] - '0';
+      return &fxsave->xmm_space[reg_index * 4];
+    }
+
+  if (strcmp (reg_name, "mxcsr") == 0)
+    return &fxsave->mxcsr;
+
+  return NULL;
+}
+
+/* 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.  */
 
 void
-supply_fpregset (elf_fpregset_t * fpregsetp)
+supply_fpregset (elf_fpregset_t * fxsave)
 {
-  i387_supply_fxsave ((char *) fpregsetp);
+  int i, reg_st0, reg_mxcsr;
+
+  reg_st0 = x86_64_register_number ("st0");
+  reg_mxcsr = x86_64_register_number ("mxcsr");
+
+  gdb_assert (reg_st0 > 0 && reg_mxcsr > reg_st0);
+
+  for (i = reg_st0; i <= reg_mxcsr; i++)
+    supply_register (i, x86_64_fxsave_offset (fxsave, i));
 }
 
-/* Fill register REGNO (if it is a floating-point register) in
-   *FPREGSETP with the value in GDB's register array.  If REGNO is -1,
-   do this for all registers.  */
+/* 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
+   this for all registers.  This function doesn't touch any of the
+   reserved bits in *FXSAVE.  */
 
 void
-fill_fpregset (elf_fpregset_t * fpregsetp, int regno)
+fill_fpregset (elf_fpregset_t * fxsave, int regnum)
 {
-  i387_fill_fxsave ((char *) fpregsetp, regno);
+  int i, last_regnum = MXCSR_REGNUM;
+  void *ptr;
+
+  if (gdbarch_tdep (current_gdbarch)->num_xmm_regs == 0)
+    last_regnum = FOP_REGNUM;
+
+  for (i = FP0_REGNUM; i <= last_regnum; i++)
+    if (regnum == -1 || regnum == i)
+      {
+       ptr = x86_64_fxsave_offset (fxsave, i);
+       if (ptr)
+         regcache_collect (i, ptr);
+      }
 }
 
 /* Fetch all floating-point registers from process/thread TID and store
@@ -406,12 +455,6 @@ static struct core_fns linux_elf_core_fns = {
 #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
 #endif
 
-/* Record the value of the debug control register.  */
-static long debug_control_mirror;
-
-/* Record which address associates with which register.  */
-static CORE_ADDR address_lookup[DR_LASTADDR - DR_FIRSTADDR + 1];
-
 /* Return the address of register REGNUM.  BLOCKEND is the value of
    u.u_ar0, which should point to the registers.  */
 CORE_ADDR
@@ -446,4 +489,3 @@ kernel_u_size (void)
 {
   return (sizeof (struct user));
 }
-  
index 3ebc1b2594ab2acff0190166b3b9bca2f5e0e336..b1bb1477dd6a93ae362fdda3b518be8b31c0dfb1 100644 (file)
@@ -37,6 +37,7 @@
 #define RDX_REGNUM 3
 #define RDI_REGNUM 5
 #define EFLAGS_REGNUM 17
+#define ST0_REGNUM 22
 #define XMM1_REGNUM  39
 
 struct register_info
@@ -49,63 +50,90 @@ struct register_info
 /* x86_64_register_raw_size_table[i] is the number of bytes of storage in
    GDB's register array occupied by register i.  */
 static struct register_info x86_64_register_info_table[] = {
-  {8, "rax", &builtin_type_int64},
-  {8, "rbx", &builtin_type_int64},
-  {8, "rcx", &builtin_type_int64},
-  {8, "rdx", &builtin_type_int64},
-  {8, "rsi", &builtin_type_int64},
-  {8, "rdi", &builtin_type_int64},
-  {8, "rbp", &builtin_type_void_func_ptr},
-  {8, "rsp", &builtin_type_void_func_ptr},
-  {8, "r8", &builtin_type_int64},
-  {8, "r9", &builtin_type_int64},
-  {8, "r10", &builtin_type_int64},
-  {8, "r11", &builtin_type_int64},
-  {8, "r12", &builtin_type_int64},
-  {8, "r13", &builtin_type_int64},
-  {8, "r14", &builtin_type_int64},
-  {8, "r15", &builtin_type_int64},
-  {8, "rip", &builtin_type_void_func_ptr},
-  {4, "eflags", &builtin_type_int32},
-  {4, "ds", &builtin_type_int32},
-  {4, "es", &builtin_type_int32},
-  {4, "fs", &builtin_type_int32},
-  {4, "gs", &builtin_type_int32},
-  {10, "st0", &builtin_type_i387_ext},
-  {10, "st1", &builtin_type_i387_ext},
-  {10, "st2", &builtin_type_i387_ext},
-  {10, "st3", &builtin_type_i387_ext},
-  {10, "st4", &builtin_type_i387_ext},
-  {10, "st5", &builtin_type_i387_ext},
-  {10, "st6", &builtin_type_i387_ext},
-  {10, "st7", &builtin_type_i387_ext},
-  {4, "fctrl", &builtin_type_int32},
-  {4, "fstat", &builtin_type_int32},
-  {4, "ftag", &builtin_type_int32},
-  {4, "fiseg", &builtin_type_int32},
-  {4, "fioff", &builtin_type_int32},
-  {4, "foseg", &builtin_type_int32},
-  {4, "fooff", &builtin_type_int32},
-  {4, "fop", &builtin_type_int32},
-  {16, "xmm0", &builtin_type_v4sf},
-  {16, "xmm1", &builtin_type_v4sf},
-  {16, "xmm2", &builtin_type_v4sf},
-  {16, "xmm3", &builtin_type_v4sf},
-  {16, "xmm4", &builtin_type_v4sf},
-  {16, "xmm5", &builtin_type_v4sf},
-  {16, "xmm6", &builtin_type_v4sf},
-  {16, "xmm7", &builtin_type_v4sf},
-  {16, "xmm8", &builtin_type_v4sf},
-  {16, "xmm9", &builtin_type_v4sf},
-  {16, "xmm10", &builtin_type_v4sf},
-  {16, "xmm11", &builtin_type_v4sf},
-  {16, "xmm12", &builtin_type_v4sf},
-  {16, "xmm13", &builtin_type_v4sf},
-  {16, "xmm14", &builtin_type_v4sf},
-  {16, "xmm15", &builtin_type_v4sf},
-  {4, "mxcsr", &builtin_type_int32}
+  /*  0 */ {8, "rax", &builtin_type_int64},
+  /*  1 */ {8, "rbx", &builtin_type_int64},
+  /*  2 */ {8, "rcx", &builtin_type_int64},
+  /*  3 */ {8, "rdx", &builtin_type_int64},
+  /*  4 */ {8, "rsi", &builtin_type_int64},
+  /*  5 */ {8, "rdi", &builtin_type_int64},
+  /*  6 */ {8, "rbp", &builtin_type_void_func_ptr},
+  /*  7 */ {8, "rsp", &builtin_type_void_func_ptr},
+  /*  8 */ {8, "r8", &builtin_type_int64},
+  /*  9 */ {8, "r9", &builtin_type_int64},
+  /* 10 */ {8, "r10", &builtin_type_int64},
+  /* 11 */ {8, "r11", &builtin_type_int64},
+  /* 12 */ {8, "r12", &builtin_type_int64},
+  /* 13 */ {8, "r13", &builtin_type_int64},
+  /* 14 */ {8, "r14", &builtin_type_int64},
+  /* 15 */ {8, "r15", &builtin_type_int64},
+  /* 16 */ {8, "rip", &builtin_type_void_func_ptr},
+  /* 17 */ {4, "eflags", &builtin_type_int32},
+  /* 18 */ {4, "ds", &builtin_type_int32},
+  /* 19 */ {4, "es", &builtin_type_int32},
+  /* 20 */ {4, "fs", &builtin_type_int32},
+  /* 21 */ {4, "gs", &builtin_type_int32},
+  /* 22 */ {10, "st0", &builtin_type_i387_ext},
+  /* 23 */ {10, "st1", &builtin_type_i387_ext},
+  /* 24 */ {10, "st2", &builtin_type_i387_ext},
+  /* 25 */ {10, "st3", &builtin_type_i387_ext},
+  /* 26 */ {10, "st4", &builtin_type_i387_ext},
+  /* 27 */ {10, "st5", &builtin_type_i387_ext},
+  /* 28 */ {10, "st6", &builtin_type_i387_ext},
+  /* 29 */ {10, "st7", &builtin_type_i387_ext},
+  /* 30 */ {4, "fctrl", &builtin_type_int32},
+  /* 31 */ {4, "fstat", &builtin_type_int32},
+  /* 32 */ {4, "ftag", &builtin_type_int32},
+  /* 33 */ {4, "fiseg", &builtin_type_int32},
+  /* 34 */ {4, "fioff", &builtin_type_int32},
+  /* 35 */ {4, "foseg", &builtin_type_int32},
+  /* 36 */ {4, "fooff", &builtin_type_int32},
+  /* 37 */ {4, "fop", &builtin_type_int32},
+  /* 38 */ {16, "xmm0", &builtin_type_v4sf},
+  /* 39 */ {16, "xmm1", &builtin_type_v4sf},
+  /* 40 */ {16, "xmm2", &builtin_type_v4sf},
+  /* 41 */ {16, "xmm3", &builtin_type_v4sf},
+  /* 42 */ {16, "xmm4", &builtin_type_v4sf},
+  /* 43 */ {16, "xmm5", &builtin_type_v4sf},
+  /* 44 */ {16, "xmm6", &builtin_type_v4sf},
+  /* 45 */ {16, "xmm7", &builtin_type_v4sf},
+  /* 46 */ {16, "xmm8", &builtin_type_v4sf},
+  /* 47 */ {16, "xmm9", &builtin_type_v4sf},
+  /* 48 */ {16, "xmm10", &builtin_type_v4sf},
+  /* 49 */ {16, "xmm11", &builtin_type_v4sf},
+  /* 50 */ {16, "xmm12", &builtin_type_v4sf},
+  /* 51 */ {16, "xmm13", &builtin_type_v4sf},
+  /* 52 */ {16, "xmm14", &builtin_type_v4sf},
+  /* 53 */ {16, "xmm15", &builtin_type_v4sf},
+  /* 54 */ {4, "mxcsr", &builtin_type_int32}
 };
 
+/* This array is a mapping from Dwarf-2 register 
+   numbering to GDB's one. Dwarf-2 numbering is 
+   defined in x86-64 ABI, section 3.6.  */
+static int x86_64_dwarf2gdb_regno_map[] = {
+  0, 1, 2, 3,                  /* RAX - RDX */
+  4, 5, 6, 7,                  /* RSI, RDI, RBP, RSP */
+  8, 9, 10, 11,                        /* R8 - R11 */
+  12, 13, 14, 15,              /* R12 - R15 */
+  -1,                          /* RA - not mapped */
+  XMM1_REGNUM - 1, XMM1_REGNUM,        /* XMM0 ... */
+  XMM1_REGNUM + 1, XMM1_REGNUM + 2,
+  XMM1_REGNUM + 3, XMM1_REGNUM + 4,
+  XMM1_REGNUM + 5, XMM1_REGNUM + 6,
+  XMM1_REGNUM + 7, XMM1_REGNUM + 8,
+  XMM1_REGNUM + 9, XMM1_REGNUM + 10,
+  XMM1_REGNUM + 11, XMM1_REGNUM + 12,
+  XMM1_REGNUM + 13, XMM1_REGNUM + 14,  /* ... XMM15 */
+  ST0_REGNUM + 0, ST0_REGNUM + 1,      /* ST0 ... */
+  ST0_REGNUM + 2, ST0_REGNUM + 3,
+  ST0_REGNUM + 4, ST0_REGNUM + 5,
+  ST0_REGNUM + 6, ST0_REGNUM + 7       /* ... ST7 */
+};
+
+static int x86_64_dwarf2gdb_regno_map_length =
+  sizeof (x86_64_dwarf2gdb_regno_map) /
+  sizeof (x86_64_dwarf2gdb_regno_map[0]);
+
 /* Number of all registers */
 #define X86_64_NUM_REGS (sizeof (x86_64_register_info_table) / \
   sizeof (x86_64_register_info_table[0]))
@@ -167,7 +195,7 @@ x86_64_register_convert_to_virtual (int regnum, struct type *type,
                                    char *from, char *to)
 {
   char buf[12];
-  DOUBLEST d;
+
   /* We only support floating-point values.  */
   if (TYPE_CODE (type) != TYPE_CODE_FLT)
     {
@@ -198,6 +226,19 @@ x86_64_register_convert_to_raw (struct type *type, int regnum,
   memcpy (to, from, FPU_REG_RAW_SIZE);
 }
 
+/* Dwarf-2 <-> GDB register numbers mapping.  */
+int
+x86_64_dwarf2_reg_to_regnum (int dw_reg)
+{
+  if (dw_reg < 0 || dw_reg > x86_64_dwarf2gdb_regno_map_length)
+    {
+      warning ("Dwarf-2 uses unmapped register #%d\n", dw_reg);
+      return dw_reg;
+    }
+
+  return x86_64_dwarf2gdb_regno_map[dw_reg];
+}
+
 /* This is the variable that is set with "set disassembly-flavour", and
    its legitimate values.  */
 static const char att_flavour[] = "att";
@@ -331,18 +372,19 @@ classify_argument (struct type *type,
          case TYPE_CODE_STRUCT:
            {
              int j;
-             for (j = 0; j < type->nfields; ++j)
+             for (j = 0; j < TYPE_NFIELDS (type); ++j)
                {
-                 int num = classify_argument (type->fields[j].type,
+                 int num = classify_argument (TYPE_FIELDS (type)[j].type,
                                               subclasses,
-                                              (type->fields[j].loc.bitpos
-                                               + bit_offset) % 256);
+                                              (TYPE_FIELDS (type)[j].loc.
+                                               bitpos + bit_offset) % 256);
                  if (!num)
                    return 0;
                  for (i = 0; i < num; i++)
                    {
                      int pos =
-                       (type->fields[j].loc.bitpos + bit_offset) / 8 / 8;
+                       (TYPE_FIELDS (type)[j].loc.bitpos +
+                        bit_offset) / 8 / 8;
                      classes[i + pos] =
                        merge_classes (subclasses[i], classes[i + pos]);
                    }
@@ -353,7 +395,7 @@ classify_argument (struct type *type,
            {
              int num;
 
-             num = classify_argument (type->target_type,
+             num = classify_argument (TYPE_TARGET_TYPE (type),
                                       subclasses, bit_offset);
              if (!num)
                return 0;
@@ -372,10 +414,10 @@ classify_argument (struct type *type,
            {
              int j;
              {
-               for (j = 0; j < type->nfields; ++j)
+               for (j = 0; j < TYPE_NFIELDS (type); ++j)
                  {
                    int num;
-                   num = classify_argument (type->fields[j].type,
+                   num = classify_argument (TYPE_FIELDS (type)[j].type,
                                             subclasses, bit_offset);
                    if (!num)
                      return 0;
@@ -385,6 +427,8 @@ classify_argument (struct type *type,
              }
            }
            break;
+         default:
+           break;
          }
        /* Final merger cleanup.  */
        for (i = 0; i < words; i++)
@@ -447,6 +491,8 @@ classify_argument (struct type *type,
        }
     case TYPE_CODE_VOID:
       return 0;
+    default:                   /* Avoid warning.  */
+      break;
     }
   internal_error (__FILE__, __LINE__,
                  "classify_argument: unknown argument type");
@@ -609,7 +655,7 @@ x86_64_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
   static int int_parameter_registers[INT_REGS] = {
     5 /* RDI */ , 4 /* RSI */ ,
     3 /* RDX */ , 2 /* RCX */ ,
-    8 /* R8  */ , 9 /* R9  */
+    8 /* R8  */ , 9            /* R9  */
   };
   /* XMM0 - XMM15  */
   static int sse_parameter_registers[SSE_REGS] = {
@@ -752,13 +798,24 @@ x86_64_store_return_value (struct type *type, char *valbuf)
 }
 \f
 
-static char *
+char *
 x86_64_register_name (int reg_nr)
 {
   if (reg_nr < 0 || reg_nr >= X86_64_NUM_REGS)
     return NULL;
   return x86_64_register_info_table[reg_nr].name;
 }
+
+int
+x86_64_register_number (const char *name)
+{
+  int reg_nr;
+
+  for (reg_nr = 0; reg_nr < X86_64_NUM_REGS; reg_nr++)
+    if (strcmp (name, x86_64_register_info_table[reg_nr].name) == 0)
+      return reg_nr;
+  return -1;
+}
 \f
 
 
@@ -800,10 +857,10 @@ x86_64_frameless_function_invocation (struct frame_info *frame)
 CORE_ADDR
 x86_64_skip_prologue (CORE_ADDR pc)
 {
-  int i, firstline, currline;
+  int i;
   struct symtab_and_line v_sal;
   struct symbol *v_function;
-  CORE_ADDR salendaddr = 0, endaddr = 0;
+  CORE_ADDR endaddr;
 
   /* We will handle only functions beginning with:
      55          pushq %rbp
@@ -817,7 +874,7 @@ x86_64_skip_prologue (CORE_ADDR pc)
   /* First check, whether pc points to pushq %rbp, movq %rsp,%rbp.  */
   for (i = 0; i < PROLOG_BUFSIZE; i++)
     if (prolog_expect[i] != prolog_buf[i])
-      return pc;       /* ... no, it doesn't. Nothing to skip.  */
+      return pc;               /* ... no, it doesn't. Nothing to skip.  */
 
   /* OK, we have found the prologue and want PC of the first 
      non-prologue instruction.  */
@@ -831,18 +888,13 @@ x86_64_skip_prologue (CORE_ADDR pc)
   if (!v_function || !v_function->ginfo.value.block || !v_sal.symtab)
     return pc;
 
-  firstline = v_sal.line;
-  currline = firstline;
-  salendaddr = v_sal.end;
   endaddr = v_function->ginfo.value.block->endaddr;
 
   for (i = 0; i < v_sal.symtab->linetable->nitems; i++)
-    if (v_sal.symtab->linetable->item[i].line > firstline
-       && v_sal.symtab->linetable->item[i].pc >= salendaddr
+    if (v_sal.symtab->linetable->item[i].pc >= pc
        && v_sal.symtab->linetable->item[i].pc < endaddr)
       {
        pc = v_sal.symtab->linetable->item[i].pc;
-       currline = v_sal.symtab->linetable->item[i].line;
        break;
       }
 
@@ -859,7 +911,7 @@ x86_64_breakpoint_from_pc (CORE_ADDR * pc, int *lenptr)
 }
 
 static struct gdbarch *
-i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+x86_64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
   struct gdbarch *gdbarch;
   struct gdbarch_tdep *tdep;
@@ -885,7 +937,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
              break;
            default:
              internal_error (__FILE__, __LINE__,
-                             "i386_gdbarch_init: unknown machine type");
+                             "x86_64_gdbarch_init: unknown machine type");
            }
          break;
        case bfd_mach_i386_i386:
@@ -902,12 +954,12 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
              return arches->gdbarch;
            default:
              internal_error (__FILE__, __LINE__,
-                             "i386_gdbarch_init: unknown machine type");
+                             "x86_64_gdbarch_init: unknown machine type");
            }
          break;
        default:
          internal_error (__FILE__, __LINE__,
-                         "i386_gdbarch_init: unknown machine type");
+                         "x86_64_gdbarch_init: unknown machine type");
        }
     }
 
@@ -927,7 +979,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       break;
     default:
       internal_error (__FILE__, __LINE__,
-                     "i386_gdbarch_init: unknown machine type");
+                     "x86_64_gdbarch_init: unknown machine type");
     }
 
   set_gdbarch_long_bit (gdbarch, 64);
@@ -967,7 +1019,6 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_fp0_regnum (gdbarch, X86_64_NUM_GREGS);  /* First FPU floating-point register.  */
 
   set_gdbarch_read_fp (gdbarch, cfi_read_fp);
-  set_gdbarch_write_fp (gdbarch, cfi_write_fp);
 
 /* Discard from the stack the innermost frame, restoring all registers.  */
   set_gdbarch_pop_frame (gdbarch, x86_64_pop_frame);
@@ -1056,7 +1107,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
 
-  set_gdbarch_breakpoint_from_pc (gdbarch, x86_64_breakpoint_from_pc);
+  set_gdbarch_breakpoint_from_pc (gdbarch,
+                                 (gdbarch_breakpoint_from_pc_ftype *)
+                                 x86_64_breakpoint_from_pc);
 
 
 /* Amount PC must be decremented by after a breakpoint.  This is often the
@@ -1065,13 +1118,15 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
 /* Use dwarf2 debug frame informations.  */
   set_gdbarch_dwarf2_build_frame_info (gdbarch, dwarf2_build_frame_info);
+  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, x86_64_dwarf2_reg_to_regnum);
+
   return gdbarch;
 }
 
 void
 _initialize_x86_64_tdep (void)
 {
-  register_gdbarch_init (bfd_arch_i386, i386_gdbarch_init);
+  register_gdbarch_init (bfd_arch_i386, x86_64_gdbarch_init);
 
   /* Initialize the table saying where each register starts in the
      register file.  */
index d15b8e71e7f0365f8a8fde26d6806cb6f0442814..edbfdf36f75fe8bed986a7bf23dddcf43421b4ff 100644 (file)
 extern int x86_64_num_regs;
 extern int x86_64_num_gregs;
 
+int x86_64_register_number (const char *name);
+char *x86_64_register_name (int reg_nr);
+       
+
 gdbarch_frame_saved_pc_ftype x86_64_linux_frame_saved_pc;
 gdbarch_saved_pc_after_call_ftype x86_64_linux_saved_pc_after_call;