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][patch] Add a symbol table


The attached patch adds a symbol table in the files generated with
-flto. The proposed field that is missing is the comdat key, but that
should be easy to add.

Next step is to write a program that is independent of gcc and can
read the table. With that I can start coding the plugin :-)

2008-07-22  Rafael Avila de Espindola  <espindola@google.com>
	* lto-header.h (lto_section_type): Add LTO_section_symtab.
	* lto-section-out.c: Include stdint.h.
	(lto_get_section_name): Handle LTO_section_symtab.
	(ld_plugin_symbol_kind): New.
	(ld_plugin_symbol_visibility): New.
	(produce_symtab_1): New.
	(produce_symtab): New.
	(produce_asm_for_decls): Call produce_symtab.

Cheers,
-- 
Rafael Avila de Espindola

Google Ireland Ltd.
Gordon House
Barrow Street
Dublin 4
Ireland

Registered in Dublin, Ireland
Registration Number: 368047
diff --git a/gcc/lto-header.h b/gcc/lto-header.h
index b02a712..77379af 100644
--- a/gcc/lto-header.h
+++ b/gcc/lto-header.h
@@ -43,7 +43,8 @@ enum lto_section_type
   LTO_section_static_initializer,
   LTO_section_cgraph,
   LTO_section_ipa_pure_const,
-  LTO_section_ipa_reference
+  LTO_section_ipa_reference,
+  LTO_section_symtab
 };
 
 struct lto_header
diff --git a/gcc/lto-section-out.c b/gcc/lto-section-out.c
index 2291815..50a7b8e 100644
--- a/gcc/lto-section-out.c
+++ b/gcc/lto-section-out.c
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "lto-section.h"
 #include "lto-section-out.h"
 #include "lto-tree-out.h"
+#include "stdint.h"
 
 /* Add FLAG onto the end of BASE.  */
  
@@ -165,6 +166,9 @@ lto_get_section_name (enum lto_section_type section_type, const char *name)
     case LTO_section_static_initializer:
       return concat (LTO_SECTION_NAME_PREFIX, ".statics", NULL);
 
+    case LTO_section_symtab:
+      return concat (LTO_SECTION_NAME_PREFIX, ".symtab", NULL);
+
     case LTO_section_decls:
       return concat (LTO_SECTION_NAME_PREFIX, ".decls", NULL);
 
@@ -903,6 +907,120 @@ write_global_references (struct output_block *ob, VEC(tree,heap) *v)
 }
 
 
+/* FIXME: These enums should come from some header that is shared with the
+   plugin. */
+
+enum ld_plugin_symbol_kind
+  {
+    LDPK_DEF,
+    LDPK_WEAKDEF,
+    LDPK_UNDEF,
+    LDPK_WEAKUNDEF,
+    LDPK_COMMON
+  };
+
+  enum ld_plugin_symbol_visibility
+  {
+    LDPV_DEFAULT,
+    LDPV_PROTECTED,
+    LDPV_INTERNAL,
+    LDPV_HIDDEN
+  };
+
+/* Helper function of produce_symtab. */
+
+static void
+produce_symtab_1 (htab_t hash, struct lto_output_stream *stream,
+		  VEC(tree,heap) *v)
+{
+  tree t;
+  int index;
+
+  for (index = 0; VEC_iterate(tree, v, index, t); index++)
+    {
+      const char *name = IDENTIFIER_POINTER (DECL_NAME(t));
+      enum ld_plugin_symbol_kind kind;
+      enum ld_plugin_symbol_visibility visibility;
+      struct lto_decl_slot d_slot;
+      int slot_num;
+      void **slot;
+      uint64_t size;
+
+      d_slot.t = t;
+      slot = htab_find_slot (hash, &d_slot, NO_INSERT);
+      gcc_assert (slot != NULL);
+      slot_num = ((struct lto_decl_slot *)*slot)->slot_num;
+
+      if (DECL_EXTERNAL (t))
+	{
+	  if (DECL_WEAK (t))
+	    kind = LDPK_WEAKUNDEF;
+	  else
+	    kind = LDPK_UNDEF;
+	}
+      else
+	{
+	  if (DECL_WEAK (t))
+	    kind = LDPK_WEAKDEF;
+	  else if (DECL_COMMON (t))
+	    kind = LDPK_COMMON;
+	  else
+	    kind = LDPK_DEF;
+	}
+
+      switch (DECL_VISIBILITY(t))
+	{
+	case VISIBILITY_DEFAULT:
+	  visibility = LDPV_DEFAULT;
+	  break;
+	case VISIBILITY_PROTECTED:
+	  visibility = LDPV_PROTECTED;
+	  break;
+	case VISIBILITY_HIDDEN:
+	  visibility = LDPV_HIDDEN;
+	  break;
+	case VISIBILITY_INTERNAL:
+	  visibility = LDPV_INTERNAL;
+	  break;
+	}
+
+      if (kind == LDPK_COMMON)
+	size = TREE_INT_CST_HIGH (DECL_SIZE (t)) << 32
+	  | TREE_INT_CST_LOW (DECL_SIZE (t));
+      else
+	size = 0;
+
+      lto_output_data_stream (stream, name, strlen (name) + 1);
+      lto_output_data_stream (stream, &kind, 1);
+      lto_output_data_stream (stream, &visibility, 1);
+      lto_output_data_stream (stream, &size, 8);
+      lto_output_data_stream (stream, &slot_num, 4);
+    }
+}
+
+/* Write an IL symbol table. HASH is the hash with the decl -> slot_num mapping.
+   FUNCTIONS is a vector of function decls. VARIABLES is a vector of variable
+   decls */
+
+static void
+produce_symtab (htab_t hash, VEC(tree,heap) *functions,
+		VEC(tree,heap) *variables)
+{
+  char *section_name = lto_get_section_name (LTO_section_symtab, NULL);
+  struct lto_output_stream stream;
+
+  lto_begin_section (section_name);
+  free(section_name);
+  memset (&stream, 0, sizeof (stream));
+
+
+  produce_symtab_1 (hash, &stream, functions);
+  produce_symtab_1 (hash, &stream, variables);
+
+  lto_write_stream (&stream);
+  lto_end_section ();
+}
+
 /* This pass is run after all of the functions are serialized and all
    of the IPA passes have written their serialized forms.  This pass
    causes the vector of all of the global decls and types used from
@@ -989,7 +1107,6 @@ produce_asm_for_decls (void)
 #endif
 
   /* Deallocate memory and clean up.  */
-  htab_delete (ob->main_hash_table);
   destroy_output_block (ob);
 
   htab_delete (out_state->field_decl_hash_table);
@@ -999,14 +1116,22 @@ produce_asm_for_decls (void)
   htab_delete (out_state->namespace_decl_hash_table);
   htab_delete (out_state->type_hash_table);
 
+  lto_end_section ();
+
+  /* Write the symbol table. */
+  produce_symtab (ob->main_hash_table,
+		  out_state->fn_decls,
+		  out_state->var_decls);
+
+  /* Finish cleanup. */
+  htab_delete (ob->main_hash_table);
+
   VEC_free (tree, heap, out_state->field_decls);
   VEC_free (tree, heap, out_state->fn_decls);
   VEC_free (tree, heap, out_state->var_decls);
   VEC_free (tree, heap, out_state->type_decls);
   VEC_free (tree, heap, out_state->namespace_decls);
   VEC_free (tree, heap, out_state->types);
-
-  lto_end_section ();
 }
 
 

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