This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[lto] fix reading DW_TAG_variable_type


The below patch fixes an issue with reading DW_TAG_variable DIEs.  We
would run across debug information like:

 <1><7e4>: Abbrev Number: 37 (DW_TAG_variable)
  <7e5>     DW_AT_name        : last_id	
  <7ed>     DW_AT_decl_file   : 1	
  <7ee>     DW_AT_decl_line   : 62	
  <7ef>     DW_AT_type        : <1c4>	
  <7f3>     DW_AT_declaration : 1	
 ...
 <1><818>: Abbrev Number: 38 (DW_TAG_variable)
  <819>     DW_AT_specification: <7e4>	
  <81d>     DW_AT_location    : 9 byte block: 3 0 0 0 0 0 0 0 0 	(DW_OP_addr: 0)

When we read the DIE at 0x818, we would find that it had a null name and
type (since we didn't follow DW_AT_specification), which build_decl and
its callees would choke on.

We fix this by following DW_AT_specification and returning the decl
associated with that when appropriate.

This still leaves open the problem of what to do about cases like:

 <2><524>: Abbrev Number: 27 (DW_TAG_variable)
  <525>     DW_AT_location    : 9 byte block: 3 0 0 0 0 0 0 0 0 	(DW_OP_addr: 0)

where we have no name, type, or specification.  I think this may be a
bug in the DWARF generation.  Suggestions on what causes this, how to
fix it, or outright fixes welcome.

Moderately non-trivial files (e.g. alloc-pool.c) are now round-trippable
through LTO.

Committed to the LTO branch.

-Nathan

2007-10-19  Nathan Froyd  <froydnj@codesourcery.com>

	* lto.c (lto_read_DIE_at_ptr): New function.
	(lto_resolve_var_ref): Use it.
	(lto_resolve_fn_ref): Use it.
	(lto_resolve_field_ref): Use it.
	(lto_read_variable_formal_parameter_constant_DIE): Follow
	DW_AT_specification and return the associated decl when appropriate.

Index: lto.c
===================================================================
--- lto.c	(revision 129458)
+++ lto.c	(working copy)
@@ -201,6 +201,11 @@ lto_read_DIE (lto_info_fd *fd,
 	      lto_context *context,
 	      bool *more);
 
+static tree
+lto_read_DIE_at_ptr (lto_info_fd *fd,
+		     lto_context *context,
+		     lto_die_ptr ptr);
+
 static void
 lto_read_child_DIEs (lto_info_fd *fd, 
 		     const DWARF2_abbrev *abbrev, 
@@ -1966,6 +1971,7 @@ lto_read_variable_formal_parameter_const
   bool artificial;
   enum tree_code code;
   tree decl;
+  tree specification;
 
   gcc_assert (abbrev->tag == DW_TAG_variable
 	      || abbrev->tag == DW_TAG_formal_parameter
@@ -1978,6 +1984,7 @@ lto_read_variable_formal_parameter_const
   declaration = false;
   code = ERROR_MARK;
   decl = NULL_TREE;
+  specification = NULL_TREE;
 
   LTO_BEGIN_READ_ATTRS ()
     {
@@ -1990,10 +1997,15 @@ lto_read_variable_formal_parameter_const
     case DW_AT_decl_line:
     case DW_AT_abstract_origin:
     case DW_AT_const_value:
-    case DW_AT_specification:
       /* Ignore.  */
       break;
 
+    case DW_AT_specification:
+      if (abbrev->tag == DW_TAG_variable)
+	specification = lto_read_DIE_at_ptr (fd, context,
+					     attr_data.u.reference);
+      break;
+
     case DW_AT_name:
       name = lto_get_identifier (&attr_data);
       /* Assume that the assembler name is the same as the source name
@@ -2063,6 +2075,14 @@ lto_read_variable_formal_parameter_const
     ;
   else
     {
+      /* Check for a specification.  */
+      if (specification
+	  && !name
+	  && !type
+	  && TREE_CODE (specification) == code)
+	return specification;
+
+
       /* Build the tree node for this entity.  */
       decl = build_decl (code, name, type);
 
@@ -3372,6 +3392,25 @@ lto_resolve_type_ref (lto_info_fd *info_
   return type;
 }
 
+tree
+lto_read_DIE_at_ptr (lto_info_fd *info_fd,
+		     lto_context *context,
+		     lto_die_ptr ptr)
+{
+  lto_fd *fd = (lto_fd *)info_fd;
+  const char *saved_die = fd->cur;
+  tree result;
+
+  fd->cur = (const char *) ptr;
+  result = lto_read_DIE (info_fd, context, NULL);
+
+  if (!result)
+    lto_file_corrupt_error (fd);
+
+  fd->cur = saved_die;
+  return result;
+}
+  
 tree 
 lto_resolve_var_ref (lto_info_fd *info_fd,
 		     lto_context *context,
@@ -3389,18 +3428,7 @@ lto_resolve_var_ref (lto_info_fd *info_f
   /* Map DIE to a variable.  */
   var = lto_cache_lookup_DIE (info_fd, die, /*skip=*/false);
   if (!var)
-    {
-      lto_fd *fd = (lto_fd *)info_fd;
-      const char *saved_die = fd->cur;
-
-      fd->cur = (const char *) die;
-      var = lto_read_DIE (info_fd, context, NULL);
-
-      if (!var)
-        lto_file_corrupt_error (fd);
-
-      fd->cur = saved_die;
-    }
+    var = lto_read_DIE_at_ptr (info_fd, context, die);
   if (TREE_CODE (var) != VAR_DECL)
     lto_file_corrupt_error ((lto_fd *)info_fd);
 
@@ -3428,18 +3456,7 @@ lto_resolve_fn_ref (lto_info_fd *info_fd
   /* Map DIE to a variable.  */
   fn = lto_cache_lookup_DIE (info_fd, die, /*skip=*/false);
   if (!fn)
-    {
-      lto_fd *fd = (lto_fd *)info_fd;
-      const char *saved_die = fd->cur;
-
-      fd->cur = (const char *) die;
-      fn = lto_read_DIE (info_fd, context, NULL);
-
-      if (!fn)
-        lto_file_corrupt_error (fd);
-
-      fd->cur = saved_die;
-    }
+    fn = lto_read_DIE_at_ptr (info_fd, context, die);
   if (TREE_CODE (fn) != FUNCTION_DECL)
     lto_file_corrupt_error ((lto_fd *)info_fd);
 
@@ -3467,18 +3484,7 @@ lto_resolve_field_ref (lto_info_fd *info
   /* Map DIE to a variable.  */
   field = lto_cache_lookup_DIE (info_fd, die, /*skip=*/false);
   if (!field)
-    {
-      lto_fd *fd = (lto_fd *)info_fd;
-      const char *saved_die = fd->cur;
-
-      fd->cur = (const char *) die;
-      field = lto_read_DIE (info_fd, context, NULL);
-
-      if (!field)
-        lto_file_corrupt_error (fd);
-
-      fd->cur = saved_die;
-    }
+    field = lto_read_DIE_at_ptr (info_fd, context, die);
   if (TREE_CODE (field) != FIELD_DECL)
     lto_file_corrupt_error ((lto_fd *)info_fd);
 


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