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 more problems in the reader


The attached patch fixes two problems with the LTO reader.  The first is
that we were not handling all DW_TAG_* values that GCC can emit.  The
second is that when reading the body of a function, we may need to refer
to function decls that have not yet been read in.  So lto_resolve_fn_ref
should check for a cached version first, but then attempt to read the
decl directly from the stream (which will be cached in the process).
lto_resolve_{var,field}_ref also needed to be reworked in a similar
manner.

Committed to the lto branch.

-Nathan

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

	* lto.c (lto_read_form): Handle DW_AT_MIPS_linkage_name and
	DW_AT_GNU_vector specially, as they are not contiguous with the
	specified set of attribute names.  Use class_mask to check for
	errors at the end of the function
	(lto_resolve_var_ref): Read the DIE if it is not cached.
	(lto_resolve_fn_ref): Likewise.
	(lto_resolve_field_ref): Likewise.

Index: gcc/lto/lto.c
===================================================================
--- gcc/lto/lto.c	(revision 129047)
+++ gcc/lto/lto.c	(working copy)
@@ -831,10 +831,15 @@ lto_read_form (lto_info_fd *info_fd, 
   name = attr->name;
   form = attr->form;
   /* Make sure this is an attribute we recognize.  */
-  if (attr->name >= sizeof (attr_classes) / sizeof (attr_classes[0]))
+  if (attr->name == DW_AT_MIPS_linkage_name)
+    class_mask = DW_cl_string;
+  else if (attr->name == DW_AT_GNU_vector)
+    class_mask = DW_cl_flag;
+  else if (attr->name >= sizeof (attr_classes) / sizeof (attr_classes[0]))
     lto_file_corrupt_error (fd);
-  /* Determine the set of permitted attribute classes.  */
-  class_mask = attr_classes[attr->name];
+  else
+    /* Determine the set of permitted attribute classes.  */
+    class_mask = attr_classes[attr->name];
 
   /* Initialize OUT.  */ 
   out->cl = DW_cl_error;
@@ -1067,7 +1072,7 @@ lto_read_form (lto_info_fd *info_fd, 
   /* Make sure that we actually read something.  */
   gcc_assert (out->cl != DW_cl_error);
   /* Check the data read is of a class appropriate for the attribute.  */
-  if (!(out->cl & attr_classes[name]))
+  if (!(out->cl & class_mask))
     lto_file_corrupt_error (fd);
 }
 
@@ -3366,8 +3371,22 @@ lto_resolve_var_ref (lto_info_fd *info_f
   die = lto_resolve_reference (info_fd, ref->offset, context, &new_context);
   /* Map DIE to a variable.  */
   var = lto_cache_lookup_DIE (info_fd, die, /*skip=*/false);
-  if (!var || TREE_CODE (var) != VAR_DECL)
-    lto_file_corrupt_error ((lto_fd *)info_fd); 
+  if (!var)
+    {
+      lto_fd *fd = (lto_fd *)info_fd;
+      lto_die_ptr saved_die = fd->cur;
+
+      fd->cur = die;
+      var = lto_read_DIE (fd, context, NULL);
+
+      if (!var)
+        lto_file_corrupt_error (fd);
+
+      fd->cur = saved_die;
+    }
+  if (TREE_CODE (var) != VAR_DECL)
+    lto_file_corrupt_error ((lto_fd *)info_fd);
+
   /* Clean up.  */
   if (new_context != context)
     XDELETE (new_context);
@@ -3391,8 +3410,22 @@ lto_resolve_fn_ref (lto_info_fd *info_fd
   die = lto_resolve_reference (info_fd, ref->offset, context, &new_context);
   /* Map DIE to a variable.  */
   fn = lto_cache_lookup_DIE (info_fd, die, /*skip=*/false);
-  if (!fn || TREE_CODE (fn) != FUNCTION_DECL)
+  if (!fn)
+    {
+      lto_fd *fd = (lto_fd *)info_fd;
+      lto_die_ptr saved_die = fd->cur;
+
+      fd->cur = die;
+      fn = lto_read_DIE (fd, context, NULL);
+
+      if (!fn)
+        lto_file_corrupt_error (fd);
+
+      fd->cur = saved_die;
+    }
+  if (TREE_CODE (fn) != FUNCTION_DECL)
     lto_file_corrupt_error ((lto_fd *)info_fd);
+
   /* Clean up.  */
   if (new_context != context)
     XDELETE (new_context);
@@ -3416,8 +3449,22 @@ lto_resolve_field_ref (lto_info_fd *info
   die = lto_resolve_reference (info_fd, ref->offset, context, &new_context);
   /* Map DIE to a variable.  */
   field = lto_cache_lookup_DIE (info_fd, die, /*skip=*/false);
-  if (!field || TREE_CODE (field) != FIELD_DECL)
-    lto_file_corrupt_error ((lto_fd *)info_fd); 
+  if (!field)
+    {
+      lto_fd *fd = (lto_fd *)info_fd;
+      lto_die_ptr saved_die = fd->cur;
+
+      fd->cur = die;
+      field = lto_read_DIE (fd, context, NULL);
+
+      if (!field)
+        lto_file_corrupt_error (fd);
+
+      fd->cur = saved_die;
+    }
+  if (TREE_CODE (field) != FIELD_DECL)
+    lto_file_corrupt_error ((lto_fd *)info_fd);
+
   /* Clean up.  */
   if (new_context != context)
     XDELETE (new_context);

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