avoid random symbols for many targets

Geoffrey Keating gkeating@apple.com
Thu Sep 7 04:47:00 GMT 2006


With this patch, GCC will never generate any kind of random symbol on
targets with one_only, ctor/dtor support, and an eh_frame section.

The key parts, of course, are that now objects in or referring to the
anonymous namespace are 'static', and so are constructor/destructor
functions if the target has support.

What do people think?  Dejagnu testing passed, so I plan to queue it
up for 4.3.
-- 
- Geoffrey Keating <geoffk@apple.com>

===File ~/patches/gcc-norandom.patch========================
Index: ChangeLog
2006-09-06  Geoffrey Keating  <geoffk@apple.com>

	* coverage.c (coverage_checksum_string): Update comment.
	* dwarf2out.c (switch_to_eh_frame_section): Update for removal
	of get_file_function_name.
	* cgraphunit.c (cgraph_build_static_cdtor): Update for rename
	of get_file_function_name_long.
	* tree.c (get_file_function_name): Rename from
	get_file_function_name_long; improve comment; handle 'I' and 'D'
	specially when the target has ctor/dtor support; remove special
	handling for 'F'.
	(get_file_function_name): Remove.
	* tree.h (get_file_function_name): Rename from
        get_file_function_name_long.
	(get_file_function_name): Remove prototype.

Index: cp/ChangeLog
2006-09-06  Geoffrey Keating  <geoffk@apple.com>

	* name-lookup.c (get_anonymous_namespace_name): New.
	(push_namespace_with_attribs): Use get_anonymous_namespace_name.
	* decl2.c (start_objects): Update for rename of
	get_file_function_name_long.

Index: fortran/ChangeLog
2006-09-06  Geoffrey Keating  <geoffk@apple.com>

	* trans-decl.c (gfc_generate_constructors): Update for removal
	of get_file_function_name.

Index: tree.c
===================================================================
--- tree.c	(revision 117407)
+++ tree.c	(working copy)
@@ -6010,41 +6010,48 @@
       *p = '_';
 }
 
-/* Generate a name for a function unique to this translation unit.
+/* Generate a name for a special-purpose function function.
+   The generated name may need to be unique across the whole link.
    TYPE is some string to identify the purpose of this function to the
-   linker or collect2.  */
+   linker or collect2; it must start with an uppercase letter,
+   one of:
+   I - for constructors
+   D - for destructors
+   N - for C++ anonymous namespaces
+   F - for DWARF unwind frame information.  */
 
 tree
