Section sizing + orphan placement bugs

Alan Modra amodra@bigpond.net.au
Thu Nov 24 05:23:00 GMT 2005


On Thu, Nov 24, 2005 at 11:49:02AM +1030, Alan Modra wrote:
> On Thu, Nov 24, 2005 at 11:27:03AM +1030, Alan Modra wrote:
> > 	* ldlang.c (lang_insert_orphan): Skip first assignment to dot
> > 	in script when looking for place to insert orphan statements.
> 
> BTW, this causes "FAIL: map addresses".  When I first looked at the
> failure, I thought it was just a matter of tweaking the testsuite, but
> on looking closer I see that it's another case where
> lang_output_section_find_by_flags does the wrong thing since HJ's patch
> to check section type.

The simple fix of removing bfd_match_sections_by_type in the loop
looking for a place for .bss fixes the testcase, but I think this is
better.  Here, we give ELF section types priority over BFD section flags
for all sections.  I also removed bfd_match_sections_by_type from the
BFD target vector, as it seems likely to me that this function will only
ever be called from linker emulation files.

bfd/
	* elf-bfd.h (_bfd_generic_match_sections_by_type): Don't define.
	* libbfd-in.h (_bfd_generic_match_sections_by_type): Delete.
	* libbfd.c (_bfd_generic_match_sections_by_type): Delete.
	* targets.c (bfd_match_sections_by_type): Don't define.
	(BFD_JUMP_TABLE_LINK): Remove _bfd_generic_match_sections_by_type.
	* coff-rs6000.c (rs6000coff_vec, pmac_xcoff_vec): Likewise.
	* coff64-rs6000.c (rs6000coff64_vec, aix5coff64_vec): Likewise.
	* bfd-in2.h: Regenerate.
	* libbfd.h: Regenerate.

ld/
	* ldlang.c (lang_output_section_find_by_flags): Add match_type param.
	Run two passes, first using match_type, second without.
	* ldlang.h (lang_match_sec_type_func): New typedef.
	(lang_output_section_find_by_flags): Update prototype.
	* emultempl/elf32.em (place_orphan): Update calls to
	bfd_match_sections_by_type and lang_output_section_find_by_flags.
	* emultempl/pe.em (place_orphan): Likewise.

Index: bfd/coff-rs6000.c
===================================================================
RCS file: /cvs/src/src/bfd/coff-rs6000.c,v
retrieving revision 1.74
diff -u -p -r1.74 coff-rs6000.c
--- bfd/coff-rs6000.c	24 Oct 2005 02:50:27 -0000	1.74
+++ bfd/coff-rs6000.c	24 Nov 2005 04:25:01 -0000
@@ -4196,7 +4196,6 @@ const bfd_target rs6000coff_vec =
     _bfd_generic_link_split_section,
     bfd_generic_gc_sections,
     bfd_generic_merge_sections,
-    _bfd_generic_match_sections_by_type,
     bfd_generic_is_group_section,
     bfd_generic_discard_group,
     _bfd_generic_section_already_linked,
@@ -4447,7 +4446,6 @@ const bfd_target pmac_xcoff_vec =
     _bfd_generic_link_split_section,
     bfd_generic_gc_sections,
     bfd_generic_merge_sections,
-    _bfd_generic_match_sections_by_type,
     bfd_generic_is_group_section,
     bfd_generic_discard_group,
     _bfd_generic_section_already_linked,
Index: bfd/coff64-rs6000.c
===================================================================
RCS file: /cvs/src/src/bfd/coff64-rs6000.c,v
retrieving revision 1.65
diff -u -p -r1.65 coff64-rs6000.c
--- bfd/coff64-rs6000.c	24 Oct 2005 02:50:27 -0000	1.65
+++ bfd/coff64-rs6000.c	24 Nov 2005 04:25:04 -0000
@@ -2743,7 +2743,6 @@ const bfd_target rs6000coff64_vec =
     _bfd_generic_link_split_section,
     bfd_generic_gc_sections,
     bfd_generic_merge_sections,
-    _bfd_generic_match_sections_by_type,
     bfd_generic_is_group_section,
     bfd_generic_discard_group,
     _bfd_generic_section_already_linked,
@@ -2995,7 +2994,6 @@ const bfd_target aix5coff64_vec =
     _bfd_generic_link_split_section,
     bfd_generic_gc_sections,
     bfd_generic_merge_sections,
