* buildsym.c (start_subfile): Handle producer.
authorDaniel Jacobowitz <drow@false.org>
Thu, 4 Jan 2007 20:26:42 +0000 (20:26 +0000)
committerDaniel Jacobowitz <drow@false.org>
Thu, 4 Jan 2007 20:26:42 +0000 (20:26 +0000)
(record_producer): New function.
* buildsym.h (struct subfile): Include producer.
(record_producer): New prototype.
* dwarf2-frame.c (struct dwarf2_cie): Add version and augmentation.
(struct dwarf2_frame_state): Add armcc_cfa_offsets_sf and
armcc_cfa_offsets_reversed.
(execute_cfa_program): Handle armcc_cfa_offsets_sf.
(dwarf2_frame_find_quirks): New function.
(dwarf2_frame_cache): Call it.  Handle armcc_cfa_offsets_reversed.
(decode_frame_entry_1): Record the CIE version.  Record the
augmentation.  Skip armcc augmentations.
* dwarf2read.c (read_file_scope): Save the producer.
* symtab.h (struct symtab): Rename unused version member to
producer.

gdb/ChangeLog
gdb/buildsym.c
gdb/buildsym.h
gdb/dwarf2-frame.c
gdb/dwarf2read.c
gdb/symtab.h
gdb/testsuite/ChangeLog

index ed80928..029330a 100644 (file)
@@ -1,16 +1,20 @@
-2007-01-04  Vladimir Prus  <vladimir@codesourcery.com>
+2007-01-04  Daniel Jacobowitz  <dan@codesourcery.com>
 
-       Implement specification of MI tests as comments
-       in C and C++ sources.
-       * lib/mi-support.exp (mi_autotest_data): New variable.
-       (mi_autotest_source): New variable.
-       (count_newlines, mi_prepare_inline_tests)
-       (mi_get_inline_test, mi_continue_to_line)
-       (mi_run_inline_test, mi_tbreak)
-       (mi_send_resuming_command, mi_wait_for_stop): New functions.
-       * gdb.mi/mi-var-cp.exp: Move most content to the C file.
-       Run inline tests.
-       * gdb.mi/mi-var-cp.cc: Define tests here.
+       * buildsym.c (start_subfile): Handle producer.
+       (record_producer): New function.
+       * buildsym.h (struct subfile): Include producer.
+       (record_producer): New prototype.
+       * dwarf2-frame.c (struct dwarf2_cie): Add version and augmentation.
+       (struct dwarf2_frame_state): Add armcc_cfa_offsets_sf and
+       armcc_cfa_offsets_reversed.
+       (execute_cfa_program): Handle armcc_cfa_offsets_sf.
+       (dwarf2_frame_find_quirks): New function.
+       (dwarf2_frame_cache): Call it.  Handle armcc_cfa_offsets_reversed.
+       (decode_frame_entry_1): Record the CIE version.  Record the
+       augmentation.  Skip armcc augmentations.
+       * dwarf2read.c (read_file_scope): Save the producer.
+       * symtab.h (struct symtab): Rename unused version member to
+       producer.
 
 2007-01-04  Daniel Jacobowitz  <dan@codesourcery.com>
 
index 2e946b9..ab6fff3 100644 (file)
@@ -596,6 +596,9 @@ start_subfile (char *name, char *dirname)
      later via a call to record_debugformat. */
   subfile->debugformat = NULL;
 
+  /* Similarly for the producer.  */
+  subfile->producer = NULL;
+
   /* If the filename of this subfile ends in .C, then change the
      language of any pending subfiles from C to C++.  We also accept
      any other C++ suffixes accepted by deduce_language_from_filename.  */
@@ -1004,6 +1007,12 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
                                                  &objfile->objfile_obstack);
            }
 
+         /* Similarly for the producer.  */
+         if (subfile->producer != NULL)
+           symtab->producer = obsavestring (subfile->producer,
+                                            strlen (subfile->producer),
+                                            &objfile->objfile_obstack);
+
          /* All symtabs for the main file and the subfiles share a
             blockvector, so we need to clear primary for everything
             but the main file.  */
@@ -1026,6 +1035,8 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
        {
          xfree ((void *) subfile->debugformat);
        }
+      if (subfile->producer != NULL)
+       xfree (subfile->producer);
 
       nextsub = subfile->next;
       xfree ((void *) subfile);
@@ -1102,6 +1113,12 @@ record_debugformat (char *format)
   current_subfile->debugformat = savestring (format, strlen (format));
 }
 
