This is the mail archive of the binutils@sourceware.org mailing list for the binutils 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]

Re: [RFC] Pointer alignment issues in ld's map_input_to_output_sections


On Fri, Jun 09, 2006 at 09:31:15AM +0930, Alan Modra wrote:
> On Thu, Jun 08, 2006 at 05:16:37PM -0600, Roger Sayle wrote:
> > One suggestion was to change the output_statement_hash_entry struct
> > to make "os" be a lang_statement_union_type instead of a
> > lang_output_section_statement_type, but unfortunately this would
> > mean increasing the size of each hash table entry to the largest
> > member of that union.
> 
> This is the right solution.  lang_output_section_statement_type is one
> of the largest elements of lang_statement_union_type.  It might even be
> the largest.

This does some renaming too, because we have lang_output_statement_type
as well as lang_output_section_statement_type.  So using
output_statement_* in function names and structs that actually deal with
lang_output_section_statement_type's is misleading.  Oh, and packing
lang_input_statement_type makes it smaller than
lang_output_section_statement_type.

Applied mainline and 2.17.

	* ldlang.h (lang_input_statement_type): Use bitfields for booleans.
	* ldlang.c (struct out_section_hash_entry): Rename from
	output_statement_hash_entry.  Delete output_section_statement_type
	entry.  Add statement_union_type entry.  Adjust all users.
	(output_section_statement_table): Rename from output_statement_table.
	Adjust all users.
	(output_section_statement_newfunc): Rename from
	output_statement_newfunc.  Adjust all users.
	(output_section_statement_table_init): Rename from
	output_statement_table_init.  Adjust all users.
	(output_section_statement_table_free): Rename from
	output_statement_table_free.  Adjust all users.

Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.222
diff -u -p -r1.222 ldlang.c
--- ld/ldlang.c	7 Jun 2006 04:55:11 -0000	1.222
+++ ld/ldlang.c	9 Jun 2006 00:57:50 -0000
@@ -869,26 +869,26 @@ lang_add_input_file (const char *name,
   return new_afile (name, file_type, target, TRUE);
 }
 
-struct output_statement_hash_entry
+struct out_section_hash_entry
 {
   struct bfd_hash_entry root;
-  lang_output_section_statement_type os;
+  lang_statement_union_type s;
 };
 
 /* The hash table.  */
 
-static struct bfd_hash_table output_statement_table;
+static struct bfd_hash_table output_section_statement_table;
 
 /* Support routines for the hash table used by lang_output_section_find,
    initialize the table, fill in an entry and remove the table.  */
 
 static struct bfd_hash_entry *