-    _bfd_generic_match_sections_by_type,
     bfd_generic_is_group_section,
     bfd_generic_discard_group,
     _bfd_generic_section_already_linked,
Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.199
diff -u -p -r1.199 elf-bfd.h
--- bfd/elf-bfd.h	25 Oct 2005 16:19:06 -0000	1.199
+++ bfd/elf-bfd.h	24 Nov 2005 04:25:09 -0000
@@ -1476,8 +1476,6 @@ extern bfd_boolean _bfd_elf_merge_sectio
   (bfd *, struct bfd_link_info *);
 extern bfd_boolean _bfd_elf_match_sections_by_type
   (bfd *, const asection *, bfd *, const asection *);
-#define _bfd_generic_match_sections_by_type \
-  _bfd_elf_match_sections_by_type
 extern bfd_boolean bfd_elf_is_group_section
   (bfd *, const struct bfd_section *);
 extern void _bfd_elf_section_already_linked
Index: bfd/libbfd-in.h
===================================================================
RCS file: /cvs/src/src/bfd/libbfd-in.h,v
retrieving revision 1.59
diff -u -p -r1.59 libbfd-in.h
--- bfd/libbfd-in.h	3 Nov 2005 16:06:11 -0000	1.59
+++ bfd/libbfd-in.h	24 Nov 2005 04:25:28 -0000
@@ -402,8 +402,6 @@ extern bfd_boolean _bfd_generic_set_sect
   ((bfd_boolean (*) (bfd *, struct bfd_section *)) bfd_false)
 #define _bfd_nolink_section_already_linked \
   ((void (*) (bfd *, struct bfd_section *)) bfd_void)
-extern bfd_boolean _bfd_generic_match_sections_by_type
-  (bfd *, const asection *, bfd *, const asection *);
 
 /* Routines to use for BFD_JUMP_TABLE_DYNAMIC for targets which do not
    have dynamic symbols or relocs.  Use BFD_JUMP_TABLE_DYNAMIC
Index: bfd/libbfd.c
===================================================================
RCS file: /cvs/src/src/bfd/libbfd.c,v
retrieving revision 1.43
diff -u -p -r1.43 libbfd.c
--- bfd/libbfd.c	24 Oct 2005 01:40:58 -0000	1.43
+++ bfd/libbfd.c	24 Nov 2005 04:25:28 -0000
@@ -1035,15 +1035,6 @@ _bfd_generic_find_line (bfd *abfd ATTRIB
 }
 
 bfd_boolean
-_bfd_generic_match_sections_by_type (bfd *abfd ATTRIBUTE_UNUSED,
-				     const asection *asec ATTRIBUTE_UNUSED,
-				     bfd *bbfd ATTRIBUTE_UNUSED,
-				     const asection *bsec ATTRIBUTE_UNUSED)
-{
-  return TRUE;
-}
-
-bfd_boolean
 _bfd_generic_init_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
 					asection *isec ATTRIBUTE_UNUSED,
 					bfd *obfd ATTRIBUTE_UNUSED,
Index: bfd/targets.c
===================================================================
RCS file: /cvs/src/src/bfd/targets.c,v
retrieving revision 1.139
diff -u -p -r1.139 targets.c
--- bfd/targets.c	25 Oct 2005 17:40:10 -0000	1.139
+++ bfd/targets.c	24 Nov 2005 04:25:35 -0000
@@ -434,7 +434,6 @@ BFD_JUMP_TABLE macros.
 .  NAME##_bfd_link_split_section, \
 .  NAME##_bfd_gc_sections, \
 .  NAME##_bfd_merge_sections, \
-.  _bfd_generic_match_sections_by_type, \
 .  NAME##_bfd_is_group_section, \
 .  NAME##_bfd_discard_group, \
 .  NAME##_section_already_linked \
@@ -474,12 +473,6 @@ BFD_JUMP_TABLE macros.
 .  {* Attempt to merge SEC_MERGE sections.  *}
 .  bfd_boolean (*_bfd_merge_sections) (bfd *, struct bfd_link_info *);
 .
-.#define bfd_match_sections_by_type(abfd, asec, bbfd, bsec) \
-.  BFD_SEND (abfd, _bfd_match_sections_by_type, (abfd, asec, bbfd, bsec))
-.  {* Return TRUE if 2 section types are compatible.  *}
-.  bfd_boolean (*_bfd_match_sections_by_type)
-.    (bfd *, const asection *, bfd *, const asection *);
-.
 .  {* Is this section a member of a group?  *}
 .  bfd_boolean (*_bfd_is_group_section) (bfd *, const struct bfd_section *);
 .
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.209
diff -u -p -r1.209 ldlang.c
--- ld/ldlang.c	24 Nov 2005 00:58:28 -0000	1.209
+++ ld/ldlang.c	24 Nov 2005 04:26:02 -0000
@@ -1147,7 +1147,8 @@ lang_output_section_statement_lookup (co
 
 lang_output_section_statement_type *
 lang_output_section_find_by_flags (const asection *sec,
-				   lang_output_section_statement_type **exact)
+				   lang_output_section_statement_type **exact,
+				   lang_match_sec_type_func match_type)
 {
   lang_output_section_statement_type *first, *look, *found;
   flagword flags;
@@ -1165,9 +1166,8 @@ lang_output_section_find_by_flags (const
       if (look->bfd_section != NULL)
 	{
 	  flags = look->bfd_section->flags;
-	  if (!bfd_match_sections_by_type (output_bfd,
-					   look->bfd_section,
-					   sec->owner, sec))
+	  if (match_type && !match_type (output_bfd, look->bfd_section,
+					 sec->owner, sec))
 	    continue;
 	}
       flags ^= sec->flags;
@@ -1177,7 +1177,8 @@ lang_output_section_find_by_flags (const
     }
   if (found != NULL)
     {
-      *exact = found;
+      if (exact != NULL)
+	*exact = found;
       return found;
     }
 
@@ -1190,9 +1191,8 @@ lang_output_section_find_by_flags (const
 	  if (look->bfd_section != NULL)
 	    {
 	      flags = look->bfd_section->flags;
-	      if (!bfd_match_sections_by_type (output_bfd,
-					       look->bfd_section,
-					       sec->owner, sec))
+	      if (match_type && !match_type (output_bfd, look->bfd_section,
+					     sec->owner, sec))
 		continue;
 	    }
 	  flags ^= sec->flags;
@@ -1200,10 +1200,8 @@ lang_output_section_find_by_flags (const
 			 | SEC_CODE | SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
 	    found = look;
 	}
-      return found;
     }
-
-  if (sec->flags & (SEC_READONLY | SEC_THREAD_LOCAL))
+  else if (sec->flags & (SEC_READONLY | SEC_THREAD_LOCAL))
     {
       /* .rodata can go after .text, .sdata2 after .rodata.  */
       for (look = first; look; look = look->next)
