[lto] fix section switching

Nathan Froyd froydnj@codesourcery.com
Thu Dec 6 21:48:00 GMT 2007


I noticed when trying to compile 255.vortex that we would sometimes get
a corrupt LTO file.  The problem was that when we grab a handle on DIEs
for VAR_DECLs, dwarf2out might decide to dump extra bits (such as
DECL_INITIAL of the decl in question) into our assembly file--probably
to have labels to refer to for debugging information.  Except that we
never suspected that sections were switched out from underneath us, so
we merrily went along, outputting LTO information into whatever section
we were now in, with predictably bad results.

The fix is to switch back to the relevant LTO section before dumping the
reference to the DIE.  I took the opportunity to pull out some repeated
code from produce_asm as well.

Committed to the LTO branch.

-Nathan

2007-12-06  Nathan Froyd  <froydnj@codesourcery.com>

	* lto-function-out.c (write_references): New function.
	(produce_asm): Call it.

Index: lto-function-out.c
===================================================================
--- lto-function-out.c	(revision 130658)
+++ lto-function-out.c	(working copy)
@@ -2011,24 +2011,43 @@ output_bb (struct output_block *ob, basi
 #endif
 }
 
+/* Write the references for the objects in V to section SEC in the
+   assembly file.  Use REF_FN to compute the reference.  */
+
+static void
+write_references (VEC(tree,heap) *v, section *sec,
+		  void (*ref_fn) (tree, lto_out_ref *))
+{
+  int index;
+  tree t;
+  lto_out_ref out_ref = {0, NULL, NULL};
+
+  for (index = 0; VEC_iterate(tree, v, index, t); index++)
+    {
+      ref_fn (t, &out_ref);
+      /* We always call switch_to_section as the act of creating a
+	 handle we can reference may have dumped some bits into the
+	 assembly.  */
+      switch_to_section (sec);
+      dw2_asm_output_data (8, out_ref.section, " ");
+      dw2_asm_output_delta (8, out_ref.label, out_ref.base_label, " ");
+    }
+}
 
 /* Create the header in the file using OB for t.  */
 
 static void
 produce_asm (struct output_block *ob, tree t, bool is_function)
 {
-  int index;
-  tree decl;
-  tree type;
   const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t));
   const char *section_name = concat (LTO_SECTION_NAME_PREFIX, name, NULL);
+  section *section = get_section (section_name, SECTION_DEBUG, t);
   struct lto_header header;
-  lto_out_ref out_ref = {0, NULL, NULL};
 
   memset (&header, 0, sizeof (struct lto_header)); 
 
   /* The entire header is stream computed here.  */
-  switch_to_section (get_section (section_name, SECTION_DEBUG, t));
+  switch_to_section (section);
   
   /* Write the header which says how to decode the pieces of the
      t.  */
@@ -2081,49 +2100,19 @@ produce_asm (struct output_block *ob, tr
 		   sizeof (struct lto_header));
 
   /* Write the global field references.  */
-  for (index = 0; VEC_iterate(tree, ob->field_decls, index, decl); index++)
-    {
-      lto_field_ref (decl, &out_ref);
-      dw2_asm_output_data (8, out_ref.section, " ");
-      dw2_asm_output_delta (8, out_ref.label,
-			    out_ref.base_label, " ");
-    }
+  write_references (ob->field_decls, section, lto_field_ref);
 
   /* Write the global function references.  */
-  for (index = 0; VEC_iterate(tree, ob->fn_decls, index, decl); index++)
-    {
-      lto_fn_ref (decl, &out_ref);
-      dw2_asm_output_data (8, out_ref.section, " ");
-      dw2_asm_output_delta (8, out_ref.label,
-			    out_ref.base_label, " ");
-    }
+  write_references (ob->fn_decls, section, lto_fn_ref);
 
   /* Write the global var references.  */
-  for (index = 0; VEC_iterate(tree, ob->var_decls, index, decl); index++)
-    {
-      lto_var_ref (decl, &out_ref);
-      dw2_asm_output_data (8, out_ref.section, " ");
-      dw2_asm_output_delta (8, out_ref.label,
-			    out_ref.base_label, " ");
-    }
+  write_references (ob->var_decls, section, lto_var_ref);
 
   /* Write the global type_decl references.  */
-  for (index = 0; VEC_iterate(tree, ob->type_decls, index, decl); index++)
-    {
-      lto_typedecl_ref (decl, &out_ref);
-      dw2_asm_output_data (8, out_ref.section, " ");
-      dw2_asm_output_delta (8, out_ref.label,
-			    out_ref.base_label, " ");
-    }
+  write_references (ob->type_decls, section, lto_typedecl_ref);
 
   /* Write the global type references.  */
-  for (index = 0; VEC_iterate(tree, ob->types, index, type); index++)
-    {
-      lto_type_ref (type, &out_ref);
-      dw2_asm_output_data (8, out_ref.section, " ");
-      dw2_asm_output_delta (8, out_ref.label,
-			    out_ref.base_label, " ");
-    }
+  write_references (ob->types, section, lto_type_ref);
 
   /* Put all of the gimple and the string table out the asm file as a
      block of text.  */



More information about the Gcc-patches mailing list