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.
This commit is contained in:
H.J. Lu 2005-10-15 14:57:55 +00:00
parent ff0929e51c
commit ecca98713a
12 changed files with 168 additions and 17 deletions

View 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.

View 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 *);

View 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

View File

@ -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);
}

View 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

View 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;
}

View 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

View 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 *);
.

View 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

View 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)

View 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 .

View 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;