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]

PR19162, Orphan output section with multiple input sections


If given input sections with differing flags, we'd like to place the
section according to the final output section flags.

bfd/
	PR ld/19162
	* elflink.c (_bfd_elf_gc_mark_reloc): Move code iterating over
	linker input bfds..
	* section.c (bfd_get_next_section_by_name): ..to here.  Add ibfd param.
	(bfd_get_linker_section): Adjust bfd_get_next_section_by_name call.
	* tekhex.c (first_phase): Likewise.
	* elflink.c (bfd_elf_gc_sections): Likewise.
	* bfd-in2.h: Regenerate.
ld/
	PR ld/19162
	* emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Check flags
	before calling _bfd_elf_match_sections_by_type.  Merge flags for
	any other input sections that might match a new output section to
	decide placement.

diff --git a/bfd/elflink.c b/bfd/elflink.c
index 1cfdd31..1b41c79 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -12179,8 +12179,6 @@ _bfd_elf_gc_mark_reloc (struct bfd_link_info *info,
   rsec = _bfd_elf_gc_mark_rsec (info, sec, gc_mark_hook, cookie, &start_stop);
   while (rsec != NULL)
     {
-      asection *s;
-
       if (!rsec->gc_mark)
 	{
 	  if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour
@@ -12191,22 +12189,7 @@ _bfd_elf_gc_mark_reloc (struct bfd_link_info *info,
 	}
       if (!start_stop)
 	break;
-      s = bfd_get_next_section_by_name (rsec);
-      if (s == NULL)
-	{
-	  bfd *i = rsec->owner;
-
-	  if (i != NULL)
-	    {
-	      while ((i = i->link.next) != NULL)
-		{
-		  s = bfd_get_section_by_name (i, rsec->name);
-		  if (s != NULL)
-		    break;
-		}
-	    }
-	}
-      rsec = s;
+      rsec = bfd_get_next_section_by_name (rsec->owner, rsec);
     }
   return TRUE;
 }
@@ -12757,7 +12740,7 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
 	      && (sec->flags & SEC_LINKER_CREATED) == 0)
 	    elf_eh_frame_section (sub) = sec;
 	  fini_reloc_cookie_for_section (&cookie, sec);
-	  sec = bfd_get_next_section_by_name (sec);
+	  sec = bfd_get_next_section_by_name (NULL, sec);
 	}
     }
 
diff --git a/bfd/section.c b/bfd/section.c
index 834a9ab..247d98a 100644
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -903,16 +903,18 @@ FUNCTION
        bfd_get_next_section_by_name
 
 SYNOPSIS
-       asection *bfd_get_next_section_by_name (asection *sec);
+       asection *bfd_get_next_section_by_name (bfd *ibfd, asection *sec);
 
 DESCRIPTION
        Given @var{sec} is a section returned by @code{bfd_get_section_by_name},
        return the next most recently created section attached to the same
-       BFD with the same name.  Return NULL if no such section exists.
+       BFD with the same name, or if no such section exists in the same BFD and
+       IBFD is non-NULL, the next section with the same name in any input
+       BFD following IBFD.  Return NULL on finding no section.
 */
 
 asection *
-bfd_get_next_section_by_name (asection *sec)
+bfd_get_next_section_by_name (bfd *ibfd, asection *sec)
 {
   struct section_hash_entry *sh;
   const char *name;
@@ -930,6 +932,16 @@ bfd_get_next_section_by_name (asection *sec)
        && strcmp (sh->root.string, name) == 0)
       return &sh->section;
 
+  if (ibfd != NULL)
+    {
+      while ((ibfd = ibfd->link.next) != NULL)
+	{
+	  asection *s = bfd_get_section_by_name (ibfd, name);
+	  if (s != NULL)
+	    return s;
+	}
+    }
+
   return NULL;
 }
 
@@ -951,7 +963,7 @@ bfd_get_linker_section (bfd *abfd, const char *name)
   asection *sec = bfd_get_section_by_name (abfd, name);
 
   while (sec != NULL && (sec->flags & SEC_LINKER_CREATED) == 0)
-    sec = bfd_get_next_section_by_name (sec);
+    sec = bfd_get_next_section_by_name (NULL, sec);
   return sec;
 }
 
