aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2005-10-15 14:57:55 +0000
committerH.J. Lu <hjl.tools@gmail.com>2005-10-15 14:57:55 +0000
commitecca98713a19ac7aac31886b4b15b806e63d9a99 (patch)
tree8606d4daeccd04e698371f934ba62278dd283d25 /ld
parentff0929e51c0e9c26e0cf1e6b7229803ccd7cc769 (diff)
downloadfsf-binutils-gdb-ecca98713a19ac7aac31886b4b15b806e63d9a99.zip
fsf-binutils-gdb-ecca98713a19ac7aac31886b4b15b806e63d9a99.tar.gz
fsf-binutils-gdb-ecca98713a19ac7aac31886b4b15b806e63d9a99.tar.bz2
bfd/
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.
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog12
-rw-r--r--ld/emultempl/elf32.em42
-rw-r--r--ld/ld.texinfo17
-rw-r--r--ld/ldlang.c48
4 files changed, 102 insertions, 17 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index dfa7317..20c5281 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -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
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 15d2722..e1e37f1 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -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)
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 238fde9..d7673fd 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -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 .
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 3ff4d81..b82a7e5 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -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;