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]

[patch 03/12] entryval#2: Tail call sites info reader


Hi,

unchanged:
	[patch 03/12] entryval: Tail call sites info reader
	http://sourceware.org/ml/gdb-patches/2011-07/msg00433.html


Thanks,
Jan


gdb/
2011-07-18  Jan Kratochvil  <jan.kratochvil@redhat.com>

	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.

--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -6195,6 +6195,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);
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -902,6 +902,13 @@ struct func_type
        this is only fetched from the Dwarf-2 DW_AT_calling_convention
        attribute.  */
     unsigned calling_convention;
+
+    /* Only those DW_TAG_GNU_call_site's in this function that have
+       DW_AT_GNU_tail_call set are linked in this list.  Function without its
+       tail call list complete (DW_AT_GNU_all_tail_call_sites or its superset
+       DW_AT_GNU_all_call_sites) has TAIL_CALL_LIST NULL, even if some
+       DW_TAG_GNU_call_site's exist in such function. */
+    struct call_site *tail_call_list;
   };
 
 /* A place where a function gets called from, represented by
@@ -913,6 +920,9 @@ struct call_site
        field as we overload core_addr_hash and core_addr_eq for it.  */
     CORE_ADDR pc;
 
+    /* List successor with head in FUNC_TYPE.TAIL_CALL_LIST.  */
+    struct call_site *tail_call_next;
+
     /* Describe DW_AT_GNU_call_site_target.  Missing attribute uses
        FIELD_LOC_KIND_DWARF_BLOCK with FIELD_DWARF_BLOCK == NULL.  */
     struct
@@ -1060,6 +1070,7 @@ extern void allocate_gnat_aux_type (struct type *);
 #define TYPE_GNAT_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.gnat_stuff
 #define TYPE_DESCRIPTIVE_TYPE(thistype) TYPE_GNAT_SPECIFIC(thistype)->descriptive_type
 #define TYPE_CALLING_CONVENTION(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.func_stuff->calling_convention
+#define TYPE_TAIL_CALL_LIST(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.func_stuff->tail_call_list
 #define TYPE_BASECLASS(thistype,index) TYPE_FIELD_TYPE(thistype, index)
 #define TYPE_N_BASECLASSES(thistype) TYPE_CPLUS_SPECIFIC(thistype)->n_baseclasses
 #define TYPE_BASECLASS_NAME(thistype,index) TYPE_FIELD_NAME(thistype, index)


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