This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[commit] Handle two quirks of RealView DWARF


This patch handles two known issues in the DWARF produced by RealView:

* It never emits DW_AT_prototyped.  So, GDB concludes all C functions
are unprototyped.  No matter which way we try this, we're going to get
some cases wrong and need XFAILs... but I think it makes a lot more
sense to default to prototyped for this compiler, and any other future
compiler with the same problem.  So I have xfailed the tests relating
to passing doubles to unprototyped functions.

* It does not emit DW_AT_declaration on incomplete structure types.
The standard does require this, but from the lack of a DW_AT_byte_size
it's possible to make a pretty reliable guess as to which types are
incomplete.

One note on the use of producer strings for this.  It's not elegant,
but it's practical.  I've heard from other debugger developers (on the
dwarf-discuss list) that this is a common practice.  I think that the
role of the debugger should be to parse "DWARF as emitted by the known
compiler".  Of course, since we're part of the GNU project and so is
GCC, the situation with GCC is different; there, I think we should add
workarounds as necessary for widely deployed compilers, but only after
fixing or at least reporting the issue to the GCC developers.

Tested on arm-eabi with no regressions; checked in.

-- 
Daniel Jacobowitz
CodeSourcery

2010-03-24  Daniel Jacobowitz  <dan@codesourcery.com>

	gdb/
	* dwarf2-frame.c (dwarf2_frame_find_quirks): Use producer_is_realview.
	* dwarf2read.c (load_full_comp_unit): Read DW_AT_producer.
	(read_structure_type): For RealView, set TYPE_STUB on structures with
	no byte size and no children.
	(read_subroutine_type): Mark functions as prototyped by default.
	* symtab.c (producer_is_realview): New function.
	* symtab.h (expand_line_sal): Fix declaration formatting.
	(producer_is_realview): Declare.

	gdb/testsuite/
	* gdb.base/callfuncs.exp (do_function_calls): Add XFAILs for RealView.
	* gdb.base/ptype.exp (ptype_maybe_prototyped): Add overprototyped
	argument.  Handle "short" and "long".
	(Top level): Pass overprototyped output for old_fptr and xptr.

---
 gdb/dwarf2-frame.c                   |   48 +++++++++++++----------------------
 gdb/dwarf2read.c                     |   17 ++++++++++++
 gdb/symtab.c                         |   25 ++++++++++++++++++
 gdb/symtab.h                         |    7 +++--
 gdb/testsuite/gdb.base/callfuncs.exp |    6 ++++
 gdb/testsuite/gdb.base/ptype.exp     |   28 ++++++++++++++++----
 6 files changed, 94 insertions(+), 37 deletions(-)

