Add SORT_BY_INIT_PRIORITY.

bfd/

2010-12-15  H.J. Lu  <hongjiu.lu@intel.com>

	* elf.c (_bfd_elf_new_section_hook): Special handling for
	.init_array/.fini_array output sections.

ld/

2010-12-15  H.J. Lu  <hongjiu.lu@intel.com>

	* Makefile.am (GENSCRIPTS): Add @enable_initfini_array@.

	* NEWS: Mention SORT_BY_INIT_PRIORITY.

	* configure.in: Add AC_CANONICAL_BUILD.
	Add --enable-initfini-array.

	* genscripts.sh (ENABLE_INITFINI_ARRAY): New.

	* ld.h (sort_type): Add by_init_priority.

	* ld.texinfo: Document SORT_BY_INIT_PRIORITY.

	* ldgram.y (SORT_BY_INIT_PRIORITY): New.
	(wildcard_spec): Handle SORT_BY_INIT_PRIORITY.

	* ldlang.c (get_init_priority): New.
	(compare_section): Use get_init_priority for by_init_priority.

	* ldlex.l (SORT_BY_INIT_PRIORITY): New.

	* scripttempl/elf.sc: Support ENABLE_INITFINI_ARRAY.

	* Makefile.in: Regenerated.
	* aclocal.m4: Regenerated.
	* config.in: Likewise.
	* configure: Likewise.

ld/testsuite/

2010-12-15  H.J. Lu  <hongjiu.lu@intel.com>

	* ld-elf/elf.exp (array_tests): Add init-mixed.
	(array_tests_static): Likewise.
	Also delete tmpdir/init-mixed.

	* ld-elf/init-mixed.c: New.
	* ld-elf/init-mixed.out: Likewise.
This commit is contained in:
H.J. Lu
2010-12-15 14:56:40 +00:00
parent bef6be3d9f
commit 02ecc8e968
20 changed files with 334 additions and 14 deletions

View File

@@ -371,18 +371,70 @@ match_simple_wild (const char *pattern, const char *name)
return TRUE;
}
/* Return the numerical value of the init_priority attribute from
section name NAME. */
static unsigned long
get_init_priority (const char *name)
{
char *end;
unsigned long init_priority;
/* GCC uses the following section names for the init_priority
attribute with numerical values 101 and 65535 inclusive. A
lower value means a higher priority.
1: .init_array.NNNN/.fini_array.NNNN: Where NNNN is the
decimal numerical value of the init_priority attribute.
The order of execution in .init_array is forward and
.fini_array is backward.
2: .ctors.NNNN/.ctors.NNNN: Where NNNN is 65535 minus the
decimal numerical value of the init_priority attribute.
The order of execution in .ctors is backward and .dtors
is forward.
*/
if (strncmp (name, ".init_array.", 12) == 0
|| strncmp (name, ".fini_array.", 12) == 0)
{
init_priority = strtoul (name + 12, &end, 10);
return *end ? 0 : init_priority;
}
else if (strncmp (name, ".ctors.", 7) == 0
|| strncmp (name, ".dtors.", 7) == 0)
{
init_priority = strtoul (name + 7, &end, 10);
return *end ? 0 : 65535 - init_priority;
}
return 0;
}
/* Compare sections ASEC and BSEC according to SORT. */
static int
compare_section (sort_type sort, asection *asec, asection *bsec)
{
int ret;
unsigned long ainit_priority, binit_priority;
switch (sort)
{
default:
abort ();
case by_init_priority:
ainit_priority
= get_init_priority (bfd_get_section_name (asec->owner, asec));
binit_priority
= get_init_priority (bfd_get_section_name (bsec->owner, bsec));
if (ainit_priority == 0 || binit_priority == 0)
goto sort_by_name;
ret = ainit_priority - binit_priority;
if (ret)
break;
else
goto sort_by_name;
case by_alignment_name:
ret = (bfd_section_alignment (bsec->owner, bsec)
- bfd_section_alignment (asec->owner, asec));
@@ -391,6 +443,7 @@ compare_section (sort_type sort, asection *asec, asection *bsec)
/* Fall through. */
case by_name:
sort_by_name:
ret = strcmp (bfd_get_section_name (asec->owner, asec),
bfd_get_section_name (bsec->owner, bsec));
break;