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: PATCH: ld/1467: Orphaned section is put in the odd place


On Wed, Oct 12, 2005 at 09:19:33AM -0400, Daniel Jacobowitz wrote:
> On Tue, Oct 11, 2005 at 10:49:33PM -0700, H. J. Lu wrote:
> > The ELF linker doesn't check section type and checks section name when
> > placing orphan. Both may lead to odd orphaned section placement. This
> > patch adds section type check and removes the section name check.
> 
> Hi HJ,
> 
> My biggest complaint about almost every patch you post is that you
> don't explain what you're doing.  What does "odd" mean here?  What does
> it look like before and after?  Is anything actually wrong?  Some bits
> of this patch are pretty obvious, but some I couldn't figure out by
> looking at them.
> 


Here is an updated patch to handle non-ELF input and reduce the code
duplication. The old section order is

  [ 1] .text             PROGBITS         0000000000000000  00100000
       0000000000000004  0000000000000000  AX       0     0     4
  [ 2] .data             PROGBITS         0000000000000004  00100004
       0000000000000004  0000000000000000  WA       0     0     4
  [ 3] .note             NOTE             0000000000000008  00100008
       0000000000000004  0000000000000000   A       0     0     1
  [ 4] .notbad           PROGBITS         000000000000000c  0010000c
       0000000000000004  0000000000000000   A       0     0     1
  [ 5] .note.bar         NOTE             0000000000000010  00100010
       0000000000000004  0000000000000000   A       0     0     1

where an orphaned PROGBITS section is placed between 2 NOTE sections.
The new one is

  [ 1] .text             PROGBITS         0000000000000000  00100000
       0000000000000004  0000000000000000  AX       0     0     4
  [ 2] .notbad           PROGBITS         0000000000000004  00100004
       0000000000000004  0000000000000000   A       0     0     1
  [ 3] .data             PROGBITS         0000000000000008  00100008
       0000000000000004  0000000000000000  WA       0     0     4
  [ 4] .note             NOTE             000000000000000c  0010000c
       0000000000000004  0000000000000000   A       0     0     1
  [ 5] .note.bar         NOTE             0000000000000010  00100010
       0000000000000004  0000000000000000   A       0     0     1


H.J.
----
bfd/

2005-10-12  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/1467
	* elf-bfd.h (_bfd_elf_match_sections_by_type): New.
	(_bfd_generic_match_sections_by_type): New. Defined.

	* elf.c (_bfd_elf_match_sections_by_type): New.

	* libbfd-in.h (_bfd_generic_match_sections_by_type): New.

	* bfd-in2.h: Regenerated.
	* libbfd.h: Likewise.

	* libbfd.c (_bfd_generic_match_sections_by_type): New.

	* targets.c (BFD_JUMP_TABLE_LINK): Initialize
	_bfd_match_sections_by_type with
	_bfd_generic_match_sections_by_type.
	(bfd_target): Add _bfd_match_sections_by_type.

ld/

2005-10-12  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/1467
	* emultempl/elf32.em: Include "elf-bfd.h".
	(gld${EMULATION_NAME}_place_orphan): Check section type and
	don't use section name for ELF input sections.

	* ldlang.c (lang_output_section_find_by_flags): Match section
	types by calling bfd_match_sections_by_type.