@@ -1212,9 +1210,8 @@ lang_output_section_find_by_flags (const
 	  if (look->bfd_section != NULL)
 	    {
 	      flags = look->bfd_section->flags;
-	      if (!bfd_match_sections_by_type (output_bfd,
-					       look->bfd_section,
-					       sec->owner, sec))
+	      if (match_type && !match_type (output_bfd, look->bfd_section,
+					     sec->owner, sec))
 		continue;
 	    }
 	  flags ^= sec->flags;
@@ -1223,10 +1220,8 @@ lang_output_section_find_by_flags (const
 	      && !(look->flags & (SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
 	    found = look;
 	}
-      return found;
     }
-
-  if (sec->flags & SEC_SMALL_DATA)
+  else if (sec->flags & SEC_SMALL_DATA)
     {
       /* .sdata goes after .data, .sbss after .sdata.  */
       for (look = first; look; look = look->next)
@@ -1235,9 +1230,8 @@ lang_output_section_find_by_flags (const
 	  if (look->bfd_section != NULL)
 	    {
 	      flags = look->bfd_section->flags;
-	      if (!bfd_match_sections_by_type (output_bfd,
-					       look->bfd_section,
-					       sec->owner, sec))
+	      if (match_type && !match_type (output_bfd, look->bfd_section,
+					     sec->owner, sec))
 		continue;
 	    }
 	  flags ^= sec->flags;
@@ -1247,10 +1241,8 @@ lang_output_section_find_by_flags (const
 		  && !(sec->flags & SEC_HAS_CONTENTS)))
 	    found = look;
 	}
-      return found;
     }
-
-  if (sec->flags & SEC_HAS_CONTENTS)
+  else if (sec->flags & SEC_HAS_CONTENTS)
     {
       /* .data goes after .rodata.  */
       for (look = first; look; look = look->next)
@@ -1259,9 +1251,8 @@ lang_output_section_find_by_flags (const
 	  if (look->bfd_section != NULL)
 	    {
 	      flags = look->bfd_section->flags;
-	      if (!bfd_match_sections_by_type (output_bfd,
-					       look->bfd_section,
-					       sec->owner, sec))
+	      if (match_type && !match_type (output_bfd, look->bfd_section,
+					     sec->owner, sec))
 		continue;
 	    }
 	  flags ^= sec->flags;
@@ -1269,27 +1260,30 @@ lang_output_section_find_by_flags (const
 			 | SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
 	    found = look;
 	}
-      return found;
     }
-
-  /* .bss goes last.  */
-  for (look = first; look; look = look->next)
+  else
     {
-      flags = look->flags;
-      if (look->bfd_section != NULL)
+      /* .bss goes last.  */
+      for (look = first; look; look = look->next)
 	{
-	  flags = look->bfd_section->flags;
-	  if (!bfd_match_sections_by_type (output_bfd,
-					   look->bfd_section,
-					   sec->owner, sec))
-	    continue;
+	  flags = look->flags;
+	  if (look->bfd_section != NULL)
+	    {
+	      flags = look->bfd_section->flags;
+	      if (match_type && !match_type (output_bfd, look->bfd_section,
+					     sec->owner, sec))
+		continue;
+	    }
+	  flags ^= sec->flags;
+	  if (!(flags & SEC_ALLOC))
+	    found = look;
 	}
-      flags ^= sec->flags;
-      if (!(flags & SEC_ALLOC))
-	found = look;
     }
 
-  return found;
+  if (found || !match_type)
+    return found;
+
+  return lang_output_section_find_by_flags (sec, NULL, NULL);
 }
 
 /* Find the last output section before given output statement.
Index: ld/ldlang.h
===================================================================
RCS file: /cvs/src/src/ld/ldlang.h,v
retrieving revision 1.57
diff -u -p -r1.57 ldlang.h
--- ld/ldlang.h	17 Nov 2005 00:10:05 -0000	1.57
+++ ld/ldlang.h	24 Nov 2005 04:26:02 -0000
@@ -304,6 +304,9 @@ typedef void (*walk_wild_section_handler
 					     callback_t callback,
 					     void *data);
 
+typedef bfd_boolean (*lang_match_sec_type_func) (bfd *, const asection *,
+						 bfd *, const asection *);
+
 struct lang_wild_statement_struct
 {
   lang_statement_header_type header;
@@ -521,7 +524,8 @@ extern void ldlang_add_file
 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 **exact);
+  (const asection *, lang_output_section_statement_type **,
+   lang_match_sec_type_func);
 extern lang_output_section_statement_type *lang_insert_orphan
   (asection *, const char *, lang_output_section_statement_type *,
    struct orphan_save *, etree_type *, lang_statement_list_type *);
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.159
diff -u -p -r1.159 elf32.em
--- ld/emultempl/elf32.em	17 Nov 2005 00:10:05 -0000	1.159
+++ ld/emultempl/elf32.em	24 Nov 2005 04:26:05 -0000
@@ -1362,9 +1362,9 @@ gld${EMULATION_NAME}_place_orphan (asect
       if (os != NULL
 	  && (os->bfd_section == NULL
 	      || os->bfd_section->flags == 0
-	      || (bfd_match_sections_by_type (output_bfd,
-					      os->bfd_section,
-					      s->owner, s)
+	      || (_bfd_elf_match_sections_by_type (output_bfd,
+						   os->bfd_section,
+						   s->owner, s)
 		  && ((s->flags ^ os->bfd_section->flags)
 		      & (SEC_LOAD | SEC_ALLOC)) == 0)))
 	{
@@ -1443,7 +1443,8 @@ gld${EMULATION_NAME}_place_orphan (asect
 	}
       after = place->os;
       if (after == NULL)
-	after = lang_output_section_find_by_flags (s, &place->os);
+	after = lang_output_section_find_by_flags
+	  (s, &place->os, _bfd_elf_match_sections_by_type);
       if (after == NULL)
 	/* *ABS* is always the first output section statement.  */
 	after = &lang_output_section_statement.head->output_section_statement;
Index: ld/emultempl/pe.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pe.em,v
retrieving revision 1.112
diff -u -p -r1.112 pe.em
--- ld/emultempl/pe.em	17 Nov 2005 00:10:05 -0000	1.112
+++ ld/emultempl/pe.em	24 Nov 2005 04:26:06 -0000
@@ -1621,7 +1621,7 @@ gld_${EMULATION_NAME}_place_orphan (asec
 	    place->os = lang_output_section_find (place->name);
 	  after = place->os;
 	  if (after == NULL)
-	    after = lang_output_section_find_by_flags (s, &place->os);
+	    after = lang_output_section_find_by_flags (s, &place->os, NULL);
 	  if (after == NULL)
 	    /* *ABS* is always the first output section statement.  */
 	    after = (&lang_output_section_statement.head

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre



More information about the Binutils mailing list