-get_file_function_name_long (const char *type)
+get_file_function_name (const char *type)
 {
   char *buf;
   const char *p;
   char *q;
 
+  /* If we already have a name we know to be unique, just use that.  */
   if (first_global_object_name)
+    p = first_global_object_name;
+  /* If the target is handling the constructors/destructors, they
+     will be local to this file and the name is only necessary for
+     debugging purposes.  */
+  else if ((type[0] == 'I' || type[0] == 'D') && targetm.have_ctors_dtors)
     {
-      p = first_global_object_name;
-
-      /* For type 'F', the generated name must be unique not only to this
-	 translation unit but also to any given link.  Since global names
-	 can be overloaded, we concatenate the first global object name
-	 with a string derived from the file name of this object.  */
-      if (!strcmp (type, "F"))
-	{
-	  const char *file = main_input_filename;
-
-	  if (! file)
-	    file = input_filename;
-
-	  q = alloca (strlen (p) + 10);
-	  sprintf (q, "%s_%08X", p, crc32_string (0, file));
-
-	  p = q;
-	}
+      const char *file = main_input_filename;
+      if (! file)
+	file = input_filename;
+      /* Just use the file's basename, because the full pathname
+	 might be quite long.  */
+      p = strrchr (file, '/');
+      if (p)
+	p++;
+      else
+	p = file;
+      p = q = ASTRDUP (p);
+      clean_symbol_name (q);
     }
   else
     {
-      /* We don't have anything that we know to be unique to this translation
+      /* Otherwise, the name must be unique across the entire link.
+	 We don't have anything that we know to be unique to this translation
 	 unit, so use what we do have and throw in some randomness.  */
       unsigned len;
       const char *name = weak_global_object_name;
@@ -6076,20 +6083,6 @@
 
   return get_identifier (buf);
 }
-
-/* If KIND=='I', return a suitable global initializer (constructor) name.
-   If KIND=='D', return a suitable global clean-up (destructor) name.  */
-
-tree
-get_file_function_name (int kind)
-{
-  char p[2];
-
-  p[0] = kind;
-  p[1] = 0;
-
-  return get_file_function_name_long (p);
-}
 
 #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
 
Index: tree.h
===================================================================
--- tree.h	(revision 117407)
+++ tree.h	(working copy)
@@ -4148,7 +4148,7 @@
 /* In tree.c */
 extern unsigned crc32_string (unsigned, const char *);
 extern void clean_symbol_name (char *);
-extern tree get_file_function_name_long (const char *);
+extern tree get_file_function_name (const char *);
 extern tree get_callee_fndecl (tree);
 extern void change_decl_assembler_name (tree, tree);
 extern int type_num_arguments (tree);
@@ -4480,10 +4480,6 @@
 extern const char *get_name (tree);
 extern tree unshare_expr (tree);
 extern void sort_case_labels (tree);
-
-/* If KIND=='I', return a suitable global initializer (constructor) name.
-   If KIND=='D', return a suitable global clean-up (destructor) name.  */
-extern tree get_file_function_name (int);
 
 /* Interface of the DWARF2 unwind info support.  */
 
Index: cgraphunit.c
===================================================================
--- cgraphunit.c	(revision 117407)
+++ cgraphunit.c	(working copy)
@@ -1662,7 +1662,7 @@
   tree decl, name, resdecl;
 
   sprintf (which_buf, "%c_%d", which, counter++);
-  name = get_file_function_name_long (which_buf);
+  name = get_file_function_name (which_buf);
 
   decl = build_decl (FUNCTION_DECL, name,
 		     build_function_type (void_type_node, void_list_node));
Index: cp/name-lookup.c
===================================================================
--- cp/name-lookup.c	(revision 117407)
+++ cp/name-lookup.c	(working copy)
@@ -61,7 +61,25 @@
    unit.  */
 static GTY(()) tree anonymous_namespace_name;
 
+/* Initialise anonymous_namespace_name if necessary, and return it.  */
 
+static tree
+get_anonymous_namespace_name(void)
+{
+  if (!anonymous_namespace_name)
+    {
+      /* The anonymous namespace has to have a unique name
+	 if typeinfo objects are being compared by name.  */
+      if (! flag_weak || ! SUPPORTS_ONE_ONLY)
+	anonymous_namespace_name = get_file_function_name ("N");
+      else
+	/* The demangler expects anonymous namespaces to be called
+	   something starting with '_GLOBAL__N_'.  */
+	anonymous_namespace_name = get_identifier ("_GLOBAL__N_1");
+    }
+  return anonymous_namespace_name;
+}
+
 /* Compute the chain index of a binding_entry given the HASH value of its
    name and the total COUNT of chains.  COUNT is assumed to be a power
    of 2.  */
@@ -3010,11 +3028,7 @@
 
   if (anon)
     {
-      /* The name of anonymous namespace is unique for the translation
-	 unit.  */
-      if (!anonymous_namespace_name)
-	anonymous_namespace_name = get_file_function_name ('N');
-      name = anonymous_namespace_name;
+      name = get_anonymous_namespace_name();
       d = IDENTIFIER_NAMESPACE_VALUE (name);
       if (d)
 	/* Reopening anonymous namespace.  */
Index: cp/decl2.c
===================================================================
--- cp/decl2.c	(revision 117407)
+++ cp/decl2.c	(working copy)
@@ -2326,7 +2326,7 @@
     sprintf (type, "%c", method_type);
 
   fndecl = build_lang_decl (FUNCTION_DECL,
-			    get_file_function_name_long (type),
+			    get_file_function_name (type),
 			    build_function_type (void_type_node,
 						 void_list_node));
   start_preparsed_function (fndecl, /*attrs=*/NULL_TREE, SF_PRE_PARSED);
Index: dwarf2out.c
===================================================================
--- dwarf2out.c	(revision 117407)
+++ dwarf2out.c	(working copy)
@@ -2021,7 +2021,7 @@
       /* We have no special eh_frame section.  Put the information in
 	 the data section and emit special labels to guide collect2.  */
       switch_to_section (data_section);
-      label = get_file_function_name ('F');
+      label = get_file_function_name ("F");
       ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE));
       targetm.asm_out.globalize_label (asm_out_file,
 				       IDENTIFIER_POINTER (label));
Index: fortran/trans-decl.c
===================================================================
--- fortran/trans-decl.c	(revision 117407)
+++ fortran/trans-decl.c	(working copy)
@@ -3210,7 +3210,7 @@
   if (gfc_static_ctors == NULL_TREE)
     return;
 
-  fnname = get_file_function_name ('I');
+  fnname = get_file_function_name ("I");
   type = build_function_type (void_type_node,
 			      gfc_chainon_list (NULL_TREE, void_type_node));
 
Index: coverage.c
===================================================================
--- coverage.c	(revision 117405)
+++ coverage.c	(working copy)
@@ -433,7 +433,7 @@
   char *dup = NULL;
 
   /* Look for everything that looks if it were produced by
-     get_file_function_name_long and zero out the second part
+     get_file_function_name and zero out the second part
      that may result from flag_random_seed.  This is not critical
      as the checksums are used only for sanity checking.  */
   for (i = 0; string[i]; i++)
============================================================



More information about the Gcc-patches mailing list