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]

ld output_section_statment related tidy


This patch started off as one to allow INSERT to add a new output
section statement before or after an existing output statement with
the same section name, but ended up just being a cleanup.  The
trouble with allowing an INSERT of the same output section name is
simply that we'd need to allow duplicate output section statements of
the same name, which we don't support currently.  That isn't a
particularly difficult thing to do, but I think it would be safer to
leave that change until we've branched.

	* ldlang.h (lang_output_section_find): Define.
	(lang_output_section_statement_lookup): Update prototype.
	* ldlang.c (lang_output_section_find,
	lang_output_section_statement_lookup_1): Merge into..
	(lang_output_section_statement_lookup): ..here.  Update all callers.
	(process_insert_statements): Set constraint negative
	for output section statements we might be inserting.  Make error
	fatal on not finding insertion section.
	(lang_output_section_find): Rather than comparing
	output_section_statement.constraint against -1, test whether
	it is postive.
	(lang_output_section_statement_lookup_1): Likewise.
	(output_prev_sec_find, strip_excluded_output_sections): Likewise.
	(lang_record_phdrs): Likewise.
	* emultempl/elf32.em (output_rel_find): Likewise.
	* NEWS: Mention INSERT.

Index: ld/NEWS
===================================================================
RCS file: /cvs/src/src/ld/NEWS,v
retrieving revision 1.85
diff -u -p -r1.85 NEWS
--- ld/NEWS	7 Jun 2008 11:35:46 -0000	1.85
+++ ld/NEWS	6 Sep 2008 00:04:49 -0000
@@ -1,6 +1,9 @@
 -*- text -*-
+* Linker scripts support a new INSERT command that makes it easier to
+  augment the default script.
+
 * Linker script input section filespecs may now specify a file within an
- archive by writing "archive:file".
+  archive by writing "archive:file".
 
 * The --sort-common switch now has an optional argument which specifies the
   direction of sorting.
@@ -8,9 +11,9 @@
 * The M68K linker now supports multiple GOT generation schemes controlled via
   the --got=<type> command line option.
 
-* The ARM EABI linker will now generate stubs for function calls to symbols that
-  are too far away.  The placement of the stubs is controlled by a new linker
-  command line option: --stub-group-size=N.
+* The ARM EABI linker will now generate stubs for function calls to symbols
+  that are too far away.  The placement of the stubs is controlled by a new
+  linker command line option: --stub-group-size=N.
 
 Changes in 2.18:
 
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.291
diff -u -p -r1.291 ldlang.c
--- ld/ldlang.c	21 Aug 2008 13:10:54 -0000	1.291
+++ ld/ldlang.c	6 Sep 2008 00:04:53 -0000
@@ -1149,7 +1149,7 @@ lang_init (void)
   first_file = lang_add_input_file (NULL, lang_input_file_is_marker_enum,
 				    NULL);
   abs_output_section =
-    lang_output_section_statement_lookup (BFD_ABS_SECTION_NAME);
+    lang_output_section_statement_lookup (BFD_ABS_SECTION_NAME, 0, TRUE);
 
   abs_output_section->bfd_section = bfd_abs_section_ptr;
 
@@ -1255,44 +1255,19 @@ lang_memory_default (asection *section)
 }
 
 lang_output_section_statement_type *
-lang_output_section_find (const char *const name)
+lang_output_section_statement_lookup (const char *const name,
+				      int constraint,
+				      bfd_boolean create)
 {
   struct out_section_hash_entry *entry;
-  unsigned long hash;
 
   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->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->s.output_section_statement.name) == 0);