-output_statement_newfunc (struct bfd_hash_entry *entry, 
-			  struct bfd_hash_table *table,
-			  const char *string)
+output_section_statement_newfunc (struct bfd_hash_entry *entry, 
+				  struct bfd_hash_table *table,
+				  const char *string)
 {
   lang_output_section_statement_type **nextp;
-  struct output_statement_hash_entry *ret;
+  struct out_section_hash_entry *ret;
 
   if (entry == NULL)
     {
@@ -901,49 +901,48 @@ output_statement_newfunc (struct bfd_has
   if (entry == NULL)
     return entry;
 
-  ret = (struct output_statement_hash_entry *) entry;
-  memset (&ret->os, 0, sizeof (ret->os));
-  ret->os.header.type = lang_output_section_statement_enum;
-  ret->os.subsection_alignment = -1;
-  ret->os.section_alignment = -1;
-  ret->os.block_value = 1;
-  lang_list_init (&ret->os.children);
-  lang_statement_append (stat_ptr,
-			 (lang_statement_union_type *) &ret->os,
-			 &ret->os.header.next);
+  ret = (struct out_section_hash_entry *) entry;
+  memset (&ret->s, 0, sizeof (ret->s));
+  ret->s.header.type = lang_output_section_statement_enum;
+  ret->s.output_section_statement.subsection_alignment = -1;
+  ret->s.output_section_statement.section_alignment = -1;
+  ret->s.output_section_statement.block_value = 1;
+  lang_list_init (&ret->s.output_section_statement.children);
+  lang_statement_append (stat_ptr, &ret->s, &ret->s.header.next);
 
   /* For every output section statement added to the list, except the
      first one, lang_output_section_statement.tail points to the "next"
      field of the last element of the list.  */
   if (lang_output_section_statement.head != NULL)
-    ret->os.prev = (lang_output_section_statement_type *)
-      ((char *) lang_output_section_statement.tail
-       - offsetof (lang_output_section_statement_type, next));
+    ret->s.output_section_statement.prev
+      = ((lang_output_section_statement_type *)
+	 ((char *) lang_output_section_statement.tail
+	  - offsetof (lang_output_section_statement_type, next)));
 
   /* GCC's strict aliasing rules prevent us from just casting the
      address, so we store the pointer in a variable and cast that
      instead.  */
-  nextp = &ret->os.next;
+  nextp = &ret->s.output_section_statement.next;
   lang_statement_append (&lang_output_section_statement,
-			 (lang_statement_union_type *) &ret->os,
+			 &ret->s,
 			 (lang_statement_union_type **) nextp);
   return &ret->root;
 }
 
 static void
-output_statement_table_init (void)
+output_section_statement_table_init (void)
 {
-  if (!bfd_hash_table_init_n (&output_statement_table,
-			      output_statement_newfunc,
-			      sizeof (struct output_statement_hash_entry),
+  if (!bfd_hash_table_init_n (&output_section_statement_table,
+			      output_section_statement_newfunc,
+			      sizeof (struct out_section_hash_entry),
 			      61))
     einfo (_("%P%F: can not create hash table: %E\n"));
 }
 
 static void
-output_statement_table_free (void)
+output_section_statement_table_free (void)
 {
-  bfd_hash_table_free (&output_statement_table);
+  bfd_hash_table_free (&output_section_statement_table);
 }
 
 /* Build enough state so that the parser can build its tree.  */
@@ -955,7 +954,7 @@ lang_init (void)
 
   stat_ptr = &statement_list;
 
-  output_statement_table_init ();
+  output_section_statement_table_init ();
 
   lang_list_init (stat_ptr);
 
@@ -985,7 +984,7 @@ lang_init (void)
 void
 lang_finish (void)
 {
-  output_statement_table_free ();
+  output_section_statement_table_free ();
 }
 
 /*----------------------------------------------------------------------
@@ -1072,24 +1071,25 @@ lang_memory_default (asection *section)
 lang_output_section_statement_type *
 lang_output_section_find (const char *const name)
 {
-  struct output_statement_hash_entry *entry;
+  struct out_section_hash_entry *entry;
   unsigned long hash;
 
-  entry = ((struct output_statement_hash_entry *)
-	   bfd_hash_lookup (&output_statement_table, name, FALSE, FALSE));
+  entry = ((struct out_section_hash_entry *)
+	   bfd_hash_lookup (&output_section_statement_table, name,
+			    FALSE, FALSE));
   if (entry == NULL)
     return NULL;
 
   hash = entry->root.hash;
   do
     {
-      if (entry->os.constraint != -1)
-	return &entry->os;
-      entry = (struct output_statement_hash_entry *) entry->root.next;
+      if (entry->s.output_section_statement.constraint != -1)
+	return &entry->s.output_section_statement;
+      entry = (struct out_section_hash_entry *) entry->root.next;
     }
   while (entry != NULL
 	 && entry->root.hash == hash
-	 && strcmp (name, entry->os.name) == 0);
+	 && strcmp (name, entry->s.output_section_statement.name) == 0);
 
   return NULL;
 }
@@ -1097,39 +1097,43 @@ lang_output_section_find (const char *co
 static lang_output_section_statement_type *
 lang_output_section_statement_lookup_1 (const char *const name, int constraint)
 {
-  struct output_statement_hash_entry *entry;
-  struct output_statement_hash_entry *last_ent;
+  struct out_section_hash_entry *entry;
+  struct out_section_hash_entry *last_ent;
   unsigned long hash;
 
-  entry = ((struct output_statement_hash_entry *)
-	   bfd_hash_lookup (&output_statement_table, name, TRUE, FALSE));
+  entry = ((struct out_section_hash_entry *)
+	   bfd_hash_lookup (&output_section_statement_table, name,
+			    TRUE, FALSE));
   if (entry == NULL)
     {
       einfo (_("%P%F: failed creating section `%s': %E\n"), name);
       return NULL;
     }
 
-  if (entry->os.name != NULL)
+  if (entry->s.output_section_statement.name != NULL)
     {
       /* We have a section of this name, but it might not have the correct
 	 constraint.  */
       hash = entry->root.hash;
       do
 	{
-	  if (entry->os.constraint != -1
+	  if (entry->s.output_section_statement.constraint != -1
 	      && (constraint == 0
-		  || (constraint == entry->os.constraint
+		  || (constraint == entry->s.output_section_statement.constraint
 		      && constraint != SPECIAL)))
-	    return &entry->os;
+	    return &entry->s.output_section_statement;
 	  last_ent = entry;
-	  entry = (struct output_statement_hash_entry *) entry->root.next;
+	  entry = (struct out_section_hash_entry *) entry->root.next;
 	}
       while (entry != NULL
 	     && entry->root.hash == hash
-	     && strcmp (name, entry->os.name) == 0);
+	     && strcmp (name, entry->s.output_section_statement.name) == 0);
 
-      entry = ((struct output_statement_hash_entry *)
-	       output_statement_newfunc (NULL, &output_statement_table, name));
+      entry
+	= ((struct out_section_hash_entry *)
+	   output_section_statement_newfunc (NULL,
+					     &output_section_statement_table,
+					     name));
       if (entry == NULL)
 	{
 	  einfo (_("%P%F: failed creating section `%s': %E\n"), name);
@@ -1139,9 +1143,9 @@ lang_output_section_statement_lookup_1 (
       last_ent->root.next = &entry->root;
     }
 
-  entry->os.name = name;
-  entry->os.constraint = constraint;
-  return &entry->os;
+  entry->s.output_section_statement.name = name;
+  entry->s.output_section_statement.constraint = constraint;
+  return &entry->s.output_section_statement;
 }
 
 lang_output_section_statement_type *
Index: ld/ldlang.h
===================================================================
RCS file: /cvs/src/src/ld/ldlang.h,v
retrieving revision 1.61
diff -u -p -r1.61 ldlang.h
--- ld/ldlang.h	7 Jun 2006 04:55:11 -0000	1.61
+++ ld/ldlang.h	9 Jun 2006 00:57:50 -0000
@@ -228,7 +228,6 @@ typedef struct lang_input_statement_stru
 
   bfd *the_bfd;
 
-  bfd_boolean closed;
   file_ptr passive_position;
 
   /* Symbol table of the file.  */
@@ -242,40 +241,42 @@ typedef struct lang_input_statement_stru
   /* Point to the next file, but skips archive contents.  */
   union lang_statement_union *next_real_file;
 
-  bfd_boolean is_archive;
+  const char *target;
+
+  unsigned int closed : 1;
+  unsigned int is_archive : 1;
 
   /* 1 means search a set of directories for this file.  */
-  bfd_boolean search_dirs_flag;
+  unsigned int search_dirs_flag : 1;
 
   /* 1 means this was found in a search directory marked as sysrooted,
      if search_dirs_flag is false, otherwise, that it should be
      searched in ld_sysroot before any other location, as long as it
      starts with a slash.  */
-  bfd_boolean sysrooted;
+  unsigned int sysrooted : 1;
 
   /* 1 means this is base file of incremental load.
      Do not load this file's text or data.
      Also default text_start to after this file's bss.  */
-  bfd_boolean just_syms_flag;
+  unsigned int just_syms_flag : 1;
 
   /* Whether to search for this entry as a dynamic archive.  */
-  bfd_boolean dynamic;
+  unsigned int dynamic : 1;
 
   /* Whether DT_NEEDED tags should be added for dynamic libraries in
      DT_NEEDED tags from this entry.  */
-  bfd_boolean add_needed;
+  unsigned int add_needed : 1;
 
   /* Whether this entry should cause a DT_NEEDED tag only when
      satisfying references from regular files, or always.  */
-  bfd_boolean as_needed;
+  unsigned int as_needed : 1;
 
   /* Whether to include the entire contents of an archive.  */
-  bfd_boolean whole_archive;
+  unsigned int whole_archive : 1;
 
-  bfd_boolean loaded;
+  unsigned int loaded : 1;
 
-  const char *target;
-  bfd_boolean real;
+  unsigned int real : 1;
 } lang_input_statement_type;
 
 typedef struct

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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