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:
parent
bef6be3d9f
commit
02ecc8e968
20 changed files with 334 additions and 14 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
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.
|
||||||
|
|
||||||
2010-12-13 Alan Modra <amodra@gmail.com>
|
2010-12-13 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* aoutx.h (aout_link_check_ar_symbols): Formatting.
|
* aoutx.h (aout_link_check_ar_symbols): Formatting.
|
||||||
|
|
13
bfd/elf.c
13
bfd/elf.c
|
@ -2304,12 +2304,19 @@ _bfd_elf_new_section_hook (bfd *abfd, asection *sec)
|
||||||
anyway. We will set ELF section type and flags for all linker
|
anyway. We will set ELF section type and flags for all linker
|
||||||
created sections. If user specifies BFD section flags, we will
|
created sections. If user specifies BFD section flags, we will
|
||||||
set ELF section type and flags based on BFD section flags in
|
set ELF section type and flags based on BFD section flags in
|
||||||
elf_fake_sections. */
|
elf_fake_sections. Special handling for .init_array/.fini_array
|
||||||
if ((!sec->flags && abfd->direction != read_direction)
|
output sections since they may contain .ctors/.dtors input
|
||||||
|
sections. We don't want _bfd_elf_init_private_section_data to
|
||||||
|
copy ELF section type from .ctors/.dtors input sections. */
|
||||||
|
if (abfd->direction != read_direction
|
||||||
|| (sec->flags & SEC_LINKER_CREATED) != 0)
|
|| (sec->flags & SEC_LINKER_CREATED) != 0)
|
||||||
{
|
{
|
||||||
ssect = (*bed->get_sec_type_attr) (abfd, sec);
|
ssect = (*bed->get_sec_type_attr) (abfd, sec);
|
||||||
if (ssect != NULL)
|
if (ssect != NULL
|
||||||
|
&& (!sec->flags
|
||||||
|
|| (sec->flags & SEC_LINKER_CREATED) != 0
|
||||||
|
|| ssect->type == SHT_INIT_ARRAY
|
||||||
|
|| ssect->type == SHT_FINI_ARRAY))
|
||||||
{
|
{
|
||||||
elf_section_type (sec) = ssect->type;
|
elf_section_type (sec) = ssect->type;
|
||||||
elf_section_flags (sec) = ssect->attr;
|
elf_section_flags (sec) = ssect->attr;
|
||||||
|
|
30
ld/ChangeLog
30
ld/ChangeLog
|
@ -1,3 +1,33 @@
|
||||||
|
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.
|
||||||
|
|
||||||
2010-12-13 Alan Modra <amodra@gmail.com>
|
2010-12-13 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* ldlang.c (load_symbols): Correct last change.
|
* ldlang.c (load_symbols): Correct last change.
|
||||||
|
|
|
@ -611,7 +611,7 @@ stringify.sed: ${srcdir}/emultempl/$(STRINGIFY)
|
||||||
|
|
||||||
# These all start with e so 'make clean' can find them.
|
# These all start with e so 'make clean' can find them.
|
||||||
|
|
||||||
GENSCRIPTS = LIB_PATH='${LIB_PATH}' $(SHELL) $(srcdir)/genscripts.sh "${srcdir}" "${libdir}" "${prefix}" "${exec_prefix}" @host@ @target@ @target_alias@ "@EMULATION_LIBPATH@" "@NATIVE_LIB_DIRS@" @use_sysroot@
|
GENSCRIPTS = LIB_PATH='${LIB_PATH}' $(SHELL) $(srcdir)/genscripts.sh "${srcdir}" "${libdir}" "${prefix}" "${exec_prefix}" @host@ @target@ @target_alias@ "@EMULATION_LIBPATH@" "@NATIVE_LIB_DIRS@" @use_sysroot@ @enable_initfini_array@
|
||||||
GEN_DEPENDS = $(srcdir)/genscripts.sh stringify.sed
|
GEN_DEPENDS = $(srcdir)/genscripts.sh stringify.sed
|
||||||
ELF_DEPS = $(srcdir)/emultempl/elf32.em $(srcdir)/emultempl/elf-generic.em
|
ELF_DEPS = $(srcdir)/emultempl/elf32.em $(srcdir)/emultempl/elf-generic.em
|
||||||
ELF_GEN_DEPS = $(srcdir)/emultempl/generic.em $(srcdir)/emultempl/elf-generic.em $(srcdir)/emultempl/genelf.em
|
ELF_GEN_DEPS = $(srcdir)/emultempl/generic.em $(srcdir)/emultempl/elf-generic.em $(srcdir)/emultempl/genelf.em
|
||||||
|
|
|
@ -299,6 +299,7 @@ datarootdir = @datarootdir@
|
||||||
do_compare = @do_compare@
|
do_compare = @do_compare@
|
||||||
docdir = @docdir@
|
docdir = @docdir@
|
||||||
dvidir = @dvidir@
|
dvidir = @dvidir@
|
||||||
|
enable_initfini_array = @enable_initfini_array@
|
||||||
exec_prefix = @exec_prefix@
|
exec_prefix = @exec_prefix@
|
||||||
host = @host@
|
host = @host@
|
||||||
host_alias = @host_alias@
|
host_alias = @host_alias@
|
||||||
|
@ -797,7 +798,7 @@ EMULATION_FILES = emultempl/pe.em emultempl/armcoff.em
|
||||||
POTFILES = $(CFILES) $(HFILES) $(EMULATION_FILES)
|
POTFILES = $(CFILES) $(HFILES) $(EMULATION_FILES)
|
||||||
|
|
||||||
# These all start with e so 'make clean' can find them.
|
# These all start with e so 'make clean' can find them.
|
||||||
GENSCRIPTS = LIB_PATH='${LIB_PATH}' $(SHELL) $(srcdir)/genscripts.sh "${srcdir}" "${libdir}" "${prefix}" "${exec_prefix}" @host@ @target@ @target_alias@ "@EMULATION_LIBPATH@" "@NATIVE_LIB_DIRS@" @use_sysroot@
|
GENSCRIPTS = LIB_PATH='${LIB_PATH}' $(SHELL) $(srcdir)/genscripts.sh "${srcdir}" "${libdir}" "${prefix}" "${exec_prefix}" @host@ @target@ @target_alias@ "@EMULATION_LIBPATH@" "@NATIVE_LIB_DIRS@" @use_sysroot@ @enable_initfini_array@
|
||||||
GEN_DEPENDS = $(srcdir)/genscripts.sh stringify.sed
|
GEN_DEPENDS = $(srcdir)/genscripts.sh stringify.sed
|
||||||
ELF_DEPS = $(srcdir)/emultempl/elf32.em $(srcdir)/emultempl/elf-generic.em
|
ELF_DEPS = $(srcdir)/emultempl/elf32.em $(srcdir)/emultempl/elf-generic.em
|
||||||
ELF_GEN_DEPS = $(srcdir)/emultempl/generic.em $(srcdir)/emultempl/elf-generic.em $(srcdir)/emultempl/genelf.em
|
ELF_GEN_DEPS = $(srcdir)/emultempl/generic.em $(srcdir)/emultempl/elf-generic.em $(srcdir)/emultempl/genelf.em
|
||||||
|
|
4
ld/NEWS
4
ld/NEWS
|
@ -1,5 +1,9 @@
|
||||||
-*- text -*-
|
-*- text -*-
|
||||||
|
|
||||||
|
* Added SORT_BY_INIT_PRIORITY to the linker script language to permit
|
||||||
|
sorting sections by numerical value of the GCC init_priority attribute
|
||||||
|
encoded in the section name.
|
||||||
|
|
||||||
Changes in 2.21:
|
Changes in 2.21:
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,9 @@
|
||||||
/* Define to 1 if you have the `glob' function. */
|
/* Define to 1 if you have the `glob' function. */
|
||||||
#undef HAVE_GLOB
|
#undef HAVE_GLOB
|
||||||
|
|
||||||
|
/* Define .init_array/.fini_array sections are available and working. */
|
||||||
|
#undef HAVE_INITFINI_ARRAY
|
||||||
|
|
||||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||||
#undef HAVE_INTTYPES_H
|
#undef HAVE_INTTYPES_H
|
||||||
|
|
||||||
|
|
56
ld/configure
vendored
56
ld/configure
vendored
|
@ -609,6 +609,7 @@ EMUL_EXTRA_OFILES
|
||||||
EMULATION_OFILES
|
EMULATION_OFILES
|
||||||
EMUL
|
EMUL
|
||||||
STRINGIFY
|
STRINGIFY
|
||||||
|
enable_initfini_array
|
||||||
ENABLE_PLUGINS_FALSE
|
ENABLE_PLUGINS_FALSE
|
||||||
ENABLE_PLUGINS_TRUE
|
ENABLE_PLUGINS_TRUE
|
||||||
NATIVE_LIB_DIRS
|
NATIVE_LIB_DIRS
|
||||||
|
@ -778,6 +779,7 @@ enable_fast_install
|
||||||
with_gnu_ld
|
with_gnu_ld
|
||||||
enable_libtool_lock
|
enable_libtool_lock
|
||||||
enable_nls
|
enable_nls
|
||||||
|
enable_initfini_array
|
||||||
'
|
'
|
||||||
ac_precious_vars='build_alias
|
ac_precious_vars='build_alias
|
||||||
host_alias
|
host_alias
|
||||||
|
@ -1427,6 +1429,7 @@ Optional Features:
|
||||||
optimize for fast installation [default=yes]
|
optimize for fast installation [default=yes]
|
||||||
--disable-libtool-lock avoid locking (might break parallel builds)
|
--disable-libtool-lock avoid locking (might break parallel builds)
|
||||||
--disable-nls do not use Native Language Support
|
--disable-nls do not use Native Language Support
|
||||||
|
--enable-initfini-array use .init_array/.fini_array sections
|
||||||
|
|
||||||
Optional Packages:
|
Optional Packages:
|
||||||
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
|
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
|
||||||
|
@ -2591,6 +2594,7 @@ test -n "$target_alias" &&
|
||||||
test "$program_prefix$program_suffix$program_transform_name" = \
|
test "$program_prefix$program_suffix$program_transform_name" = \
|
||||||
NONENONEs,x,x, &&
|
NONENONEs,x,x, &&
|
||||||
program_prefix=${target_alias}-
|
program_prefix=${target_alias}-
|
||||||
|
|
||||||
ac_ext=c
|
ac_ext=c
|
||||||
ac_cpp='$CPP $CPPFLAGS'
|
ac_cpp='$CPP $CPPFLAGS'
|
||||||
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||||
|
@ -11622,7 +11626,7 @@ else
|
||||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||||
lt_status=$lt_dlunknown
|
lt_status=$lt_dlunknown
|
||||||
cat > conftest.$ac_ext <<_LT_EOF
|
cat > conftest.$ac_ext <<_LT_EOF
|
||||||
#line 11625 "configure"
|
#line 11629 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
|
|
||||||
#if HAVE_DLFCN_H
|
#if HAVE_DLFCN_H
|
||||||
|
@ -11728,7 +11732,7 @@ else
|
||||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||||
lt_status=$lt_dlunknown
|
lt_status=$lt_dlunknown
|
||||||
cat > conftest.$ac_ext <<_LT_EOF
|
cat > conftest.$ac_ext <<_LT_EOF
|
||||||
#line 11731 "configure"
|
#line 11735 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
|
|
||||||
#if HAVE_DLFCN_H
|
#if HAVE_DLFCN_H
|
||||||
|
@ -12944,6 +12948,54 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Check whether --enable-initfini-array was given.
|
||||||
|
if test "${enable_initfini_array+set}" = set; then :
|
||||||
|
enableval=$enable_initfini_array;
|
||||||
|
else
|
||||||
|
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for .preinit_array/.init_array/.fini_array support" >&5
|
||||||
|
$as_echo_n "checking for .preinit_array/.init_array/.fini_array support... " >&6; }
|
||||||
|
if test "${gcc_cv_initfini_array+set}" = set; then :
|
||||||
|
$as_echo_n "(cached) " >&6
|
||||||
|
else
|
||||||
|
if test "x${build}" = "x${target}" ; then
|
||||||
|
if test "$cross_compiling" = yes; then :
|
||||||
|
gcc_cv_initfini_array=no
|
||||||
|
else
|
||||||
|
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||||
|
/* end confdefs.h. */
|
||||||
|
|
||||||
|
static int x = -1;
|
||||||
|
int main (void) { return x; }
|
||||||
|
int foo (void) { x = 0; }
|
||||||
|
int (*fp) (void) __attribute__ ((section (".init_array"))) = foo;
|
||||||
|
_ACEOF
|
||||||
|
if ac_fn_c_try_run "$LINENO"; then :
|
||||||
|
gcc_cv_initfini_array=yes
|
||||||
|
else
|
||||||
|
gcc_cv_initfini_array=no
|
||||||
|
fi
|
||||||
|
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
|
||||||
|
conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
gcc_cv_initfini_array=no
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_initfini_array" >&5
|
||||||
|
$as_echo "$gcc_cv_initfini_array" >&6; }
|
||||||
|
enable_initfini_array=$gcc_cv_initfini_array
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test $enable_initfini_array = yes; then
|
||||||
|
|
||||||
|
$as_echo "#define HAVE_INITFINI_ARRAY 1" >>confdefs.h
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a known getopt prototype in unistd.h" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a known getopt prototype in unistd.h" >&5
|
||||||
$as_echo_n "checking for a known getopt prototype in unistd.h... " >&6; }
|
$as_echo_n "checking for a known getopt prototype in unistd.h... " >&6; }
|
||||||
if test "${ld_cv_decl_getopt_unistd_h+set}" = set; then :
|
if test "${ld_cv_decl_getopt_unistd_h+set}" = set; then :
|
||||||
|
|
|
@ -5,6 +5,7 @@ AC_INIT
|
||||||
AC_CONFIG_SRCDIR(ldmain.c)
|
AC_CONFIG_SRCDIR(ldmain.c)
|
||||||
|
|
||||||
AC_CANONICAL_TARGET
|
AC_CANONICAL_TARGET
|
||||||
|
AC_CANONICAL_BUILD
|
||||||
AC_ISC_POSIX
|
AC_ISC_POSIX
|
||||||
|
|
||||||
changequote(,)dnl
|
changequote(,)dnl
|
||||||
|
@ -175,6 +176,30 @@ if test x$enable_plugins = xno ; then
|
||||||
fi
|
fi
|
||||||
AM_CONDITIONAL([ENABLE_PLUGINS], [test x$enable_plugins = xyes])
|
AM_CONDITIONAL([ENABLE_PLUGINS], [test x$enable_plugins = xyes])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(initfini-array,
|
||||||
|
[ --enable-initfini-array use .init_array/.fini_array sections],
|
||||||
|
[], [
|
||||||
|
AC_CACHE_CHECK(for .preinit_array/.init_array/.fini_array support,
|
||||||
|
gcc_cv_initfini_array, [dnl
|
||||||
|
if test "x${build}" = "x${target}" ; then
|
||||||
|
AC_RUN_IFELSE([AC_LANG_SOURCE([
|
||||||
|
static int x = -1;
|
||||||
|
int main (void) { return x; }
|
||||||
|
int foo (void) { x = 0; }
|
||||||
|
int (*fp) (void) __attribute__ ((section (".init_array"))) = foo;])],
|
||||||
|
[gcc_cv_initfini_array=yes], [gcc_cv_initfini_array=no],
|
||||||
|
[gcc_cv_initfini_array=no])
|
||||||
|
else
|
||||||
|
gcc_cv_initfini_array=no
|
||||||
|
fi])
|
||||||
|
enable_initfini_array=$gcc_cv_initfini_array
|
||||||
|
])
|
||||||
|
AC_SUBST(enable_initfini_array)
|
||||||
|
if test $enable_initfini_array = yes; then
|
||||||
|
AC_DEFINE(HAVE_INITFINI_ARRAY, 1,
|
||||||
|
[Define .init_array/.fini_array sections are available and working.])
|
||||||
|
fi
|
||||||
|
|
||||||
AC_MSG_CHECKING(for a known getopt prototype in unistd.h)
|
AC_MSG_CHECKING(for a known getopt prototype in unistd.h)
|
||||||
AC_CACHE_VAL(ld_cv_decl_getopt_unistd_h,
|
AC_CACHE_VAL(ld_cv_decl_getopt_unistd_h,
|
||||||
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <unistd.h>], [extern int getopt (int, char *const*, const char *);])],
|
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <unistd.h>], [extern int getopt (int, char *const*, const char *);])],
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
# default_emulation \
|
# default_emulation \
|
||||||
# native_lib_dirs \
|
# native_lib_dirs \
|
||||||
# use_sysroot \
|
# use_sysroot \
|
||||||
|
# enable_initfini_array \
|
||||||
# this_emulation \
|
# this_emulation \
|
||||||
# optional:
|
# optional:
|
||||||
# tool_dir \
|
# tool_dir \
|
||||||
|
@ -89,9 +90,10 @@ EMULATION_LIBPATH=$8
|
||||||
NATIVE_LIB_DIRS=$9
|
NATIVE_LIB_DIRS=$9
|
||||||
shift 9
|
shift 9
|
||||||
use_sysroot=$1
|
use_sysroot=$1
|
||||||
EMULATION_NAME=$2
|
ENABLE_INITFINI_ARRAY=$2
|
||||||
TOOL_LIB=$3
|
EMULATION_NAME=$3
|
||||||
CUSTOMIZER_SCRIPT=$4
|
TOOL_LIB=$4
|
||||||
|
CUSTOMIZER_SCRIPT=$5
|
||||||
|
|
||||||
# Can't use ${TOOL_LIB:-$target_alias} here due to an Ultrix shell bug.
|
# Can't use ${TOOL_LIB:-$target_alias} here due to an Ultrix shell bug.
|
||||||
if [ "x${TOOL_LIB}" = "x" ] ; then
|
if [ "x${TOOL_LIB}" = "x" ] ; then
|
||||||
|
|
3
ld/ld.h
3
ld/ld.h
|
@ -86,7 +86,8 @@ typedef enum {sort_none, sort_ascending, sort_descending} sort_order;
|
||||||
/* A wildcard specification. */
|
/* A wildcard specification. */
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
none, by_name, by_alignment, by_name_alignment, by_alignment_name
|
none, by_name, by_alignment, by_name_alignment, by_alignment_name,
|
||||||
|
by_init_priority
|
||||||
} sort_type;
|
} sort_type;
|
||||||
|
|
||||||
extern sort_type sort_section;
|
extern sort_type sort_section;
|
||||||
|
|
|
@ -3911,6 +3911,12 @@ into ascending order by name before placing them in the output file.
|
||||||
difference is @code{SORT_BY_ALIGNMENT} will sort sections into
|
difference is @code{SORT_BY_ALIGNMENT} will sort sections into
|
||||||
ascending order by alignment before placing them in the output file.
|
ascending order by alignment before placing them in the output file.
|
||||||
|
|
||||||
|
@cindex SORT_BY_INIT_PRIORITY
|
||||||
|
@code{SORT_BY_INIT_PRIORITY} is very similar to @code{SORT_BY_NAME}. The
|
||||||
|
difference is @code{SORT_BY_INIT_PRIORITY} will sort sections into
|
||||||
|
ascending order by numerical value of the GCC init_priority attribute
|
||||||
|
encoded in the section name before placing them in the output file.
|
||||||
|
|
||||||
@cindex SORT
|
@cindex SORT
|
||||||
@code{SORT} is an alias for @code{SORT_BY_NAME}.
|
@code{SORT} is an alias for @code{SORT_BY_NAME}.
|
||||||
|
|
||||||
|
|
|
@ -126,6 +126,7 @@ static int error_index;
|
||||||
%token SECTIONS PHDRS INSERT_K AFTER BEFORE
|
%token SECTIONS PHDRS INSERT_K AFTER BEFORE
|
||||||
%token DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END
|
%token DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END
|
||||||
%token SORT_BY_NAME SORT_BY_ALIGNMENT
|
%token SORT_BY_NAME SORT_BY_ALIGNMENT
|
||||||
|
%token SORT_BY_INIT_PRIORITY
|
||||||
%token '{' '}'
|
%token '{' '}'
|
||||||
%token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
|
%token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
|
||||||
%token INHIBIT_COMMON_ALLOCATION
|
%token INHIBIT_COMMON_ALLOCATION
|
||||||
|
@ -482,6 +483,12 @@ wildcard_spec:
|
||||||
$$.sorted = by_name;
|
$$.sorted = by_name;
|
||||||
$$.exclude_name_list = $5;
|
$$.exclude_name_list = $5;
|
||||||
}
|
}
|
||||||
|
| SORT_BY_INIT_PRIORITY '(' wildcard_name ')'
|
||||||
|
{
|
||||||
|
$$.name = $3;
|
||||||
|
$$.sorted = by_init_priority;
|
||||||
|
$$.exclude_name_list = NULL;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
exclude_name_list:
|
exclude_name_list:
|
||||||
|
|
53
ld/ldlang.c
53
ld/ldlang.c
|
@ -371,18 +371,70 @@ match_simple_wild (const char *pattern, const char *name)
|
||||||
return TRUE;
|
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. */
|
/* Compare sections ASEC and BSEC according to SORT. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
compare_section (sort_type sort, asection *asec, asection *bsec)
|
compare_section (sort_type sort, asection *asec, asection *bsec)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
unsigned long ainit_priority, binit_priority;
|
||||||
|
|
||||||
switch (sort)
|
switch (sort)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
abort ();
|
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:
|
case by_alignment_name:
|
||||||
ret = (bfd_section_alignment (bsec->owner, bsec)
|
ret = (bfd_section_alignment (bsec->owner, bsec)
|
||||||
- bfd_section_alignment (asec->owner, asec));
|
- bfd_section_alignment (asec->owner, asec));
|
||||||
|
@ -391,6 +443,7 @@ compare_section (sort_type sort, asection *asec, asection *bsec)
|
||||||
/* Fall through. */
|
/* Fall through. */
|
||||||
|
|
||||||
case by_name:
|
case by_name:
|
||||||
|
sort_by_name:
|
||||||
ret = strcmp (bfd_get_section_name (asec->owner, asec),
|
ret = strcmp (bfd_get_section_name (asec->owner, asec),
|
||||||
bfd_get_section_name (bsec->owner, bsec));
|
bfd_get_section_name (bsec->owner, bsec));
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -297,6 +297,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
|
||||||
<BOTH,SCRIPT>"SORT_BY_NAME" { RTOKEN(SORT_BY_NAME); }
|
<BOTH,SCRIPT>"SORT_BY_NAME" { RTOKEN(SORT_BY_NAME); }
|
||||||
<BOTH,SCRIPT>"SORT_BY_ALIGNMENT" { RTOKEN(SORT_BY_ALIGNMENT); }
|
<BOTH,SCRIPT>"SORT_BY_ALIGNMENT" { RTOKEN(SORT_BY_ALIGNMENT); }
|
||||||
<BOTH,SCRIPT>"SORT" { RTOKEN(SORT_BY_NAME); }
|
<BOTH,SCRIPT>"SORT" { RTOKEN(SORT_BY_NAME); }
|
||||||
|
<BOTH,SCRIPT>"SORT_BY_INIT_PRIORITY" { RTOKEN(SORT_BY_INIT_PRIORITY); }
|
||||||
<EXPRESSION,BOTH,SCRIPT>"NOLOAD" { RTOKEN(NOLOAD);}
|
<EXPRESSION,BOTH,SCRIPT>"NOLOAD" { RTOKEN(NOLOAD);}
|
||||||
<EXPRESSION,BOTH,SCRIPT>"DSECT" { RTOKEN(DSECT);}
|
<EXPRESSION,BOTH,SCRIPT>"DSECT" { RTOKEN(DSECT);}
|
||||||
<EXPRESSION,BOTH,SCRIPT>"COPY" { RTOKEN(COPY);}
|
<EXPRESSION,BOTH,SCRIPT>"COPY" { RTOKEN(COPY);}
|
||||||
|
|
|
@ -222,18 +222,31 @@ test "${LARGE_SECTIONS}" = "yes" && LARGE_SECTIONS="
|
||||||
*(.ldata${RELOCATING+ .ldata.* .gnu.linkonce.l.*})
|
*(.ldata${RELOCATING+ .ldata.* .gnu.linkonce.l.*})
|
||||||
${RELOCATING+. = ALIGN(. != 0 ? ${ALIGNMENT} : 1);}
|
${RELOCATING+. = ALIGN(. != 0 ? ${ALIGNMENT} : 1);}
|
||||||
}"
|
}"
|
||||||
|
if test "${ENABLE_INITFINI_ARRAY}" = "yes"; then
|
||||||
|
SORT_INIT_ARRAY="KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))"
|
||||||
|
SORT_FINI_ARRAY="KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))"
|
||||||
|
CTORS_IN_INIT_ARRAY="KEEP (*(EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o $OTHER_EXCLUDE_FILES) .ctors))"
|
||||||
|
DTORS_IN_FINI_ARRAY="KEEP (*(EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o $OTHER_EXCLUDE_FILES) .dtors))"
|
||||||
|
else
|
||||||
|
SORT_INIT_ARRAY="KEEP (*(SORT(.init_array.*)))"
|
||||||
|
SORT_FINI_ARRAY="KEEP (*(SORT(.fini_array.*)))"
|
||||||
|
CTORS_IN_INIT_ARRAY=
|
||||||
|
DTORS_IN_FINI_ARRAY=
|
||||||
|
fi
|
||||||
INIT_ARRAY=".init_array ${RELOCATING-0} :
|
INIT_ARRAY=".init_array ${RELOCATING-0} :
|
||||||
{
|
{
|
||||||
${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__init_array_start = .);}}
|
${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__init_array_start = .);}}
|
||||||
KEEP (*(SORT(.init_array.*)))
|
${SORT_INIT_ARRAY}
|
||||||
KEEP (*(.init_array))
|
KEEP (*(.init_array))
|
||||||
|
${CTORS_IN_INIT_ARRAY}
|
||||||
${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__init_array_end = .);}}
|
${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__init_array_end = .);}}
|
||||||
}"
|
}"
|
||||||
FINI_ARRAY=".fini_array ${RELOCATING-0} :
|
FINI_ARRAY=".fini_array ${RELOCATING-0} :
|
||||||
{
|
{
|
||||||
${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__fini_array_start = .);}}
|
${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__fini_array_start = .);}}
|
||||||
KEEP (*(SORT(.fini_array.*)))
|
${SORT_FINI_ARRAY}
|
||||||
KEEP (*(.fini_array))
|
KEEP (*(.fini_array))
|
||||||
|
${DTORS_IN_FINI_ARRAY}
|
||||||
${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__fini_array_end = .);}}
|
${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__fini_array_end = .);}}
|
||||||
}"
|
}"
|
||||||
CTOR=".ctors ${CONSTRUCTING-0} :
|
CTOR=".ctors ${CONSTRUCTING-0} :
|
||||||
|
|
|
@ -1,3 +1,12 @@
|
||||||
|
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.
|
||||||
|
|
||||||
2010-12-11 Alan Modra <amodra@gmail.com>
|
2010-12-11 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* ld-elfvers/vers25a.dsym: Really include _? in match.
|
* ld-elfvers/vers25a.dsym: Really include _? in match.
|
||||||
|
|
|
@ -74,11 +74,13 @@ set array_tests {
|
||||||
{"preinit array" "" "" {preinit.c} "preinit" "preinit.out"}
|
{"preinit array" "" "" {preinit.c} "preinit" "preinit.out"}
|
||||||
{"init array" "" "" {init.c} "init" "init.out"}
|
{"init array" "" "" {init.c} "init" "init.out"}
|
||||||
{"fini array" "" "" {fini.c} "fini" "fini.out"}
|
{"fini array" "" "" {fini.c} "fini" "fini.out"}
|
||||||
|
{"init array mixed" "" "" {init-mixed.c} "init-mixed" "init-mixed.out" "-I."}
|
||||||
}
|
}
|
||||||
set array_tests_static {
|
set array_tests_static {
|
||||||
{"static preinit array" "-static" "" {preinit.c} "preinit" "preinit.out"}
|
{"static preinit array" "-static" "" {preinit.c} "preinit" "preinit.out"}
|
||||||
{"static init array" "-static" "" {init.c} "init" "init.out"}
|
{"static init array" "-static" "" {init.c} "init" "init.out"}
|
||||||
{"static fini array" "-static" "" {fini.c} "fini" "fini.out"}
|
{"static fini array" "-static" "" {fini.c} "fini" "fini.out"}
|
||||||
|
{"static init array mixed" "" "" {init-mixed.c} "init-mixed" "init-mixed.out" "-I."}
|
||||||
}
|
}
|
||||||
|
|
||||||
# NetBSD ELF systems do not currently support the .*_array sections.
|
# NetBSD ELF systems do not currently support the .*_array sections.
|
||||||
|
@ -93,4 +95,4 @@ switch -regexp $target_triplet {
|
||||||
}
|
}
|
||||||
run_ld_link_exec_tests $xfails $array_tests_static
|
run_ld_link_exec_tests $xfails $array_tests_static
|
||||||
|
|
||||||
catch "exec rm -f tmpdir/preinit tmpdir/init tmpdir/fini" status
|
catch "exec rm -f tmpdir/preinit tmpdir/init tmpdir/fini tmpdir/init-mixed" status
|
||||||
|
|
98
ld/testsuite/ld-elf/init-mixed.c
Normal file
98
ld/testsuite/ld-elf/init-mixed.c
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_INITFINI_ARRAY
|
||||||
|
static int count;
|
||||||
|
|
||||||
|
static void
|
||||||
|
init1005 ()
|
||||||
|
{
|
||||||
|
if (count != 0)
|
||||||
|
abort ();
|
||||||
|
count = 1005;
|
||||||
|
}
|
||||||
|
void (*const init_array1005[]) ()
|
||||||
|
__attribute__ ((section (".init_array.01005"), aligned (sizeof (void *))))
|
||||||
|
= { init1005 };
|
||||||
|
static void
|
||||||
|
fini1005 ()
|
||||||
|
{
|
||||||
|
if (count != 1005)
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
void (*const fini_array1005[]) ()
|
||||||
|
__attribute__ ((section (".fini_array.01005"), aligned (sizeof (void *))))
|
||||||
|
= { fini1005 };
|
||||||
|
|
||||||
|
static void
|
||||||
|
ctor1007 ()
|
||||||
|
{
|
||||||
|
if (count != 1005)
|
||||||
|
abort ();
|
||||||
|
count = 1007;
|
||||||
|
}
|
||||||
|
void (*const ctors1007[]) ()
|
||||||
|
__attribute__ ((section (".ctors.64528"), aligned (sizeof (void *))))
|
||||||
|
= { ctor1007 };
|
||||||
|
static void
|
||||||
|
dtor1007 ()
|
||||||
|
{
|
||||||
|
if (count != 1007)
|
||||||
|
abort ();
|
||||||
|
count = 1005;
|
||||||
|
}
|
||||||
|
void (*const dtors1007[]) ()
|
||||||
|
__attribute__ ((section (".dtors.64528"), aligned (sizeof (void *))))
|
||||||
|
= { dtor1007 };
|
||||||
|
|
||||||
|
static void
|
||||||
|
init65530 ()
|
||||||
|
{
|
||||||
|
if (count != 1007)
|
||||||
|
abort ();
|
||||||
|
count = 65530;
|
||||||
|
}
|
||||||
|
void (*const init_array65530[]) ()
|
||||||
|
__attribute__ ((section (".init_array.65530"), aligned (sizeof (void *))))
|
||||||
|
= { init65530 };
|
||||||
|
static void
|
||||||
|
fini65530 ()
|
||||||
|
{
|
||||||
|
if (count != 65530)
|
||||||
|
abort ();
|
||||||
|
count = 1007;
|
||||||
|
}
|
||||||
|
void (*const fini_array65530[]) ()
|
||||||
|
__attribute__ ((section (".fini_array.65530"), aligned (sizeof (void *))))
|
||||||
|
= { fini65530 };
|
||||||
|
|
||||||
|
static void
|
||||||
|
ctor65535 ()
|
||||||
|
{
|
||||||
|
if (count != 65530)
|
||||||
|
abort ();
|
||||||
|
count = 65535;
|
||||||
|
}
|
||||||
|
void (*const ctors65535[]) ()
|
||||||
|
__attribute__ ((section (".ctors"), aligned (sizeof (void *))))
|
||||||
|
= { ctor65535 };
|
||||||
|
static void
|
||||||
|
dtor65535 ()
|
||||||
|
{
|
||||||
|
if (count != 65535)
|
||||||
|
abort ();
|
||||||
|
count = 65530;
|
||||||
|
}
|
||||||
|
void (*const dtors65535[]) ()
|
||||||
|
__attribute__ ((section (".dtors"), aligned (sizeof (void *))))
|
||||||
|
= { dtor65535 };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
printf ("OK\n");
|
||||||
|
return 0;
|
||||||
|
}
|
1
ld/testsuite/ld-elf/init-mixed.out
Normal file
1
ld/testsuite/ld-elf/init-mixed.out
Normal file
|
@ -0,0 +1 @@
|
||||||
|
OK
|
Loading…
Add table
Add a link
Reference in a new issue