diff --git a/bfd/tekhex.c b/bfd/tekhex.c
index ccc68f9..951c327 100644
--- a/bfd/tekhex.c
+++ b/bfd/tekhex.c
@@ -459,7 +459,8 @@ first_phase (bfd *abfd, int type, char *src, char * src_end)
 		    else
 		      {
 			if (alt_section == NULL)
-			  alt_section = bfd_get_next_section_by_name (section);
+			  alt_section
+			    = bfd_get_next_section_by_name (NULL, section);
 			if (alt_section == NULL)
 			  alt_section = bfd_make_section_anyway_with_flags
 			    (abfd, section->name,
@@ -476,7 +477,8 @@ first_phase (bfd *abfd, int type, char *src, char * src_end)
 		    else
 		      {
 			if (alt_section == NULL)
-			  alt_section = bfd_get_next_section_by_name (section);
+			  alt_section
+			    = bfd_get_next_section_by_name (NULL, section);
 			if (alt_section == NULL)
 			  alt_section = bfd_make_section_anyway_with_flags
 			    (abfd, section->name,
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 1dc215f..629c414 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -1852,6 +1852,8 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
   int isdyn = 0;
   int iself = s->owner->xvec->flavour == bfd_target_elf_flavour;
   unsigned int sh_type = iself ? elf_section_type (s) : SHT_NULL;
+  flagword flags;
+  asection *nexts;
 
   if (!bfd_link_relocatable (&link_info)
       && link_info.combreloc
@@ -1890,11 +1892,11 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
 
 	if (os->bfd_section != NULL
 	    && (os->bfd_section->flags == 0
-		|| (_bfd_elf_match_sections_by_type (link_info.output_bfd,
-						     os->bfd_section,
-						     s->owner, s)
-		    && ((s->flags ^ os->bfd_section->flags)
-			& (SEC_LOAD | SEC_ALLOC)) == 0)))
+		|| (((s->flags ^ os->bfd_section->flags)
+		     & (SEC_LOAD | SEC_ALLOC)) == 0
+		    && _bfd_elf_match_sections_by_type (link_info.output_bfd,
+							os->bfd_section,
+							s->owner, s))))
 	  {
 	    /* We already have an output section statement with this
 	       name, and its bfd section has compatible flags.
@@ -1950,28 +1952,41 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
      stored right after the program headers where the OS can read it
      in the first page.  */
 
+  flags = s->flags;
+  nexts = s;
+  while ((nexts = bfd_get_next_section_by_name (nexts->owner, nexts)) != NULL)
+    if (nexts->output_section == NULL
+	&& (nexts->flags & SEC_EXCLUDE) == 0
+	&& ((nexts->flags ^ flags) & (SEC_LOAD | SEC_ALLOC)) == 0
+	&& (nexts->owner->flags & DYNAMIC) == 0
+	&& nexts->owner->usrdata != NULL
+	&& !(((lang_input_statement_type *) nexts->owner->usrdata)
+	     ->flags.just_syms)
+	&& _bfd_elf_match_sections_by_type (nexts->owner, nexts, s->owner, s))
+      flags = (((flags ^ SEC_READONLY) | (nexts->flags ^ SEC_READONLY))
+	       ^ SEC_READONLY);
   place = NULL;
-  if ((s->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+  if ((flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
     place = &hold[orphan_nonalloc];
-  else if ((s->flags & SEC_ALLOC) == 0)
+  else if ((flags & SEC_ALLOC) == 0)
     ;
-  else if ((s->flags & SEC_LOAD) != 0
+  else if ((flags & SEC_LOAD) != 0
 	   && ((iself && sh_type == SHT_NOTE)
 	       || (!iself && CONST_STRNEQ (secname, ".note"))))
     place = &hold[orphan_interp];
-  else if ((s->flags & (SEC_LOAD | SEC_HAS_CONTENTS | SEC_THREAD_LOCAL)) == 0)
+  else if ((flags & (SEC_LOAD | SEC_HAS_CONTENTS | SEC_THREAD_LOCAL)) == 0)
     place = &hold[orphan_bss];
-  else if ((s->flags & SEC_SMALL_DATA) != 0)
+  else if ((flags & SEC_SMALL_DATA) != 0)
     place = &hold[orphan_sdata];
-  else if ((s->flags & SEC_THREAD_LOCAL) != 0)
+  else if ((flags & SEC_THREAD_LOCAL) != 0)
     place = &hold[orphan_tdata];
-  else if ((s->flags & SEC_READONLY) == 0)
+  else if ((flags & SEC_READONLY) == 0)
     place = &hold[orphan_data];
   else if (((iself && (sh_type == SHT_RELA || sh_type == SHT_REL))
 	    || (!iself && CONST_STRNEQ (secname, ".rel")))
-	   && (s->flags & SEC_LOAD) != 0)
+	   && (flags & SEC_LOAD) != 0)
     place = &hold[orphan_rel];
-  else if ((s->flags & SEC_CODE) == 0)
+  else if ((flags & SEC_CODE) == 0)
     place = &hold[orphan_rodata];
   else
     place = &hold[orphan_text];

-- 
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]