--- binutils/bfd/elf-bfd.h.orphan	2005-09-28 10:40:36.000000000 -0700
+++ binutils/bfd/elf-bfd.h	2005-10-12 10:39:22.000000000 -0700
@@ -1474,6 +1474,10 @@ extern bfd_boolean _bfd_elf_slurp_versio
   (bfd *, bfd_boolean);
 extern bfd_boolean _bfd_elf_merge_sections
   (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
--- binutils/bfd/elf.c.orphan	2005-10-07 13:47:31.000000000 -0700
+++ binutils/bfd/elf.c	2005-10-12 10:37:40.000000000 -0700
@@ -8502,3 +8502,18 @@ asection _bfd_elf_large_com_section
   = BFD_FAKE_SECTION (_bfd_elf_large_com_section,
 		      SEC_IS_COMMON, NULL, NULL, "LARGE_COMMON",
 		      0);
+
+/* Return TRUE if 2 section types are compatible.  */
+
+bfd_boolean
+_bfd_elf_match_sections_by_type (bfd *abfd, const asection *asec,
+				 bfd *bbfd, const asection *bsec)
+{
+  if (asec == NULL
+      || bsec == NULL
+      || abfd->xvec->flavour != bfd_target_elf_flavour
+      || bbfd->xvec->flavour != bfd_target_elf_flavour)
+    return TRUE;
+
+  return elf_section_type (asec) == elf_section_type (bsec);
+}
--- binutils/bfd/libbfd-in.h.orphan	2005-07-06 08:45:40.000000000 -0700
+++ binutils/bfd/libbfd-in.h	2005-10-12 10:37:54.000000000 -0700
@@ -399,6 +399,8 @@ 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
--- binutils/bfd/libbfd.c.orphan	2005-10-07 13:47:31.000000000 -0700
+++ binutils/bfd/libbfd.c	2005-10-12 10:38:09.000000000 -0700
@@ -1033,3 +1033,12 @@ _bfd_generic_find_line (bfd *abfd ATTRIB
 {
   return FALSE;
 }
+
+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;
+}
--- binutils/bfd/targets.c.orphan	2005-09-30 08:45:11.000000000 -0700
+++ binutils/bfd/targets.c	2005-10-12 10:39:49.000000000 -0700
@@ -427,6 +427,7 @@ 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 \
@@ -466,6 +467,12 @@ 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 *);
 .
--- binutils/ld/emultempl/elf32.em.orphan	2005-09-07 11:42:00.000000000 -0700
+++ binutils/ld/emultempl/elf32.em	2005-10-12 10:54:36.000000000 -0700
@@ -53,6 +53,7 @@ Foundation, Inc., 51 Franklin Street - F
 #include "ldemul.h"
 #include <ldgram.h>
 #include "elf/common.h"
+#include "elf-bfd.h"
 
 /* Declare functions used by various EXTRA_EM_FILEs.  */
 static void gld${EMULATION_NAME}_before_parse (void);
@@ -1324,19 +1325,34 @@ gld${EMULATION_NAME}_place_orphan (lang_
   lang_output_section_statement_type *after;
   lang_output_section_statement_type *os;
   int isdyn = 0;
+  int iself = s->owner->xvec->flavour == bfd_target_elf_flavour;
+  unsigned int sh_type = iself ? elf_section_type (s) : SHT_NULL;
 
   secname = bfd_get_section_name (s->owner, s);
 
   if (! link_info.relocatable
       && link_info.combreloc
-      && (s->flags & SEC_ALLOC)
-      && strncmp (secname, ".rel", 4) == 0)
+      && (s->flags & SEC_ALLOC))
     {
-      if (secname[4] == 'a')
-	secname = ".rela.dyn";
-      else
-	secname = ".rel.dyn";
-      isdyn = 1;
+      if (iself)
+	switch (sh_type)
+	  {
+	  case SHT_RELA:
+	    secname = ".rela.dyn";
+	    isdyn = 1;
+	    break;
+	  case SHT_REL:
+	    secname = ".rel.dyn";
+	    isdyn = 1;
+	    break;
+	  default:
+	    break;
+	  }
+      else if (strncmp (secname, ".rel", 4) == 0)
+	{
+	  secname = secname[4] == 'a' ? ".rela.dyn" : ".rel.dyn";
+	  isdyn = 1;
+	}
     }
 
   if (isdyn || (!config.unique_orphan_sections && !unique_section_p (s)))