+void
+record_producer (const char *producer)
+{
+  current_subfile->producer = savestring (producer, strlen (producer));
+}
+
 /* Merge the first symbol list SRCLIST into the second symbol list
    TARGETLIST by repeated calls to add_symbol_to_list().  This
    procedure "frees" each link of SRCLIST by adding it to the
index 8b8ee89..3b4fee6 100644 (file)
@@ -68,6 +68,7 @@ struct subfile
     struct linetable *line_vector;
     int line_vector_length;
     enum language language;
+    char *producer;
     char *debugformat;
   };
 
@@ -281,6 +282,8 @@ extern void record_pending_block (struct objfile *objfile,
 
 extern void record_debugformat (char *format);
 
+extern void record_producer (const char *producer);
+
 extern void merge_symbol_lists (struct pending **srclist,
                                struct pending **targetlist);
 
index 861e19d..2f3751b 100644 (file)
@@ -64,6 +64,9 @@ struct dwarf2_cie
   gdb_byte *initial_instructions;
   gdb_byte *end;
 
+  /* Saved augmentation, in case it's needed later.  */
+  char *augmentation;
+
   /* Encoding of addresses.  */
   gdb_byte encoding;
 
@@ -73,6 +76,9 @@ struct dwarf2_cie
   /* True if an 'S' augmentation existed.  */
   unsigned char signal_frame;
 
+  /* The version recorded in the CIE.  */
+  unsigned char version;
+
   struct dwarf2_cie *next;
 };
 
@@ -138,6 +144,16 @@ struct dwarf2_frame_state
   LONGEST data_align;
   ULONGEST code_align;
   ULONGEST retaddr_column;
+
+  /* Flags for known producer quirks.  */
+
+  /* The ARM compilers, in DWARF2 mode, assume that DW_CFA_def_cfa
+     and DW_CFA_def_cfa_offset takes a factored offset.  */
+  int armcc_cfa_offsets_sf;
+
+  /* The ARM compilers, in DWARF2 or DWARF3 mode, may assume that
+     the CFA is defined as REG - OFFSET rather than REG + OFFSET.  */
+  int armcc_cfa_offsets_reversed;
 };
 
 /* Store the length the expression for the CFA in the `cfa_reg' field,
@@ -430,6 +446,10 @@ bad CFI data; mismatched DW_CFA_restore_state at 0x%s"), paddr (fs->pc));
            case DW_CFA_def_cfa:
              insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->cfa_reg);
              insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
+
+             if (fs->armcc_cfa_offsets_sf)
+               utmp *= fs->data_align;
+
              fs->cfa_offset = utmp;
              fs->cfa_how = CFA_REG_OFFSET;
              break;
@@ -444,6 +464,10 @@ bad CFI data; mismatched DW_CFA_restore_state at 0x%s"), paddr (fs->pc));
 
            case DW_CFA_def_cfa_offset:
              insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
+
+             if (fs->armcc_cfa_offsets_sf)
+               utmp *= fs->data_align;
+
              fs->cfa_offset = utmp;
              /* cfa_how deliberately not set.  */
              break;
@@ -715,6 +739,49 @@ dwarf2_frame_eh_frame_regnum (struct gdbarch *gdbarch, int regnum)
     return regnum;
   return ops->eh_frame_regnum (gdbarch, regnum);
 }
+
+static void
+dwarf2_frame_find_quirks (struct dwarf2_frame_state *fs,
+                         struct dwarf2_fde *fde)
+{
+  static const char *arm_idents[] = {
+    "ARM C Compiler, ADS",
+    "Thumb C Compiler, ADS",
+    "ARM C++ Compiler, ADS",
+    "Thumb C++ Compiler, ADS",
+    "ARM/Thumb C/C++ Compiler, RVCT"
+  };
+  int i;
+
+  struct symtab *s;
+
+  s = find_pc_symtab (fs->pc);
+  if (s == NULL || s->producer == NULL)
+    return;
+
+  for (i = 0; i < ARRAY_SIZE (arm_idents); i++)
+    if (strncmp (s->producer, arm_idents[i], strlen (arm_idents[i])) == 0)
+      {
+       if (fde->cie->version == 1)
+         fs->armcc_cfa_offsets_sf = 1;
+
+       if (fde->cie->version == 1)
+         fs->armcc_cfa_offsets_reversed = 1;
+
+       /* The reversed offset problem is present in some compilers
+          using DWARF3, but it was eventually fixed.  Check the ARM
+          defined augmentations, which are in the format "armcc" followed
+          by a list of one-character options.  The "+" option means
+          this problem is fixed (no quirk needed).  If the armcc
+          augmentation is missing, the quirk is needed.  */
+       if (fde->cie->version == 3
+           && (strncmp (fde->cie->augmentation, "armcc", 5) != 0
+               || strchr (fde->cie->augmentation + 5, '+') == NULL))
+         fs->armcc_cfa_offsets_reversed = 1;
+
+       return;
+      }
+}
 \f
 
 struct dwarf2_frame_cache
