This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[commit] Handle two quirks of RealView DWARF
- From: Daniel Jacobowitz <dan at codesourcery dot com>
- To: gdb-patches at sourceware dot org
- Date: Wed, 24 Mar 2010 17:11:43 -0400
- Subject: [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)" \