@@ -1347,8 +1363,10 @@ gld${EMULATION_NAME}_place_orphan (lang_
       if (os != NULL
 	  && (os->bfd_section == NULL
 	      || os->bfd_section->flags == 0
-	      || ((s->flags ^ os->bfd_section->flags)
-		  & (SEC_LOAD | SEC_ALLOC)) == 0))
+	      || ((!iself
+		   || sh_type == elf_section_type (os->bfd_section))
+		  && ((s->flags ^ os->bfd_section->flags)
+		      & (SEC_LOAD | SEC_ALLOC)) == 0)))
 	{
 	  /* We already have an output section statement with this
 	     name, and its bfd section, if any, has compatible flags.
@@ -1395,7 +1413,8 @@ gld${EMULATION_NAME}_place_orphan (lang_
   if ((s->flags & SEC_ALLOC) == 0)
     ;
   else if ((s->flags & SEC_LOAD) != 0
-	   && strncmp (secname, ".note", 5) == 0)
+	   && ((iself && sh_type == SHT_NOTE)
+	       || (!iself && strncmp (secname, ".note", 5) == 0)))
     place = &hold[orphan_interp];
   else if ((s->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
     place = &hold[orphan_bss];
@@ -1403,7 +1422,8 @@ gld${EMULATION_NAME}_place_orphan (lang_
     place = &hold[orphan_sdata];
   else if ((s->flags & SEC_READONLY) == 0)
     place = &hold[orphan_data];
-  else if (strncmp (secname, ".rel", 4) == 0
+  else if (((iself && (sh_type == SHT_RELA || sh_type == SHT_REL))
+	    || (!iself && strncmp (secname, ".rel", 4) == 0))
 	   && (s->flags & SEC_LOAD) != 0)
     place = &hold[orphan_rel];
   else if ((s->flags & SEC_CODE) == 0)
--- binutils/ld/ldlang.c.orphan	2005-10-04 09:28:29.000000000 -0700
+++ binutils/ld/ldlang.c	2005-10-12 10:41:17.000000000 -0700
@@ -1149,7 +1149,13 @@ lang_output_section_find_by_flags (const
     {
       flags = look->flags;
       if (look->bfd_section != NULL)
-	flags = look->bfd_section->flags;
+	{
+	  flags = look->bfd_section->flags;
+	  if (!bfd_match_sections_by_type (output_bfd,
+					   look->bfd_section,
+					   sec->owner, sec))
+	    continue;
+	}
       flags ^= sec->flags;
       if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY
 		     | SEC_CODE | SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
@@ -1168,7 +1174,13 @@ lang_output_section_find_by_flags (const
 	{
 	  flags = look->flags;
 	  if (look->bfd_section != NULL)
-	    flags = look->bfd_section->flags;
+	    {
+	      flags = look->bfd_section->flags;
+	      if (!bfd_match_sections_by_type (output_bfd,
+					       look->bfd_section,
+					       sec->owner, sec))
+		continue;
+	    }
 	  flags ^= sec->flags;
 	  if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
 			 | SEC_CODE | SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
@@ -1184,7 +1196,13 @@ lang_output_section_find_by_flags (const
 	{
 	  flags = look->flags;
 	  if (look->bfd_section != NULL)
-	    flags = look->bfd_section->flags;
+	    {
+	      flags = look->bfd_section->flags;
+	      if (!bfd_match_sections_by_type (output_bfd,
+					       look->bfd_section,
+					       sec->owner, sec))
+		continue;
+	    }
 	  flags ^= sec->flags;
 	  if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
 			 | SEC_READONLY))
@@ -1201,7 +1219,13 @@ lang_output_section_find_by_flags (const
 	{
 	  flags = look->flags;
 	  if (look->bfd_section != NULL)
-	    flags = look->bfd_section->flags;
+	    {
+	      flags = look->bfd_section->flags;
+	      if (!bfd_match_sections_by_type (output_bfd,
+					       look->bfd_section,
+					       sec->owner, sec))
+		continue;
+	    }
 	  flags ^= sec->flags;
 	  if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
 			 | SEC_THREAD_LOCAL))
@@ -1219,7 +1243,13 @@ lang_output_section_find_by_flags (const
 	{
 	  flags = look->flags;
 	  if (look->bfd_section != NULL)
-	    flags = look->bfd_section->flags;
+	    {
+	      flags = look->bfd_section->flags;
+	      if (!bfd_match_sections_by_type (output_bfd,
+					       look->bfd_section,
+					       sec->owner, sec))
+		continue;
+	    }
 	  flags ^= sec->flags;
 	  if (!(flags & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
 			 | SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
@@ -1233,7 +1263,13 @@ lang_output_section_find_by_flags (const
     {
       flags = look->flags;
       if (look->bfd_section != NULL)
-	flags = look->bfd_section->flags;
+	{
+	  flags = look->bfd_section->flags;
+	  if (!bfd_match_sections_by_type (output_bfd,
+					   look->bfd_section,
+					   sec->owner, sec))
+	    continue;
+	}
       flags ^= sec->flags;
       if (!(flags & SEC_ALLOC))
 	found = look;


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