aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2read.c
diff options
context:
space:
mode:
authorJan Kratochvil <jan.kratochvil@redhat.com>2011-10-09 19:23:41 +0000
committerJan Kratochvil <jan.kratochvil@redhat.com>2011-10-09 19:23:41 +0000
commitbb984ff154d9e532deccdb52b3527496852c5930 (patch)
tree713649ab6d268f6ec6d4d18fb752efab6df73ac3 /gdb/dwarf2read.c
parent8e3b41a9061833aa9dc504d68e7446bca4984f16 (diff)
downloadgdb-bb984ff154d9e532deccdb52b3527496852c5930.zip
gdb-bb984ff154d9e532deccdb52b3527496852c5930.tar.gz
gdb-bb984ff154d9e532deccdb52b3527496852c5930.tar.bz2
gdb/
Tail call sites reader implementation. * dwarf2read.c (read_call_site_scope): Recognize DW_AT_GNU_tail_call, fill in TYPE_TAIL_CALL_LIST. * gdbtypes.h (struct func_type): New field tail_call_list. (struct call_site): New field tail_call_next. (TYPE_TAIL_CALL_LIST): New definition.
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r--gdb/dwarf2read.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index a139b96..abc2163 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -6209,6 +6209,53 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
memset (call_site, 0, sizeof (*call_site) - sizeof (*call_site->parameter));
call_site->pc = pc;
+ if (dwarf2_flag_true_p (die, DW_AT_GNU_tail_call, cu))
+ {
+ struct die_info *func_die;
+
+ /* Skip also over DW_TAG_inlined_subroutine. */
+ for (func_die = die->parent;
+ func_die && func_die->tag != DW_TAG_subprogram
+ && func_die->tag != DW_TAG_subroutine_type;
+ func_die = func_die->parent);
+
+ /* DW_AT_GNU_all_call_sites is a superset
+ of DW_AT_GNU_all_tail_call_sites. */
+ if (func_die
+ && !dwarf2_flag_true_p (func_die, DW_AT_GNU_all_call_sites, cu)
+ && !dwarf2_flag_true_p (func_die, DW_AT_GNU_all_tail_call_sites, cu))
+ {
+ /* TYPE_TAIL_CALL_LIST is not interesting in functions where it is
+ not complete. But keep CALL_SITE for look ups via call_site_htab,
+ both the initial caller containing the real return address PC and
+ the final callee containing the current PC of a chain of tail
+ calls do not need to have the tail call list complete. But any
+ function candidate for a virtual tail call frame searched via
+ TYPE_TAIL_CALL_LIST must have the tail call list complete to be
+ determined unambiguously. */
+ }
+ else
+ {
+ struct type *func_type = NULL;
+
+ if (func_die)
+ func_type = get_die_type (func_die, cu);
+ if (func_type != NULL)
+ {
+ gdb_assert (TYPE_CODE (func_type) == TYPE_CODE_FUNC);
+
+ /* Enlist this call site to the function. */
+ call_site->tail_call_next = TYPE_TAIL_CALL_LIST (func_type);
+ TYPE_TAIL_CALL_LIST (func_type) = call_site;
+ }
+ else
+ complaint (&symfile_complaints,
+ _("Cannot find function owning DW_TAG_GNU_call_site "
+ "DIE 0x%x [in module %s]"),
+ die->offset, cu->objfile->name);
+ }
+ }
+
attr = dwarf2_attr (die, DW_AT_GNU_call_site_target, cu);
if (attr == NULL)
attr = dwarf2_attr (die, DW_AT_abstract_origin, cu);