bfd/
authorH.J. Lu <hjl.tools@gmail.com>
Sat, 15 Oct 2005 14:57:55 +0000 (14:57 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Sat, 15 Oct 2005 14:57:55 +0000 (14:57 +0000)
2005-10-15  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-15  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.

* ld.texinfo: Document orphan section processing.

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

12 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf-bfd.h
bfd/elf.c
bfd/libbfd-in.h
bfd/libbfd.c
bfd/libbfd.h
bfd/targets.c
ld/ChangeLog
ld/emultempl/elf32.em
ld/ld.texinfo
ld/ldlang.c

index fdf2809..e940c93 100644 (file)
@@ -1,3 +1,23 @@
+2005-10-15  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.
+
 2005-10-08  Paul Brook  <paul@codesourcery.com>
 
        * elf32-arm.c: Move #include "elf/arm.h" after libbfd.h.
index 3471081..1d93b0f 100644 (file)
@@ -4926,6 +4926,7 @@ typedef struct bfd_target
   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 \
@@ -4965,6 +4966,12 @@ typedef struct bfd_target
   /* 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 f4c0ed8..d011a45 100644 (file)
@@ -1474,6 +1474,10 @@ extern bfd_boolean _bfd_elf_slurp_version_tables
   (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
index 435622d..3a139a0 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -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);
+}
index 47595c6..0290c84 100644 (file)
@@ -399,6 +399,8 @@ extern bfd_boolean _bfd_generic_set_section_contents
   ((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 66137bb..3b27e08 100644 (file)
@@ -1033,3 +1033,12 @@ _bfd_generic_find_line (bfd *abfd ATTRIBUTE_UNUSED,
 {
   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;
+}
index 6f3650b..56ad092 100644 (file)
@@ -404,6 +404,8 @@ extern bfd_boolean _bfd_generic_set_section_contents
   ((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 dd5e097..271954f 100644 (file)
@@ -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 *);
 .
index dfa7317..20c5281 100644 (file)
@@ -1,3 +1,15 @@
+2005-10-15  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.
+
+       * ld.texinfo: Document orphan section processing.
+
+       * ldlang.c (lang_output_section_find_by_flags): Match section
+       types by calling bfd_match_sections_by_type.
+
 2005-10-13  Mark Mitchell  <mark@codesourcery.com>
 
        * ld.texino: Describe double-quoted string syntax for version
index 15d2722..e1e37f1 100644 (file)
@@ -53,6 +53,7 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
 #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_input_statement_type *file, asection *s)
   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_input_statement_type *file, asection *s)
       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_input_statement_type *file, asection *s)
   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_input_statement_type *file, asection *s)
     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)
index 238fde9..d7673fd 100644 (file)
@@ -4442,6 +4442,7 @@ expressions.
 @menu
 * Constants::                  Constants
 * Symbols::                    Symbol Names
+* Orphan Sections::            Orphan Sections
 * Location Counter::           The Location Counter
 * Operators::                  Operators
 * Evaluation::                 Evaluation
@@ -4503,6 +4504,22 @@ Since symbols can contain many non-alphabetic characters, it is safest
 to delimit symbols with spaces.  For example, @samp{A-B} is one symbol,
 whereas @samp{A - B} is an expression involving subtraction.
 
+@node Orphan Sections
+@subsection Orphan Sections
+@cindex orphan
+Orphan sections are sections present in the input files which
+are not explicitly placed into the output file by the linker
+script.  The linker will still copy these sections into the
+output file, but it has to guess as to where they should be
+placed.  The linker uses a simple heuristic to do this.  It
+attempts to place orphan sections after non-orphan sections of the
+same attribute, such as code vs data, loadable vs non-loadable, etc.
+If there is not enough room to do this then it places
+at the end of the file.
+
+For ELF targets, the attribute of the section includes section type as
+well as section flag.
+
 @node Location Counter
 @subsection The Location Counter
 @kindex .
index 3ff4d81..b82a7e5 100644 (file)
@@ -1149,7 +1149,13 @@ lang_output_section_find_by_flags (const asection *sec,
     {
       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 asection *sec,
        {
          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 asection *sec,
        {
          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 asection *sec,
        {
          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 asection *sec,
        {
          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 asection *sec,
     {
       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;