-
-  return NULL;
-}
-
-static lang_output_section_statement_type *
-lang_output_section_statement_lookup_1 (const char *const name, int constraint)
-{
-  struct out_section_hash_entry *entry;
-  struct out_section_hash_entry *last_ent;
-  unsigned long hash;
-
-  entry = ((struct out_section_hash_entry *)
-	   bfd_hash_lookup (&output_section_statement_table, name,
-			    TRUE, FALSE));
+			    create, FALSE));
   if (entry == NULL)
     {
-      einfo (_("%P%F: failed creating section `%s': %E\n"), name);
+      if (create)
+	einfo (_("%P%F: failed creating section `%s': %E\n"), name);
       return NULL;
     }
 
@@ -1300,10 +1275,12 @@ lang_output_section_statement_lookup_1 (
     {
       /* We have a section of this name, but it might not have the correct
 	 constraint.  */
-      hash = entry->root.hash;
+      struct out_section_hash_entry *last_ent;
+      unsigned long hash = entry->root.hash;
+
       do
 	{
-	  if (entry->s.output_section_statement.constraint != -1
+	  if (entry->s.output_section_statement.constraint >= 0
 	      && (constraint == 0
 		  || (constraint == entry->s.output_section_statement.constraint
 		      && constraint != SPECIAL)))
@@ -1315,6 +1292,9 @@ lang_output_section_statement_lookup_1 (
 	     && entry->root.hash == hash
 	     && strcmp (name, entry->s.output_section_statement.name) == 0);
 
+      if (!create)
+	return NULL;
+
       entry
 	= ((struct out_section_hash_entry *)
 	   output_section_statement_newfunc (NULL,
@@ -1334,12 +1314,6 @@ lang_output_section_statement_lookup_1 (
   return &entry->s.output_section_statement;
 }
 
-lang_output_section_statement_type *
-lang_output_section_statement_lookup (const char *const name)
-{
-  return lang_output_section_statement_lookup_1 (name, 0);
-}
-
 /* A variant of lang_output_section_find used by place_orphan.
    Returns the output statement that should precede a new output
    statement for SEC.  If an exact match is found on certain flags,
@@ -1502,7 +1476,7 @@ output_prev_sec_find (lang_output_sectio
 
   for (lookup = os->prev; lookup != NULL; lookup = lookup->prev)
     {
-      if (lookup->constraint == -1)
+      if (lookup->constraint < 0)
 	continue;
 
       if (lookup->bfd_section != NULL && lookup->bfd_section->owner != NULL)
@@ -3378,7 +3352,7 @@ map_input_to_output_sections
 	    {
 	      lang_output_section_statement_type *aos
 		= (lang_output_section_statement_lookup
-		   (s->address_statement.section_name));
+		   (s->address_statement.section_name, 0, TRUE));
 
 	      if (aos->bfd_section == NULL)
 		init_os (aos, NULL, 0);
@@ -3403,6 +3377,7 @@ process_insert_statements (void)
   lang_statement_union_type **s;
   lang_output_section_statement_type *first_os = NULL;
   lang_output_section_statement_type *last_os = NULL;
+  lang_output_section_statement_type *os;
 
   /* "start of list" is actually the statement immediately after
      the special abs_section output statement, so that it isn't
@@ -3415,6 +3390,12 @@ process_insert_statements (void)
 	  /* Keep pointers to the first and last output section
 	     statement in the sequence we may be about to move.  */
 	  last_os = &(*s)->output_section_statement;
+
+	  /* Set constraint negative so that lang_output_section_find
+	     won't match this output section statement.  At this
+	     stage in linking constraint has values in the range
+	     [-1, ONLY_IN_RW].  */
+	  last_os->constraint = -2 - last_os->constraint;
 	  if (first_os == NULL)
 	    first_os = last_os;
 	}
@@ -3422,7 +3403,6 @@ process_insert_statements (void)
 	{
 	  lang_insert_statement_type *i = &(*s)->insert_statement;
 	  lang_output_section_statement_type *where;
-	  lang_output_section_statement_type *os;
 	  lang_statement_union_type **ptr;
 	  lang_statement_union_type *first;
 
@@ -3431,21 +3411,12 @@ process_insert_statements (void)
 	    {
 	      do
 		where = where->prev;
-	      while (where != NULL && where->constraint == -1);
+	      while (where != NULL && where->constraint < 0);
 	    }
 	  if (where == NULL)
 	    {
-	      einfo (_("%X%P: %s not found for insert\n"), i->where);
-	      continue;
-	    }
-	  /* You can't insert into the list you are moving.  */
-	  for (os = first_os; os != NULL; os = os->next)
-	    if (os == where || os == last_os)
-	      break;
-	  if (os == where)
-	    {
-	      einfo (_("%X%P: %s not found for insert\n"), i->where);
-	      continue;
+	      einfo (_("%F%P: %s not found for insert\n"), i->where);
+	      return;
 	    }
 
 	  /* Deal with reordering the output section statement list.  */
@@ -3482,6 +3453,7 @@ process_insert_statements (void)
 	      last_sec = NULL;
 	      for (os = first_os; os != NULL; os = os->next)
 		{
+		  os->constraint = -2 - os->constraint;
 		  if (os->bfd_section != NULL
 		      && os->bfd_section->owner != NULL)
 		    {
@@ -3542,6 +3514,14 @@ process_insert_statements (void)
 	  s = &lang_output_section_statement.head;
 	}
     }
+
+  /* Undo constraint twiddling.  */
+  for (os = first_os; os != NULL; os = os->next)
+    {
+      os->constraint = -2 - os->constraint;
+      if (os == last_os)
+	break;
+    }
 }
 
 /* An output section might have been removed after its statement was
@@ -3569,7 +3549,7 @@ strip_excluded_output_sections (void)
       asection *output_section;
       bfd_boolean exclude;
 
-      if (os->constraint == -1)
+      if (os->constraint < 0)
 	continue;
 
       output_section = os->bfd_section;
@@ -5665,11 +5645,9 @@ lang_place_orphans (void)
 		      || command_line.force_common_definition)
 		    {
 		      if (default_common_section == NULL)
-			{
-			  default_common_section =
-			    lang_output_section_statement_lookup (".bss");
-
-			}
+			default_common_section
+			  = lang_output_section_statement_lookup (".bss", 0,
+								  TRUE);
 		      lang_add_section (&default_common_section->children, s,
 					default_common_section);
 		    }
@@ -5680,7 +5658,7 @@ lang_place_orphans (void)
 		{
 		  lang_output_section_statement_type *os;
 
-		  os = lang_output_section_statement_lookup (s->name);
+		  os = lang_output_section_statement_lookup (s->name, 0, TRUE);
 		  lang_add_section (&os->children, s, os);
 		}
 	    }
@@ -5827,12 +5805,10 @@ lang_enter_output_section_statement (con
 {
   lang_output_section_statement_type *os;
 
-  os = lang_output_section_statement_lookup_1 (output_section_statement_name,
-					       constraint);
+  os = lang_output_section_statement_lookup (output_section_statement_name,
+					     constraint, TRUE);
   current_section = os;
 
-  /* Make next things chain into subchain of this.  */
-
   if (os->addr_tree == NULL)
     {
       os->addr_tree = address_exp;
@@ -5843,6 +5819,8 @@ lang_enter_output_section_statement (con
   else
     os->flags = SEC_NEVER_LOAD;
   os->block_value = 1;
+
+  /* Make next things chain into subchain of this.  */
   stat_ptr = &os->children;
 
   os->subsection_alignment =
@@ -6639,7 +6617,7 @@ lang_record_phdrs (void)
 	{
 	  lang_output_section_phdr_list *pl;
 
-	  if (os->constraint == -1)
+	  if (os->constraint < 0)
 	    continue;
 
 	  pl = os->phdrs;
@@ -6720,7 +6698,7 @@ lang_record_phdrs (void)
     {
       lang_output_section_phdr_list *pl;
 
-      if (os->constraint == -1
+      if (os->constraint < 0
 	  || os->bfd_section == NULL)
 	continue;
 
Index: ld/ldlang.h
===================================================================
RCS file: /cvs/src/src/ld/ldlang.h,v
retrieving revision 1.78
diff -u -p -r1.78 ldlang.h
--- ld/ldlang.h	17 Aug 2008 03:12:50 -0000	1.78
+++ ld/ldlang.h	6 Sep 2008 00:04:54 -0000
@@ -525,12 +525,13 @@ extern void lang_do_assignments
        statement != (lang_input_statement_type *) NULL;			\
        statement = (lang_input_statement_type *) statement->next)	\
 
+#define lang_output_section_find(NAME) \
+  lang_output_section_statement_lookup (NAME, 0, FALSE)
+
 extern void lang_process
   (void);
 extern void ldlang_add_file
   (lang_input_statement_type *);
-extern lang_output_section_statement_type *lang_output_section_find
-  (const char * const);
 extern lang_output_section_statement_type *lang_output_section_find_by_flags
   (const asection *, lang_output_section_statement_type **,
    lang_match_sec_type_func);
@@ -541,9 +542,8 @@ extern lang_input_statement_type *lang_a
   (const char *, lang_input_file_enum_type, const char *);
 extern void lang_add_keepsyms_file
   (const char *);
-extern lang_output_section_statement_type *
-  lang_output_section_statement_lookup
-  (const char *const);
+extern lang_output_section_statement_type *lang_output_section_statement_lookup
+  (const char *const, int, bfd_boolean);
 extern void ldlang_add_undef
   (const char *const);
 extern void lang_add_output_format
Index: ld/emultempl/beos.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/beos.em,v
retrieving revision 1.39
diff -u -p -r1.39 beos.em
--- ld/emultempl/beos.em	15 Feb 2008 03:35:53 -0000	1.39
+++ ld/emultempl/beos.em	6 Sep 2008 00:04:55 -0000
@@ -697,7 +697,7 @@ gld${EMULATION_NAME}_place_orphan (asect
   output_secname = xstrdup (secname);
   ps = strchr (output_secname + 1, '\$');
   *ps = 0;
-  os = lang_output_section_statement_lookup (output_secname);
+  os = lang_output_section_statement_lookup (output_secname, 0, TRUE);
 
   /* Find the '\$' wild statement for this section.  We currently require the
      linker script to explicitly mention "*(.foo\$)".
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.191
diff -u -p -r1.191 elf32.em
--- ld/emultempl/elf32.em	8 Aug 2008 08:06:16 -0000	1.191
+++ ld/emultempl/elf32.em	6 Sep 2008 00:04:56 -0000
@@ -1583,7 +1583,7 @@ output_rel_find (asection *sec, int isdy
        lookup != NULL;
        lookup = lookup->next)
     {
-      if (lookup->constraint != -1
+      if (lookup->constraint >= 0
 	  && CONST_STRNEQ (lookup->name, ".rel"))
 	{
 	  int lookrela = lookup->name[4] == 'a';
Index: ld/emultempl/sunos.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/sunos.em,v
retrieving revision 1.30
diff -u -p -r1.30 sunos.em
--- ld/emultempl/sunos.em	15 Feb 2008 03:35:53 -0000	1.30
+++ ld/emultempl/sunos.em	6 Sep 2008 00:04:56 -0000
@@ -698,7 +698,7 @@ gld${EMULATION_NAME}_before_allocation (
 
       /* Set the .text section to start at 0x20, not 0x2020.  FIXME:
 	 This is too magical.  */
-      os = lang_output_section_statement_lookup (".text");
+      os = lang_output_section_statement_lookup (".text", 0, TRUE);
       if (os->addr_tree == NULL)
 	os->addr_tree = exp_intop (0x20);
     }

-- 
Alan Modra
Australia Development Lab, IBM


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