@@ -781,6 +848,9 @@ dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache)
   fs->code_align = fde->cie->code_alignment_factor;
   fs->retaddr_column = fde->cie->return_address_register;
 
+  /* Check for "quirks" - known bugs in producers.  */
+  dwarf2_frame_find_quirks (fs, fde);
+
   /* First decode all the insns in the CIE.  */
   execute_cfa_program (fde->cie->initial_instructions,
                       fde->cie->end, next_frame, fs, fde->eh_frame_p);
@@ -798,7 +868,10 @@ dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache)
     {
     case CFA_REG_OFFSET:
       cache->cfa = read_reg (next_frame, fs->cfa_reg);
-      cache->cfa += fs->cfa_offset;
+      if (fs->armcc_cfa_offsets_reversed)
+       cache->cfa -= fs->cfa_offset;
+      else
+       cache->cfa += fs->cfa_offset;
       break;
 
     case CFA_EXP:
@@ -1584,12 +1657,18 @@ decode_frame_entry_1 (struct comp_unit *unit, gdb_byte *start, int eh_frame_p)
       cie_version = read_1_byte (unit->abfd, buf);
       if (cie_version != 1 && cie_version != 3)
        return NULL;
+      cie->version = cie_version;
       buf += 1;
 
       /* Interpret the interesting bits of the augmentation.  */
-      augmentation = (char *) buf;
+      cie->augmentation = augmentation = (char *) buf;
       buf += (strlen (augmentation) + 1);
 
+      /* Ignore armcc augmentations.  We only use them for quirks,
+        and that doesn't happen until later.  */
+      if (strncmp (augmentation, "armcc", 5) == 0)
+       augmentation += strlen (augmentation);
+
       /* The GCC 2.x "eh" augmentation has a pointer immediately
          following the augmentation string, so it must be handled
          first.  */
index 3dcf436..9059189 100644 (file)
@@ -2803,16 +2803,9 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
   attr = dwarf2_attr (die, DW_AT_producer, cu);
   if (attr) 
     cu->producer = DW_STRING (attr);
-  
+
   /* We assume that we're processing GCC output. */
   processing_gcc_compilation = 2;
-#if 0
-  /* FIXME:Do something here.  */
-  if (dip->at_producer != NULL)
-    {
-      handle_producer (dip->at_producer);
-    }
-#endif
 
   /* The compilation unit may be in a different language or objfile,
      zero out all remembered fundamental types.  */
@@ -2820,6 +2813,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
 
   start_symtab (name, comp_dir, lowpc);
   record_debugformat ("DWARF 2");
+  record_producer (cu->producer);
 
   initialize_cu_func_list (cu);
 
index 4a980c1..1d72c84 100644 (file)
@@ -846,9 +846,9 @@ struct symtab
 
   char *debugformat;
 
-  /* String of version information.  May be zero.  */
+  /* String of producer version information.  May be zero.  */
 
-  char *version;
+  char *producer;
 
   /* Full name of file as found by searching the source path.
      NULL if not yet known.  */
index 9b4fe7e..b68951b 100644 (file)
@@ -1,3 +1,17 @@
+2007-01-04  Vladimir Prus  <vladimir@codesourcery.com>
+
+       Implement specification of MI tests as comments
+       in C and C++ sources.
+       * lib/mi-support.exp (mi_autotest_data): New variable.
+       (mi_autotest_source): New variable.
+       (count_newlines, mi_prepare_inline_tests)
+       (mi_get_inline_test, mi_continue_to_line)
+       (mi_run_inline_test, mi_tbreak)
+       (mi_send_resuming_command, mi_wait_for_stop): New functions.
+       * gdb.mi/mi-var-cp.exp: Move most content to the C file.
+       Run inline tests.
+       * gdb.mi/mi-var-cp.cc: Define tests here.
+
 2006-01-04  Joel Brobecker  <brobecker@adacore.com>
 
        Make this testcase a bit more realistic. The current code