Index: gdb-mainline/gdb/dwarf2-frame.c
===================================================================
--- gdb-mainline.orig/gdb/dwarf2-frame.c	2010-03-24 12:39:17.000000000 -0700
+++ gdb-mainline/gdb/dwarf2-frame.c	2010-03-24 13:42:54.000000000 -0700
@@ -839,43 +839,33 @@ 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)
+  if (s == 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 (producer_is_realview (s->producer))
+    {
+      if (fde->cie->version == 1)
+	fs->armcc_cfa_offsets_sf = 1;
 
-	if (fde->cie->version == 1)
-	  fs->armcc_cfa_offsets_reversed = 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;
+      /* 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;
-      }
+      return;
+    }
 }
 
 
Index: gdb-mainline/gdb/dwarf2read.c
===================================================================
--- gdb-mainline.orig/gdb/dwarf2read.c	2010-03-24 12:39:17.000000000 -0700
+++ gdb-mainline/gdb/dwarf2read.c	2010-03-24 13:42:54.000000000 -0700
@@ -3072,6 +3072,12 @@ load_full_comp_unit (struct dwarf2_per_c
   else
     set_cu_language (language_minimal, cu);
 
+  /* Similarly, if we do not read the producer, we can not apply
+     producer-specific interpretation.  */
+  attr = dwarf2_attr (cu->dies, DW_AT_producer, cu);
+  if (attr)
+    cu->producer = DW_STRING (attr);
+
   /* Link this CU into read_in_chain.  */
   per_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
   dwarf2_per_objfile->read_in_chain = per_cu;
@@ -5071,6 +5077,11 @@ read_structure_type (struct die_info *di
   TYPE_STUB_SUPPORTED (type) = 1;
   if (die_is_declaration (die, cu))
     TYPE_STUB (type) = 1;
+  else if (attr == NULL && die->child == NULL
+	   && producer_is_realview (cu->producer))
+    /* RealView does not output the required DW_AT_declaration
+       on incomplete types.  */
+    TYPE_STUB (type) = 1;
 
   set_descriptive_type (type, die, cu);
 
@@ -5869,6 +5880,12 @@ read_subroutine_type (struct die_info *d
       || cu->language == language_java
       || cu->language == language_pascal)
     TYPE_PROTOTYPED (ftype) = 1;
+  else if (producer_is_realview (cu->producer))
+    /* RealView does not emit DW_AT_prototyped.  We can not
+       distinguish prototyped and unprototyped functions; default to
+       prototyped, since that is more common in modern code (and
+       RealView warns about unprototyped functions).  */
+    TYPE_PROTOTYPED (ftype) = 1;
 
   /* Store the calling convention in the type if it's available in
      the subroutine die.  Otherwise set the calling convention to
Index: gdb-mainline/gdb/symtab.c
===================================================================
--- gdb-mainline.orig/gdb/symtab.c	2010-03-24 12:39:17.000000000 -0700
+++ gdb-mainline/gdb/symtab.c	2010-03-24 13:42:54.000000000 -0700
@@ -4424,6 +4424,31 @@ expand_line_sal (struct symtab_and_line 
   return ret;
 }
 
+/* Return 1 if the supplied producer string matches the ARM RealView
+   compiler (armcc).  */
+
+int
+producer_is_realview (const char *producer)
+{
+  static const char *const arm_idents[] = {
+    "ARM C Compiler, ADS",
+    "Thumb C Compiler, ADS",
+    "ARM C++ Compiler, ADS",
+    "Thumb C++ Compiler, ADS",
+    "ARM/Thumb C/C++ Compiler, RVCT",
+    "ARM C/C++ Compiler, RVCT"
+  };
+  int i;
+
+  if (producer == NULL)
+    return 0;
+
+  for (i = 0; i < ARRAY_SIZE (arm_idents); i++)
+    if (strncmp (producer, arm_idents[i], strlen (arm_idents[i])) == 0)
+      return 1;
+
+  return 0;
+}
 
 void
 _initialize_symtab (void)
Index: gdb-mainline/gdb/symtab.h
===================================================================
--- gdb-mainline.orig/gdb/symtab.h	2010-03-24 12:39:17.000000000 -0700
+++ gdb-mainline/gdb/symtab.h	2010-03-24 13:42:54.000000000 -0700
@@ -1198,8 +1198,11 @@ struct symbol *lookup_global_symbol_from
 						  const char *name,
 						  const domain_enum domain);
 
-extern struct symtabs_and_lines
-expand_line_sal (struct symtab_and_line sal);
+extern struct symtabs_and_lines expand_line_sal (struct symtab_and_line sal);
+
+/* Return 1 if the supplied producer string matches the ARM RealView
+   compiler (armcc).  */
+int producer_is_realview (const char *producer);
 
 void fixup_section (struct general_symbol_info *ginfo,
 		    CORE_ADDR addr, struct objfile *objfile);
Index: gdb-mainline/gdb/testsuite/gdb.base/callfuncs.exp
===================================================================
--- gdb-mainline.orig/gdb/testsuite/gdb.base/callfuncs.exp	2010-03-24 13:46:24.000000000 -0700
+++ gdb-mainline/gdb/testsuite/gdb.base/callfuncs.exp	2010-03-24 13:46:34.000000000 -0700
@@ -129,13 +129,19 @@ proc do_function_calls {} {
 	# Gcc emits different stabs for the two parameters; the first is
 	# claimed to be a float, the second a double.
 	# dbxout.c in gcc claims this is the desired behavior.
+	# These tests also fail for RealView, because GDB can not tell that
+	# the function is unprototyped.
 	setup_xfail "mn10300-*-*"
+	if { [test_compiler_info "armcc-*"] } { setup_xfail "*-*-*" }
 	gdb_test "p t_float_values(3.14159,-2.3765)" " = 1"
 	setup_xfail "mn10300-*-*"
+	if { [test_compiler_info "armcc-*"] } { setup_xfail "*-*-*" }
 	gdb_test "p t_float_values(float_val1,float_val2)" " = 1"
 	setup_xfail "mn10300-*-*"
+	if { [test_compiler_info "armcc-*"] } { setup_xfail "*-*-*" }
 	gdb_test "p t_float_values(3.14159,float_val2)" " = 1"
 	setup_xfail "mn10300-*-*"
+	if { [test_compiler_info "armcc-*"] } { setup_xfail "*-*-*" }
 	gdb_test "p t_float_values(float_val1,-2.3765)" " = 1"
 
 	# Test passing of arguments which might not be widened.
Index: gdb-mainline/gdb/testsuite/gdb.base/ptype.exp
===================================================================
--- gdb-mainline.orig/gdb/testsuite/gdb.base/ptype.exp	2010-03-24 13:46:24.000000000 -0700
+++ gdb-mainline/gdb/testsuite/gdb.base/ptype.exp	2010-03-24 13:46:34.000000000 -0700
@@ -555,15 +555,23 @@ get_debug_format
 #   generated by GCC, that's an xfail; as of 9 Feb 2002, GCC never emits
 #   prototyped function types in STABS.  Like PROTOTYPED, PLAIN is a
 #   literal string, not a regular expression.
+# - If we see OVERPROTOTYPED, it's an xfail for RealView; RealView
+#   does not distinguish prototyped and unprototyped functions, and
+#   GDB defaults to prototyped.
 # - Otherwise, it's a failure.
-proc ptype_maybe_prototyped { id prototyped plain } {
+proc ptype_maybe_prototyped { id prototyped plain { overprototyped "NO-MATCH" } } {
     global gdb_prompt
     global gcc_compiled
 
-    # Turn `prototyped' and `plain', which are literal strings, into
+    # Turn the arguments, which are literal strings, into
     # regular expressions by quoting any special characters they contain.
-    regsub -all "\[\]\[*()\]" $prototyped "\\\\&" prototyped
-    regsub -all "\[\]\[*()\]" $plain "\\\\&" plain
+    foreach var { prototyped plain overprototyped } {
+	eval "set val \$$var"
+	regsub -all "\[\]\[*()\]" $val "\\\\&" val
+	regsub -all "short int" $val "short( int)?" val
+	regsub -all "long int" $val "long( int)?" val
+	eval "set $var \$val"
+    }
 
     send_gdb "ptype $id\n"
     gdb_expect {
@@ -574,6 +582,12 @@ proc ptype_maybe_prototyped { id prototy
             if {$gcc_compiled} { setup_xfail_format "stabs" }
             fail "ptype $id (compiler doesn't emit prototyped types)"
         }
+        -re "type = $overprototyped\[\r\n\]+$gdb_prompt $" {
+            if { [test_compiler_info "armcc-*"] } {
+		setup_xfail "*-*-*"
+	    }
+            fail "ptype $id (compiler doesn't emit unprototyped types)"
+        }
         -re "$gdb_prompt $" {
             fail "ptype $id"
         }
@@ -585,13 +599,15 @@ proc ptype_maybe_prototyped { id prototy
 
 ptype_maybe_prototyped "func_type" "int (*)(int (*)(int, float), float)" \
                                    "int (*)()"
-ptype_maybe_prototyped "old_fptr" "double (*)()" "double (*)()"
+ptype_maybe_prototyped "old_fptr" "double (*)()" "double (*)()" \
+                                  "double (*)(void)"
 ptype_maybe_prototyped "new_fptr" "double (*)(void)" "double (*)()"
 ptype_maybe_prototyped "fptr" "int (*)(int, float)" "int (*)()"
 ptype_maybe_prototyped "fptr2" "int *(*)(int (*)(int, float), float)" \
                                "int *(*)()"
 ptype_maybe_prototyped "xptr" "int (*)(int (*)(), int (*)(void), int)" \
-                              "int (*)()"
+                              "int (*)()" \
+                              "int (*)(int (*)(void), int (*)(void), int)"
 ptype_maybe_prototyped "ffptr" "int (*(*)(char))(short int)" \
                                "int (*(*)())()"
 ptype_maybe_prototyped "fffptr" "int (*(*(*)(char))(short int))(long int)" \


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]