2008-04-11 Cary Coutant <ccoutant@google.com>
Add support for TLS descriptors for i386 and x86_64. * i386.cc (Target_i386::Relocate::tls_desc_gd_to_ie): New function. (Target_i386::Relocate::tls_desc_gd_to_le): New function. (Target_i386::Got_type): Add GOT_TYPE_TLS_NOFFSET and GOT_TYPE_TLS_DESC. (Target_i386::got_mod_index_entry): Remove unnecessary code. (Target_i386::Scan::local): Implement R_386_TLS_GOTDESC and R_386_TLS_DESC_CALL relocations. Fix problem with initial-exec relocations. (Target_i386::Scan::global): Fix problem with GD-to-IE relaxation. Implement R_386_TLS_GOTDESC and R_386_TLS_DESC_CALL relocations; Fix problem with initial-exec relocations. (Target_i386::Relocate::relocate_tls): Likewise. (Target_i386::Relocate::tls_gd_to_ie): Fix problem with GD-to-IE relaxation. * output.cc (Output_data_dynamic::Dynamic_entry::write): Add support for section-plus-offset dynamic table entries. * output.h (Output_data_dynamic::add_section_plus_offset): New function. (Output_data_dynamic::Dynamic_entry): Add support for section-plus-offset dynamic table entries. (Output_data_dynamic::Classification): Likewise. (Output_data_dynamic::classification_): Renamed offset_. * x86_64.cc (Target_x86_64::Relocate::tls_desc_gd_to_ie): New function. (Target_x86_64::Relocate::tls_desc_gd_to_le): New function. (Target_x86_64::make_plt_section): New function. (Target_x86_64::reserve_tlsdesc_entries): New function. (Output_data_plt_x86_64::Output_data_plt_x86_64): Add new parameter. (Output_data_plt_x86_64::reserve_tlsdesc_entry): New function. (Output_data_plt_x86_64::has_tlsdesc_entry): New function. (Output_data_plt_x86_64::get_tlsdesc_got_offset): New function. (Output_data_plt_x86_64::get_tlsdesc_plt_offset): New function. (Output_data_plt_x86_64::tlsdesc_plt_entry): New field. (Output_data_plt_x86_64::set_final_data_size): Move out of line; add extra PLT entry for TLS descriptors. (Output_data_plt_x86_64::got_): New field. (Output_data_plt_x86_64::tlsdesc_got_offset_): New field. (Output_data_plt_x86_64::Output_data_plt_x86_64): Initialize new fields. (Output_data_plt_x86_64::do_write): Write extra PLT entry for TLS descriptors. (Target_x86_64::make_plt_entry): Factor out make_plt_section. (Target_x86_64::got_mod_index_entry): Remove unnecessary code. (Target_x86_64::Scan::local): Implement R_386_TLS_GOTDESC and R_386_TLS_DESC_CALL relocations. (Target_x86_64::Scan::global): Likewise. (Target_x86_64::do_finalize_sections): Add dynamic table entries for TLS descriptors. (Relocate::relocate_tls): Fix problem with GD-to-IE relaxation. Implement R_386_TLS_GOTDESC and R_386_TLS_DESC_CALL relocations. (Target_x86_64::Relocate::tls_gd_to_ie): Fix problem with GD-to-IE relaxation. * configure.ac: Export new conditional variables TLS_GNU2_DIALECT and TLS_DESCRIPTORS. * Makefile.in: Rebuild. * configure: Rebuild. * testsuite/Makefile.am (tls_shared_gd_to_ie_test): New target. (tls_test_shared2.so): New target. (tls_shared_gd_to_ie_test_SOURCES): New variable. (tls_shared_gd_to_ie_test_DEPENDENCIES): New variable. (tls_shared_gd_to_ie_test_LDFLAGS): New variable. (tls_shared_gd_to_ie_test_LDADD): New variable. (tls_shared_gnu2_gd_to_ie_test): New target. (tls_test_gnu2.o, tls_test_file2_gnu2.o, tls_test_gnu2_shared2.so): New targets. (tls_shared_gnu2_gd_to_ie_test_SOURCES): New variable. (ls_shared_gnu2_gd_to_ie_test_DEPENDENCIES): New variable. (tls_shared_gnu2_gd_to_ie_test_LDFLAGS): New variable. (tls_shared_gnu2_gd_to_ie_test_LDADD): New variable. (tls_shared_gnu2_test): New target. (tls_test_gnu2_shared.so): New target. (tls_shared_gnu2_test_SOURCES): New variable. (tls_shared_gnu2_test_DEPENDENCIES): New variable. (tls_shared_gnu2_test_LDFLAGS): New variable. (tls_shared_gnu2_test_LDADD): New variable. * testsuite/Makefile.in: Rebuild. * testsuite/Makefile.
This commit is contained in:
parent
83bfb6b776
commit
c2b45e22d5
@ -1,3 +1,82 @@
|
||||
2008-04-11 Cary Coutant <ccoutant@google.com>
|
||||
|
||||
Add support for TLS descriptors for i386 and x86_64.
|
||||
* i386.cc (Target_i386::Relocate::tls_desc_gd_to_ie): New function.
|
||||
(Target_i386::Relocate::tls_desc_gd_to_le): New function.
|
||||
(Target_i386::Got_type): Add GOT_TYPE_TLS_NOFFSET and
|
||||
GOT_TYPE_TLS_DESC.
|
||||
(Target_i386::got_mod_index_entry): Remove unnecessary code.
|
||||
(Target_i386::Scan::local): Implement R_386_TLS_GOTDESC and
|
||||
R_386_TLS_DESC_CALL relocations. Fix problem with initial-exec
|
||||
relocations.
|
||||
(Target_i386::Scan::global): Fix problem with GD-to-IE relaxation.
|
||||
Implement R_386_TLS_GOTDESC and R_386_TLS_DESC_CALL relocations;
|
||||
Fix problem with initial-exec relocations.
|
||||
(Target_i386::Relocate::relocate_tls): Likewise.
|
||||
(Target_i386::Relocate::tls_gd_to_ie): Fix problem with GD-to-IE
|
||||
relaxation.
|
||||
* output.cc (Output_data_dynamic::Dynamic_entry::write): Add
|
||||
support for section-plus-offset dynamic table entries.
|
||||
* output.h (Output_data_dynamic::add_section_plus_offset): New function.
|
||||
(Output_data_dynamic::Dynamic_entry): Add support for
|
||||
section-plus-offset dynamic table entries.
|
||||
(Output_data_dynamic::Classification): Likewise.
|
||||
(Output_data_dynamic::classification_): Renamed offset_.
|
||||
* x86_64.cc (Target_x86_64::Relocate::tls_desc_gd_to_ie): New function.
|
||||
(Target_x86_64::Relocate::tls_desc_gd_to_le): New function.
|
||||
(Target_x86_64::make_plt_section): New function.
|
||||
(Target_x86_64::reserve_tlsdesc_entries): New function.
|
||||
(Output_data_plt_x86_64::Output_data_plt_x86_64): Add new parameter.
|
||||
(Output_data_plt_x86_64::reserve_tlsdesc_entry): New function.
|
||||
(Output_data_plt_x86_64::has_tlsdesc_entry): New function.
|
||||
(Output_data_plt_x86_64::get_tlsdesc_got_offset): New function.
|
||||
(Output_data_plt_x86_64::get_tlsdesc_plt_offset): New function.
|
||||
(Output_data_plt_x86_64::tlsdesc_plt_entry): New field.
|
||||
(Output_data_plt_x86_64::set_final_data_size): Move out of line;
|
||||
add extra PLT entry for TLS descriptors.
|
||||
(Output_data_plt_x86_64::got_): New field.
|
||||
(Output_data_plt_x86_64::tlsdesc_got_offset_): New field.
|
||||
(Output_data_plt_x86_64::Output_data_plt_x86_64): Initialize new
|
||||
fields.
|
||||
(Output_data_plt_x86_64::do_write): Write extra PLT entry for TLS
|
||||
descriptors.
|
||||
(Target_x86_64::make_plt_entry): Factor out make_plt_section.
|
||||
(Target_x86_64::got_mod_index_entry): Remove unnecessary code.
|
||||
(Target_x86_64::Scan::local): Implement R_386_TLS_GOTDESC and
|
||||
R_386_TLS_DESC_CALL relocations.
|
||||
(Target_x86_64::Scan::global): Likewise.
|
||||
(Target_x86_64::do_finalize_sections): Add dynamic table entries
|
||||
for TLS descriptors.
|
||||
(Relocate::relocate_tls): Fix problem with GD-to-IE relaxation.
|
||||
Implement R_386_TLS_GOTDESC and R_386_TLS_DESC_CALL relocations.
|
||||
(Target_x86_64::Relocate::tls_gd_to_ie): Fix problem with
|
||||
GD-to-IE relaxation.
|
||||
* configure.ac: Export new conditional variables TLS_GNU2_DIALECT
|
||||
and TLS_DESCRIPTORS.
|
||||
* Makefile.in: Rebuild.
|
||||
* configure: Rebuild.
|
||||
* testsuite/Makefile.am (tls_shared_gd_to_ie_test): New target.
|
||||
(tls_test_shared2.so): New target.
|
||||
(tls_shared_gd_to_ie_test_SOURCES): New variable.
|
||||
(tls_shared_gd_to_ie_test_DEPENDENCIES): New variable.
|
||||
(tls_shared_gd_to_ie_test_LDFLAGS): New variable.
|
||||
(tls_shared_gd_to_ie_test_LDADD): New variable.
|
||||
(tls_shared_gnu2_gd_to_ie_test): New target.
|
||||
(tls_test_gnu2.o, tls_test_file2_gnu2.o, tls_test_gnu2_shared2.so):
|
||||
New targets.
|
||||
(tls_shared_gnu2_gd_to_ie_test_SOURCES): New variable.
|
||||
(ls_shared_gnu2_gd_to_ie_test_DEPENDENCIES): New variable.
|
||||
(tls_shared_gnu2_gd_to_ie_test_LDFLAGS): New variable.
|
||||
(tls_shared_gnu2_gd_to_ie_test_LDADD): New variable.
|
||||
(tls_shared_gnu2_test): New target.
|
||||
(tls_test_gnu2_shared.so): New target.
|
||||
(tls_shared_gnu2_test_SOURCES): New variable.
|
||||
(tls_shared_gnu2_test_DEPENDENCIES): New variable.
|
||||
(tls_shared_gnu2_test_LDFLAGS): New variable.
|
||||
(tls_shared_gnu2_test_LDADD): New variable.
|
||||
* testsuite/Makefile.in: Rebuild.
|
||||
* testsuite/Makefile.
|
||||
|
||||
2008-04-11 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* testsuite/Makefile.am (justsyms_2r.o): Add dependency on
|
||||
|
@ -186,7 +186,6 @@ GCC_FALSE = @GCC_FALSE@
|
||||
GCC_TRUE = @GCC_TRUE@
|
||||
GENCAT = @GENCAT@
|
||||
GMSGFMT = @GMSGFMT@
|
||||
GREP = @GREP@
|
||||
HAVE_ZLIB_FALSE = @HAVE_ZLIB_FALSE@
|
||||
HAVE_ZLIB_TRUE = @HAVE_ZLIB_TRUE@
|
||||
INCINTL = @INCINTL@
|
||||
@ -231,7 +230,11 @@ STRIP = @STRIP@
|
||||
TARGETOBJS = @TARGETOBJS@
|
||||
THREADS_FALSE = @THREADS_FALSE@
|
||||
THREADS_TRUE = @THREADS_TRUE@
|
||||
TLS_DESCRIPTORS_FALSE = @TLS_DESCRIPTORS_FALSE@
|
||||
TLS_DESCRIPTORS_TRUE = @TLS_DESCRIPTORS_TRUE@
|
||||
TLS_FALSE = @TLS_FALSE@
|
||||
TLS_GNU2_DIALECT_FALSE = @TLS_GNU2_DIALECT_FALSE@
|
||||
TLS_GNU2_DIALECT_TRUE = @TLS_GNU2_DIALECT_TRUE@
|
||||
TLS_TRUE = @TLS_TRUE@
|
||||
USE_NLS = @USE_NLS@
|
||||
VERSION = @VERSION@
|
||||
@ -239,9 +242,10 @@ WARN_CFLAGS = @WARN_CFLAGS@
|
||||
WARN_CXXFLAGS = @WARN_CXXFLAGS@
|
||||
XGETTEXT = @XGETTEXT@
|
||||
YACC = @YACC@
|
||||
YFLAGS = @YFLAGS@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_RANLIB = @ac_ct_RANLIB@
|
||||
ac_ct_STRIP = @ac_ct_STRIP@
|
||||
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
|
||||
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
|
||||
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
|
||||
@ -258,30 +262,23 @@ build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
sysconfdir = @sysconfdir@
|
||||
|
216
gold/configure
vendored
216
gold/configure
vendored
@ -309,7 +309,7 @@ ac_includes_default="\
|
||||
# include <unistd.h>
|
||||
#endif"
|
||||
|
||||
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar THREADS_TRUE THREADS_FALSE TARGETOBJS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE YACC RANLIB ac_ct_RANLIB LN_S USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT MKINSTALLDIRS MSGFMT MSGMERGE NATIVE_LINKER_TRUE NATIVE_LINKER_FALSE GCC_TRUE GCC_FALSE FN_PTRS_IN_SO_WITHOUT_PIC_TRUE FN_PTRS_IN_SO_WITHOUT_PIC_FALSE TLS_TRUE TLS_FALSE STATIC_TLS_TRUE STATIC_TLS_FALSE CONSTRUCTOR_PRIORITY_TRUE CONSTRUCTOR_PRIORITY_FALSE WARN_CFLAGS NO_WERROR WARN_CXXFLAGS LFS_CFLAGS LIBOBJS CPP EGREP HAVE_ZLIB_TRUE HAVE_ZLIB_FALSE CXXCPP MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT LTLIBOBJS'
|
||||
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar THREADS_TRUE THREADS_FALSE TARGETOBJS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE YACC RANLIB ac_ct_RANLIB LN_S USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT MKINSTALLDIRS MSGFMT MSGMERGE NATIVE_LINKER_TRUE NATIVE_LINKER_FALSE GCC_TRUE GCC_FALSE FN_PTRS_IN_SO_WITHOUT_PIC_TRUE FN_PTRS_IN_SO_WITHOUT_PIC_FALSE TLS_TRUE TLS_FALSE STATIC_TLS_TRUE STATIC_TLS_FALSE TLS_GNU2_DIALECT_TRUE TLS_GNU2_DIALECT_FALSE TLS_DESCRIPTORS_TRUE TLS_DESCRIPTORS_FALSE CONSTRUCTOR_PRIORITY_TRUE CONSTRUCTOR_PRIORITY_FALSE WARN_CFLAGS NO_WERROR WARN_CXXFLAGS LFS_CFLAGS LIBOBJS CPP EGREP HAVE_ZLIB_TRUE HAVE_ZLIB_FALSE CXXCPP MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT LTLIBOBJS'
|
||||
ac_subst_files=''
|
||||
|
||||
# Initialize some variables set by options.
|
||||
@ -982,7 +982,7 @@ esac
|
||||
else
|
||||
echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
|
||||
fi
|
||||
cd $ac_popdir
|
||||
cd "$ac_popdir"
|
||||
done
|
||||
fi
|
||||
|
||||
@ -2648,8 +2648,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -2707,8 +2706,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -2824,8 +2822,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -2879,8 +2876,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -2925,8 +2921,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -2970,8 +2965,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -3329,8 +3323,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_cxx_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -3388,8 +3381,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_cxx_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -3460,8 +3452,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_cxx_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -3505,8 +3496,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_cxx_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -4283,8 +4273,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -4326,8 +4315,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -4384,8 +4372,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -4535,8 +4522,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -4595,8 +4581,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -4631,6 +4616,111 @@ else
|
||||
fi
|
||||
|
||||
|
||||
save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -mtls-dialect=gnu2"
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
int i;
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
(eval $ac_compile) 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; } &&
|
||||
{ ac_try='test -s conftest.$ac_objext'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
have_tls_gnu2=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
have_tls_gnu2=no
|
||||
fi
|
||||
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
CFLAGS="$save_CFLAGS"
|
||||
|
||||
|
||||
if test "$have_tls_gnu2" = "yes"; then
|
||||
TLS_GNU2_DIALECT_TRUE=
|
||||
TLS_GNU2_DIALECT_FALSE='#'
|
||||
else
|
||||
TLS_GNU2_DIALECT_TRUE='#'
|
||||
TLS_GNU2_DIALECT_FALSE=
|
||||
fi
|
||||
|
||||
|
||||
echo "$as_me:$LINENO: checking for glibc >= 2.5" >&5
|
||||
echo $ECHO_N "checking for glibc >= 2.5... $ECHO_C" >&6
|
||||
if test "${gold_cv_lib_glibc25+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
|
||||
#include <features.h>
|
||||
#if !defined __GLIBC__
|
||||
error
|
||||
#elif __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 5)
|
||||
error
|
||||
#endif
|
||||
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
(eval $ac_compile) 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; } &&
|
||||
{ ac_try='test -s conftest.$ac_objext'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
gold_cv_lib_glibc25=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
gold_cv_lib_glibc25=no
|
||||
fi
|
||||
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
echo "$as_me:$LINENO: result: $gold_cv_lib_glibc25" >&5
|
||||
echo "${ECHO_T}$gold_cv_lib_glibc25" >&6
|
||||
|
||||
|
||||
|
||||
if test "$gold_cv_lib_glibc25" = "yes"; then
|
||||
TLS_DESCRIPTORS_TRUE=
|
||||
TLS_DESCRIPTORS_FALSE='#'
|
||||
else
|
||||
TLS_DESCRIPTORS_TRUE='#'
|
||||
TLS_DESCRIPTORS_FALSE=
|
||||
fi
|
||||
|
||||
|
||||
echo "$as_me:$LINENO: checking for constructor priorities" >&5
|
||||
echo $ECHO_N "checking for constructor priorities... $ECHO_C" >&6
|
||||
if test "${gold_cv_c_conprio+set}" = set; then
|
||||
@ -4648,8 +4738,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -4823,8 +4912,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -5151,8 +5239,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -5322,8 +5409,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -5394,8 +5480,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -5449,8 +5534,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -5513,8 +5597,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -5916,8 +5999,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_cxx_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -6067,8 +6149,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_cxx_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -6252,8 +6333,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_cxx_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -6311,8 +6391,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_cxx_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
@ -6530,6 +6609,20 @@ echo "$as_me: error: conditional \"STATIC_TLS\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
if test -z "${TLS_GNU2_DIALECT_TRUE}" && test -z "${TLS_GNU2_DIALECT_FALSE}"; then
|
||||
{ { echo "$as_me:$LINENO: error: conditional \"TLS_GNU2_DIALECT\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." >&5
|
||||
echo "$as_me: error: conditional \"TLS_GNU2_DIALECT\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
if test -z "${TLS_DESCRIPTORS_TRUE}" && test -z "${TLS_DESCRIPTORS_FALSE}"; then
|
||||
{ { echo "$as_me:$LINENO: error: conditional \"TLS_DESCRIPTORS\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." >&5
|
||||
echo "$as_me: error: conditional \"TLS_DESCRIPTORS\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
if test -z "${CONSTRUCTOR_PRIORITY_TRUE}" && test -z "${CONSTRUCTOR_PRIORITY_FALSE}"; then
|
||||
{ { echo "$as_me:$LINENO: error: conditional \"CONSTRUCTOR_PRIORITY\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." >&5
|
||||
@ -7181,6 +7274,10 @@ s,@TLS_TRUE@,$TLS_TRUE,;t t
|
||||
s,@TLS_FALSE@,$TLS_FALSE,;t t
|
||||
s,@STATIC_TLS_TRUE@,$STATIC_TLS_TRUE,;t t
|
||||
s,@STATIC_TLS_FALSE@,$STATIC_TLS_FALSE,;t t
|
||||
s,@TLS_GNU2_DIALECT_TRUE@,$TLS_GNU2_DIALECT_TRUE,;t t
|
||||
s,@TLS_GNU2_DIALECT_FALSE@,$TLS_GNU2_DIALECT_FALSE,;t t
|
||||
s,@TLS_DESCRIPTORS_TRUE@,$TLS_DESCRIPTORS_TRUE,;t t
|
||||
s,@TLS_DESCRIPTORS_FALSE@,$TLS_DESCRIPTORS_FALSE,;t t
|
||||
s,@CONSTRUCTOR_PRIORITY_TRUE@,$CONSTRUCTOR_PRIORITY_TRUE,;t t
|
||||
s,@CONSTRUCTOR_PRIORITY_FALSE@,$CONSTRUCTOR_PRIORITY_FALSE,;t t
|
||||
s,@WARN_CFLAGS@,$WARN_CFLAGS,;t t
|
||||
@ -7363,11 +7460,6 @@ esac
|
||||
*) ac_INSTALL=$ac_top_builddir$INSTALL ;;
|
||||
esac
|
||||
|
||||
if test x"$ac_file" != x-; then
|
||||
{ echo "$as_me:$LINENO: creating $ac_file" >&5
|
||||
echo "$as_me: creating $ac_file" >&6;}
|
||||
rm -f "$ac_file"
|
||||
fi
|
||||
# Let's still pretend it is `configure' which instantiates (i.e., don't
|
||||
# use $as_me), people would be surprised to read:
|
||||
# /* config.h. Generated by config.status. */
|
||||
@ -7406,6 +7498,12 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
|
||||
fi;;
|
||||
esac
|
||||
done` || { (exit 1); exit 1; }
|
||||
|
||||
if test x"$ac_file" != x-; then
|
||||
{ echo "$as_me:$LINENO: creating $ac_file" >&5
|
||||
echo "$as_me: creating $ac_file" >&6;}
|
||||
rm -f "$ac_file"
|
||||
fi
|
||||
_ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF
|
||||
sed "$ac_vpsub
|
||||
|
@ -219,6 +219,27 @@ error
|
||||
|
||||
AM_CONDITIONAL(STATIC_TLS, test "$gold_cv_lib_glibc24" = "yes")
|
||||
|
||||
dnl Test for the -ftls-dialect=gnu2 option.
|
||||
save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -mtls-dialect=gnu2"
|
||||
AC_COMPILE_IFELSE([int i;], [have_tls_gnu2=yes], [have_tls_gnu2=no])
|
||||
CFLAGS="$save_CFLAGS"
|
||||
AM_CONDITIONAL(TLS_GNU2_DIALECT, test "$have_tls_gnu2" = "yes")
|
||||
|
||||
dnl On GNU/Linux TLS descriptors are supported by the dynamic loader
|
||||
dnl only with glibc 2.5 or later.
|
||||
AC_CACHE_CHECK([for glibc >= 2.5], [gold_cv_lib_glibc25],
|
||||
[AC_COMPILE_IFELSE([
|
||||
#include <features.h>
|
||||
#if !defined __GLIBC__
|
||||
error
|
||||
#elif __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 5)
|
||||
error
|
||||
#endif
|
||||
], [gold_cv_lib_glibc25=yes], [gold_cv_lib_glibc25=no])])
|
||||
|
||||
AM_CONDITIONAL(TLS_DESCRIPTORS, test "$gold_cv_lib_glibc25" = "yes")
|
||||
|
||||
dnl Check whether the compiler supports constructor priorities in
|
||||
dnl attributes, which were added in gcc 4.3.
|
||||
AC_CACHE_CHECK([for constructor priorities], [gold_cv_c_conprio],
|
||||
|
246
gold/i386.cc
246
gold/i386.cc
@ -236,6 +236,26 @@ class Target_i386 : public Sized_target<32, false>
|
||||
unsigned char* view,
|
||||
section_size_type view_size);
|
||||
|
||||
// Do a TLS_GOTDESC or TLS_DESC_CALL General-Dynamic to Initial-Exec
|
||||
// transition.
|
||||
inline void
|
||||
tls_desc_gd_to_ie(const Relocate_info<32, false>*, size_t relnum,
|
||||
Output_segment* tls_segment,
|
||||
const elfcpp::Rel<32, false>&, unsigned int r_type,
|
||||
elfcpp::Elf_types<32>::Elf_Addr value,
|
||||
unsigned char* view,
|
||||
section_size_type view_size);
|
||||
|
||||
// Do a TLS_GOTDESC or TLS_DESC_CALL General-Dynamic to Local-Exec
|
||||
// transition.
|
||||
inline void
|
||||
tls_desc_gd_to_le(const Relocate_info<32, false>*, size_t relnum,
|
||||
Output_segment* tls_segment,
|
||||
const elfcpp::Rel<32, false>&, unsigned int r_type,
|
||||
elfcpp::Elf_types<32>::Elf_Addr value,
|
||||
unsigned char* view,
|
||||
section_size_type view_size);
|
||||
|
||||
// Do a TLS Local-Dynamic to Local-Exec transition.
|
||||
inline void
|
||||
tls_ld_to_le(const Relocate_info<32, false>*, size_t relnum,
|
||||
@ -343,9 +363,10 @@ class Target_i386 : public Sized_target<32, false>
|
||||
enum Got_type
|
||||
{
|
||||
GOT_TYPE_STANDARD = 0, // GOT entry for a regular symbol
|
||||
GOT_TYPE_TLS_OFFSET = 1, // GOT entry for TLS offset
|
||||
GOT_TYPE_TLS_PAIR = 2, // GOT entry for TLS module/offset pair
|
||||
GOT_TYPE_TLS_DESC = 3 // GOT entry for TLS_DESC pair
|
||||
GOT_TYPE_TLS_NOFFSET = 1, // GOT entry for negative TLS offset
|
||||
GOT_TYPE_TLS_OFFSET = 2, // GOT entry for positive TLS offset
|
||||
GOT_TYPE_TLS_PAIR = 3, // GOT entry for TLS module/offset pair
|
||||
GOT_TYPE_TLS_DESC = 4 // GOT entry for TLS_DESC pair
|
||||
};
|
||||
|
||||
// The GOT section.
|
||||
@ -360,7 +381,7 @@ class Target_i386 : public Sized_target<32, false>
|
||||
Copy_relocs<32, false>* copy_relocs_;
|
||||
// Space for variables copied with a COPY reloc.
|
||||
Output_data_space* dynbss_;
|
||||
// Offset of the GOT entry for the TLS module index;
|
||||
// Offset of the GOT entry for the TLS module index.
|
||||
unsigned int got_mod_index_offset_;
|
||||
};
|
||||
|
||||
@ -704,7 +725,6 @@ Target_i386::got_mod_index_entry(Symbol_table* symtab, Layout* layout,
|
||||
unsigned int got_offset = got->add_constant(0);
|
||||
rel_dyn->add_local(object, 0, elfcpp::R_386_TLS_DTPMOD32, got,
|
||||
got_offset);
|
||||
got->add_constant(0);
|
||||
this->got_mod_index_offset_ = got_offset;
|
||||
}
|
||||
return this->got_mod_index_offset_;
|
||||
@ -1011,13 +1031,25 @@ Target_i386::Scan::local(const General_options&,
|
||||
break;
|
||||
|
||||
case elfcpp::R_386_TLS_GOTDESC: // Global-dynamic (from ~oliva)
|
||||
case elfcpp::R_386_TLS_DESC_CALL:
|
||||
// FIXME: If not relaxing to LE, we need to generate
|
||||
// a GOT entry with an R_386_TLS_DESC reloc.
|
||||
if (optimized_type != tls::TLSOPT_TO_LE)
|
||||
if (optimized_type == tls::TLSOPT_NONE)
|
||||
{
|
||||
// Create a double GOT entry with an R_386_TLS_DESC reloc.
|
||||
Output_data_got<32, false>* got
|
||||
= target->got_section(symtab, layout);
|
||||
unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
|
||||
got->add_local_pair_with_rel(object, r_sym,
|
||||
lsym.get_st_shndx(),
|
||||
GOT_TYPE_TLS_DESC,
|
||||
target->rel_dyn_section(layout),
|
||||
elfcpp::R_386_TLS_DESC, 0);
|
||||
}
|
||||
else if (optimized_type != tls::TLSOPT_TO_LE)
|
||||
unsupported_reloc_local(object, r_type);
|
||||
break;
|
||||
|
||||
case elfcpp::R_386_TLS_DESC_CALL:
|
||||
break;
|
||||
|
||||
case elfcpp::R_386_TLS_LDM: // Local-dynamic
|
||||
if (optimized_type == tls::TLSOPT_NONE)
|
||||
{
|
||||
@ -1057,7 +1089,10 @@ Target_i386::Scan::local(const General_options&,
|
||||
unsigned int dyn_r_type = (r_type == elfcpp::R_386_TLS_IE_32
|
||||
? elfcpp::R_386_TLS_TPOFF32
|
||||
: elfcpp::R_386_TLS_TPOFF);
|
||||
got->add_local_with_rel(object, r_sym, GOT_TYPE_TLS_OFFSET,
|
||||
unsigned int got_type = (r_type == elfcpp::R_386_TLS_IE_32
|
||||
? GOT_TYPE_TLS_OFFSET
|
||||
: GOT_TYPE_TLS_NOFFSET);
|
||||
got->add_local_with_rel(object, r_sym, got_type,
|
||||
target->rel_dyn_section(layout),
|
||||
dyn_r_type);
|
||||
}
|
||||
@ -1313,21 +1348,38 @@ Target_i386::Scan::global(const General_options& options,
|
||||
// Create a GOT entry for the tp-relative offset.
|
||||
Output_data_got<32, false>* got
|
||||
= target->got_section(symtab, layout);
|
||||
got->add_global_with_rel(gsym, GOT_TYPE_TLS_OFFSET,
|
||||
got->add_global_with_rel(gsym, GOT_TYPE_TLS_NOFFSET,
|
||||
target->rel_dyn_section(layout),
|
||||
elfcpp::R_386_TLS_TPOFF32);
|
||||
elfcpp::R_386_TLS_TPOFF);
|
||||
}
|
||||
else if (optimized_type != tls::TLSOPT_TO_LE)
|
||||
unsupported_reloc_global(object, r_type, gsym);
|
||||
break;
|
||||
|
||||
case elfcpp::R_386_TLS_GOTDESC: // Global-dynamic (~oliva url)
|
||||
case elfcpp::R_386_TLS_DESC_CALL:
|
||||
// FIXME: If not relaxing to LE, we need to generate
|
||||
// a GOT entry with an R_386_TLS_DESC reloc.
|
||||
if (optimized_type != tls::TLSOPT_TO_LE)
|
||||
if (optimized_type == tls::TLSOPT_NONE)
|
||||
{
|
||||
// Create a double GOT entry with an R_386_TLS_DESC reloc.
|
||||
Output_data_got<32, false>* got
|
||||
= target->got_section(symtab, layout);
|
||||
got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_DESC,
|
||||
target->rel_dyn_section(layout),
|
||||
elfcpp::R_386_TLS_DESC, 0);
|
||||
}
|
||||
else if (optimized_type == tls::TLSOPT_TO_IE)
|
||||
{
|
||||
// Create a GOT entry for the tp-relative offset.
|
||||
Output_data_got<32, false>* got
|
||||
= target->got_section(symtab, layout);
|
||||
got->add_global_with_rel(gsym, GOT_TYPE_TLS_NOFFSET,
|
||||
target->rel_dyn_section(layout),
|
||||
elfcpp::R_386_TLS_TPOFF);
|
||||
}
|
||||
else if (optimized_type != tls::TLSOPT_TO_LE)
|
||||
unsupported_reloc_global(object, r_type, gsym);
|
||||
unsupported_reloc_global(object, r_type, gsym);
|
||||
break;
|
||||
|
||||
case elfcpp::R_386_TLS_DESC_CALL:
|
||||
break;
|
||||
|
||||
case elfcpp::R_386_TLS_LDM: // Local-dynamic
|
||||
@ -1366,7 +1418,10 @@ Target_i386::Scan::global(const General_options& options,
|
||||
unsigned int dyn_r_type = (r_type == elfcpp::R_386_TLS_IE_32
|
||||
? elfcpp::R_386_TLS_TPOFF32
|
||||
: elfcpp::R_386_TLS_TPOFF);
|
||||
got->add_global_with_rel(gsym, GOT_TYPE_TLS_OFFSET,
|
||||
unsigned int got_type = (r_type == elfcpp::R_386_TLS_IE_32
|
||||
? GOT_TYPE_TLS_OFFSET
|
||||
: GOT_TYPE_TLS_NOFFSET);
|
||||
got->add_global_with_rel(gsym, got_type,
|
||||
target->rel_dyn_section(layout),
|
||||
dyn_r_type);
|
||||
}
|
||||
@ -1782,19 +1837,20 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int got_type = (optimized_type == tls::TLSOPT_TO_IE
|
||||
? GOT_TYPE_TLS_NOFFSET
|
||||
: GOT_TYPE_TLS_PAIR);
|
||||
unsigned int got_offset;
|
||||
if (gsym != NULL)
|
||||
{
|
||||
gold_assert(gsym->has_got_offset(GOT_TYPE_TLS_PAIR));
|
||||
got_offset = (gsym->got_offset(GOT_TYPE_TLS_PAIR)
|
||||
- target->got_size());
|
||||
gold_assert(gsym->has_got_offset(got_type));
|
||||
got_offset = gsym->got_offset(got_type) - target->got_size();
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());
|
||||
gold_assert(object->local_has_got_offset(r_sym,
|
||||
GOT_TYPE_TLS_PAIR));
|
||||
got_offset = (object->local_got_offset(r_sym, GOT_TYPE_TLS_PAIR)
|
||||
gold_assert(object->local_has_got_offset(r_sym, got_type));
|
||||
got_offset = (object->local_got_offset(r_sym, got_type)
|
||||
- target->got_size());
|
||||
}
|
||||
if (optimized_type == tls::TLSOPT_TO_IE)
|
||||
@ -1819,6 +1875,50 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
|
||||
|
||||
case elfcpp::R_386_TLS_GOTDESC: // Global-dynamic (from ~oliva url)
|
||||
case elfcpp::R_386_TLS_DESC_CALL:
|
||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
this->tls_desc_gd_to_le(relinfo, relnum, tls_segment,
|
||||
rel, r_type, value, view,
|
||||
view_size);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int got_type = (optimized_type == tls::TLSOPT_TO_IE
|
||||
? GOT_TYPE_TLS_NOFFSET
|
||||
: GOT_TYPE_TLS_DESC);
|
||||
unsigned int got_offset;
|
||||
if (gsym != NULL)
|
||||
{
|
||||
gold_assert(gsym->has_got_offset(got_type));
|
||||
got_offset = gsym->got_offset(got_type) - target->got_size();
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());
|
||||
gold_assert(object->local_has_got_offset(r_sym, got_type));
|
||||
got_offset = (object->local_got_offset(r_sym, got_type)
|
||||
- target->got_size());
|
||||
}
|
||||
if (optimized_type == tls::TLSOPT_TO_IE)
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
this->tls_desc_gd_to_ie(relinfo, relnum, tls_segment, rel, r_type,
|
||||
got_offset, view, view_size);
|
||||
break;
|
||||
}
|
||||
else if (optimized_type == tls::TLSOPT_NONE)
|
||||
{
|
||||
if (r_type == elfcpp::R_386_TLS_GOTDESC)
|
||||
{
|
||||
// Relocate the field with the offset of the pair of GOT
|
||||
// entries.
|
||||
Relocate_functions<32, false>::rel32(view, got_offset);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
|
||||
_("unsupported reloc %u"),
|
||||
r_type);
|
||||
@ -1882,19 +1982,20 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
|
||||
{
|
||||
// Relocate the field with the offset of the GOT entry for
|
||||
// the tp-relative offset of the symbol.
|
||||
unsigned int got_type = (r_type == elfcpp::R_386_TLS_IE_32
|
||||
? GOT_TYPE_TLS_OFFSET
|
||||
: GOT_TYPE_TLS_NOFFSET);
|
||||
unsigned int got_offset;
|
||||
if (gsym != NULL)
|
||||
{
|
||||
gold_assert(gsym->has_got_offset(GOT_TYPE_TLS_OFFSET));
|
||||
got_offset = gsym->got_offset(GOT_TYPE_TLS_OFFSET);
|
||||
gold_assert(gsym->has_got_offset(got_type));
|
||||
got_offset = gsym->got_offset(got_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());
|
||||
gold_assert(object->local_has_got_offset(r_sym,
|
||||
GOT_TYPE_TLS_OFFSET));
|
||||
got_offset = object->local_got_offset(r_sym,
|
||||
GOT_TYPE_TLS_OFFSET);
|
||||
gold_assert(object->local_has_got_offset(r_sym, got_type));
|
||||
got_offset = object->local_got_offset(r_sym, got_type);
|
||||
}
|
||||
// For the R_386_TLS_IE relocation, we need to apply the
|
||||
// absolute address of the GOT entry.
|
||||
@ -2004,7 +2105,7 @@ Target_i386::Relocate::tls_gd_to_le(const Relocate_info<32, false>* relinfo,
|
||||
inline void
|
||||
Target_i386::Relocate::tls_gd_to_ie(const Relocate_info<32, false>* relinfo,
|
||||
size_t relnum,
|
||||
Output_segment* tls_segment,
|
||||
Output_segment*,
|
||||
const elfcpp::Rel<32, false>& rel,
|
||||
unsigned int,
|
||||
elfcpp::Elf_types<32>::Elf_Addr value,
|
||||
@ -2026,9 +2127,8 @@ Target_i386::Relocate::tls_gd_to_ie(const Relocate_info<32, false>* relinfo,
|
||||
|
||||
int roff = 5;
|
||||
|
||||
// FIXME: For now, support only one form.
|
||||
tls::check_tls(relinfo, relnum, rel.get_r_offset(),
|
||||
op1 == 0x8d && op2 == 0x04);
|
||||
// FIXME: For now, support only the first (SIB) form.
|
||||
tls::check_tls(relinfo, relnum, rel.get_r_offset(), op2 == 0x04);
|
||||
|
||||
if (op2 == 0x04)
|
||||
{
|
||||
@ -2058,7 +2158,6 @@ Target_i386::Relocate::tls_gd_to_ie(const Relocate_info<32, false>* relinfo,
|
||||
}
|
||||
}
|
||||
|
||||
value = tls_segment->memsz() - value;
|
||||
Relocate_functions<32, false>::rel32(view + roff, value);
|
||||
|
||||
// The next reloc should be a PLT32 reloc against __tls_get_addr.
|
||||
@ -2066,6 +2165,83 @@ Target_i386::Relocate::tls_gd_to_ie(const Relocate_info<32, false>* relinfo,
|
||||
this->skip_call_tls_get_addr_ = true;
|
||||
}
|
||||
|
||||
// Do a relocation in which we convert a TLS_GOTDESC or TLS_DESC_CALL
|
||||
// General-Dynamic to a Local-Exec.
|
||||
|
||||
inline void
|
||||
Target_i386::Relocate::tls_desc_gd_to_le(
|
||||
const Relocate_info<32, false>* relinfo,
|
||||
size_t relnum,
|
||||
Output_segment* tls_segment,
|
||||
const elfcpp::Rel<32, false>& rel,
|
||||
unsigned int r_type,
|
||||
elfcpp::Elf_types<32>::Elf_Addr value,
|
||||
unsigned char* view,
|
||||
section_size_type view_size)
|
||||
{
|
||||
if (r_type == elfcpp::R_386_TLS_GOTDESC)
|
||||
{
|
||||
// leal foo@TLSDESC(%ebx), %eax
|
||||
// ==> leal foo@NTPOFF, %eax
|
||||
tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
|
||||
tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 4);
|
||||
tls::check_tls(relinfo, relnum, rel.get_r_offset(),
|
||||
view[-2] == 0x8d && view[-1] == 0x83);
|
||||
view[-1] = 0x05;
|
||||
value -= tls_segment->memsz();
|
||||
Relocate_functions<32, false>::rel32(view, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// call *foo@TLSCALL(%eax)
|
||||
// ==> nop; nop
|
||||
gold_assert(r_type == elfcpp::R_386_TLS_DESC_CALL);
|
||||
tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 2);
|
||||
tls::check_tls(relinfo, relnum, rel.get_r_offset(),
|
||||
view[0] == 0xff && view[1] == 0x10);
|
||||
view[0] = 0x66;
|
||||
view[1] = 0x90;
|
||||
}
|
||||
}
|
||||
|
||||
// Do a relocation in which we convert a TLS_GOTDESC or TLS_DESC_CALL
|
||||
// General-Dynamic to an Initial-Exec.
|
||||
|
||||
inline void
|
||||
Target_i386::Relocate::tls_desc_gd_to_ie(
|
||||
const Relocate_info<32, false>* relinfo,
|
||||
size_t relnum,
|
||||
Output_segment*,
|
||||
const elfcpp::Rel<32, false>& rel,
|
||||
unsigned int r_type,
|
||||
elfcpp::Elf_types<32>::Elf_Addr value,
|
||||
unsigned char* view,
|
||||
section_size_type view_size)
|
||||
{
|
||||
if (r_type == elfcpp::R_386_TLS_GOTDESC)
|
||||
{
|
||||
// leal foo@TLSDESC(%ebx), %eax
|
||||
// ==> movl foo@GOTNTPOFF(%ebx), %eax
|
||||
tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, -2);
|
||||
tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 4);
|
||||
tls::check_tls(relinfo, relnum, rel.get_r_offset(),
|
||||
view[-2] == 0x8d && view[-1] == 0x83);
|
||||
view[-2] = 0x8b;
|
||||
Relocate_functions<32, false>::rel32(view, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// call *foo@TLSCALL(%eax)
|
||||
// ==> nop; nop
|
||||
gold_assert(r_type == elfcpp::R_386_TLS_DESC_CALL);
|
||||
tls::check_range(relinfo, relnum, rel.get_r_offset(), view_size, 2);
|
||||
tls::check_tls(relinfo, relnum, rel.get_r_offset(),
|
||||
view[0] == 0xff && view[1] == 0x10);
|
||||
view[0] = 0x66;
|
||||
view[1] = 0x90;
|
||||
}
|
||||
}
|
||||
|
||||
// Do a relocation in which we convert a TLS Local-Dynamic to a
|
||||
// Local-Exec.
|
||||
|
||||
|
@ -1342,16 +1342,12 @@ Output_data_dynamic::Dynamic_entry::write(
|
||||
const Stringpool* pool) const
|
||||
{
|
||||
typename elfcpp::Elf_types<size>::Elf_WXword val;
|
||||
switch (this->classification_)
|
||||
switch (this->offset_)
|
||||
{
|
||||
case DYNAMIC_NUMBER:
|
||||
val = this->u_.val;
|
||||
break;
|
||||
|
||||
case DYNAMIC_SECTION_ADDRESS:
|
||||
val = this->u_.od->address();
|
||||
break;
|
||||
|
||||
case DYNAMIC_SECTION_SIZE:
|
||||
val = this->u_.od->data_size();
|
||||
break;
|
||||
@ -1369,7 +1365,8 @@ Output_data_dynamic::Dynamic_entry::write(
|
||||
break;
|
||||
|
||||
default:
|
||||
gold_unreachable();
|
||||
val = this->u_.od->address() + this->offset_;
|
||||
break;
|
||||
}
|
||||
|
||||
elfcpp::Dyn_write<size, big_endian> dw(pov);
|
||||
|
@ -1534,6 +1534,13 @@ class Output_data_dynamic : public Output_section_data
|
||||
add_section_address(elfcpp::DT tag, const Output_data* od)
|
||||
{ this->add_entry(Dynamic_entry(tag, od, false)); }
|
||||
|
||||
// Add a new dynamic entry with the address of output data
|
||||
// plus a constant offset.
|
||||
void
|
||||
add_section_plus_offset(elfcpp::DT tag, const Output_data* od,
|
||||
unsigned int offset)
|
||||
{ this->add_entry(Dynamic_entry(tag, od, offset)); }
|
||||
|
||||
// Add a new dynamic entry with the size of output data.
|
||||
void
|
||||
add_section_size(elfcpp::DT tag, const Output_data* od)
|
||||
@ -1573,25 +1580,31 @@ class Output_data_dynamic : public Output_section_data
|
||||
public:
|
||||
// Create an entry with a fixed numeric value.
|
||||
Dynamic_entry(elfcpp::DT tag, unsigned int val)
|
||||
: tag_(tag), classification_(DYNAMIC_NUMBER)
|
||||
: tag_(tag), offset_(DYNAMIC_NUMBER)
|
||||
{ this->u_.val = val; }
|
||||
|
||||
// Create an entry with the size or address of a section.
|
||||
Dynamic_entry(elfcpp::DT tag, const Output_data* od, bool section_size)
|
||||
: tag_(tag),
|
||||
classification_(section_size
|
||||
? DYNAMIC_SECTION_SIZE
|
||||
: DYNAMIC_SECTION_ADDRESS)
|
||||
offset_(section_size
|
||||
? DYNAMIC_SECTION_SIZE
|
||||
: DYNAMIC_SECTION_ADDRESS)
|
||||
{ this->u_.od = od; }
|
||||
|
||||
// Create an entry with the address of a section plus a constant offset.
|
||||
Dynamic_entry(elfcpp::DT tag, const Output_data* od, unsigned int offset)
|
||||
: tag_(tag),
|
||||
offset_(offset)
|
||||
{ this->u_.od = od; }
|
||||
|
||||
// Create an entry with the address of a symbol.
|
||||
Dynamic_entry(elfcpp::DT tag, const Symbol* sym)
|
||||
: tag_(tag), classification_(DYNAMIC_SYMBOL)
|
||||
: tag_(tag), offset_(DYNAMIC_SYMBOL)
|
||||
{ this->u_.sym = sym; }
|
||||
|
||||
// Create an entry with a string.
|
||||
Dynamic_entry(elfcpp::DT tag, const char* str)
|
||||
: tag_(tag), classification_(DYNAMIC_STRING)
|
||||
: tag_(tag), offset_(DYNAMIC_STRING)
|
||||
{ this->u_.str = str; }
|
||||
|
||||
// Write the dynamic entry to an output view.
|
||||
@ -1600,25 +1613,27 @@ class Output_data_dynamic : public Output_section_data
|
||||
write(unsigned char* pov, const Stringpool*) const;
|
||||
|
||||
private:
|
||||
// Classification is encoded in the OFFSET field.
|
||||
enum Classification
|
||||
{
|
||||
// Number.
|
||||
DYNAMIC_NUMBER,
|
||||
// Section address.
|
||||
DYNAMIC_SECTION_ADDRESS,
|
||||
DYNAMIC_SECTION_ADDRESS = 0,
|
||||
// Number.
|
||||
DYNAMIC_NUMBER = -1U,
|
||||
// Section size.
|
||||
DYNAMIC_SECTION_SIZE,
|
||||
DYNAMIC_SECTION_SIZE = -2U,
|
||||
// Symbol adress.
|
||||
DYNAMIC_SYMBOL,
|
||||
DYNAMIC_SYMBOL = -3U,
|
||||
// String.
|
||||
DYNAMIC_STRING
|
||||
DYNAMIC_STRING = -4U
|
||||
// Any other value indicates a section address plus OFFSET.
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
// For DYNAMIC_NUMBER.
|
||||
unsigned int val;
|
||||
// For DYNAMIC_SECTION_ADDRESS and DYNAMIC_SECTION_SIZE.
|
||||
// For DYNAMIC_SECTION_SIZE and section address plus OFFSET.
|
||||
const Output_data* od;
|
||||
// For DYNAMIC_SYMBOL.
|
||||
const Symbol* sym;
|
||||
@ -1627,8 +1642,8 @@ class Output_data_dynamic : public Output_section_data
|
||||
} u_;
|
||||
// The dynamic tag.
|
||||
elfcpp::DT tag_;
|
||||
// The type of entry.
|
||||
Classification classification_;
|
||||
// The type of entry (Classification) or offset within a section.
|
||||
unsigned int offset_;
|
||||
};
|
||||
|
||||
// Add an entry to the list.
|
||||
|
@ -410,12 +410,15 @@ check_PROGRAMS += tls_test
|
||||
check_PROGRAMS += tls_pic_test
|
||||
check_PROGRAMS += tls_shared_test
|
||||
check_PROGRAMS += tls_shared_ie_test
|
||||
check_PROGRAMS += tls_shared_gd_to_ie_test
|
||||
tls_test_pic.o: tls_test.cc
|
||||
$(CXXCOMPILE) -c -fpic -o $@ $<
|
||||
tls_test_file2_pic.o: tls_test_file2.cc
|
||||
$(CXXCOMPILE) -c -fpic -o $@ $<
|
||||
tls_test_shared.so: tls_test_pic.o tls_test_file2_pic.o gcctestdir/ld
|
||||
$(CXXLINK) -Bgcctestdir/ -shared tls_test_pic.o tls_test_file2_pic.o
|
||||
tls_test_shared2.so: tls_test_file2_pic.o gcctestdir/ld
|
||||
$(CXXLINK) -Bgcctestdir/ -shared tls_test_file2_pic.o
|
||||
|
||||
tls_test_pic_ie.o: tls_test.cc
|
||||
$(CXXCOMPILE) -c -fpic -ftls-model=initial-exec -o $@ $<
|
||||
@ -444,6 +447,43 @@ tls_shared_ie_test_DEPENDENCIES = gcctestdir/ld tls_test_ie_shared.so
|
||||
tls_shared_ie_test_LDFLAGS = -Bgcctestdir/ -Wl,-R,.
|
||||
tls_shared_ie_test_LDADD = tls_test_ie_shared.so -lpthread
|
||||
|
||||
tls_shared_gd_to_ie_test_SOURCES = tls_test_main.cc
|
||||
tls_shared_gd_to_ie_test_DEPENDENCIES = gcctestdir/ld tls_test_pic.o tls_test_shared2.so
|
||||
tls_shared_gd_to_ie_test_LDFLAGS = -Bgcctestdir/ -Wl,-R,.
|
||||
tls_shared_gd_to_ie_test_LDADD = tls_test_pic.o tls_test_shared2.so -lpthread
|
||||
|
||||
if TLS_GNU2_DIALECT
|
||||
|
||||
check_PROGRAMS += tls_shared_gnu2_gd_to_ie_test
|
||||
|
||||
tls_test_gnu2.o: tls_test.cc
|
||||
$(CXXCOMPILE) -c -fpic -mtls-dialect=gnu2 -o $@ $<
|
||||
tls_test_file2_gnu2.o: tls_test_file2.cc
|
||||
$(CXXCOMPILE) -c -fpic -mtls-dialect=gnu2 -o $@ $<
|
||||
tls_test_gnu2_shared2.so: tls_test_file2_gnu2.o gcctestdir/ld
|
||||
$(CXXLINK) -Bgcctestdir/ -shared tls_test_file2_gnu2.o
|
||||
|
||||
tls_shared_gnu2_gd_to_ie_test_SOURCES = tls_test_main.cc
|
||||
tls_shared_gnu2_gd_to_ie_test_DEPENDENCIES = gcctestdir/ld tls_test_gnu2.o tls_test_gnu2_shared2.so
|
||||
tls_shared_gnu2_gd_to_ie_test_LDFLAGS = -Bgcctestdir/ -Wl,-R,.
|
||||
tls_shared_gnu2_gd_to_ie_test_LDADD = tls_test_gnu2.o tls_test_gnu2_shared2.so -lpthread
|
||||
|
||||
if TLS_DESCRIPTORS
|
||||
|
||||
check_PROGRAMS += tls_shared_gnu2_test
|
||||
|
||||
tls_test_gnu2_shared.so: tls_test_gnu2.o tls_test_file2_gnu2.o gcctestdir/ld
|
||||
$(CXXLINK) -Bgcctestdir/ -shared tls_test_gnu2.o tls_test_file2_gnu2.o
|
||||
|
||||
tls_shared_gnu2_test_SOURCES = tls_test_main.cc
|
||||
tls_shared_gnu2_test_DEPENDENCIES = gcctestdir/ld tls_test_gnu2_shared.so
|
||||
tls_shared_gnu2_test_LDFLAGS = -Bgcctestdir/ -Wl,-R,.
|
||||
tls_shared_gnu2_test_LDADD = tls_test_gnu2_shared.so -lpthread
|
||||
|
||||
endif TLS_DESCRIPTORS
|
||||
|
||||
endif TLS_GNU2_DIALECT
|
||||
|
||||
if STATIC_TLS
|
||||
check_PROGRAMS += tls_static_test
|
||||
check_PROGRAMS += tls_static_pic_test
|
||||
|
@ -46,7 +46,7 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
|
||||
$(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
|
||||
$(am__EXEEXT_4) $(am__EXEEXT_5) $(am__EXEEXT_6) \
|
||||
$(am__EXEEXT_7) $(am__EXEEXT_8) $(am__EXEEXT_9) \
|
||||
$(am__EXEEXT_10)
|
||||
$(am__EXEEXT_10) $(am__EXEEXT_11) $(am__EXEEXT_12)
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_1 = basic_test \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ basic_static_test basic_pic_test \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ basic_static_pic_test \
|
||||
@ -146,14 +146,17 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@am__append_4 = tls_test \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@ tls_pic_test \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@ tls_shared_test \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@ tls_shared_ie_test
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@ tls_shared_ie_test \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@ tls_shared_gd_to_ie_test
|
||||
@GCC_FALSE@tls_test_DEPENDENCIES =
|
||||
@NATIVE_LINKER_FALSE@tls_test_DEPENDENCIES =
|
||||
@TLS_FALSE@tls_test_DEPENDENCIES =
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@STATIC_TLS_TRUE@@TLS_TRUE@am__append_5 = tls_static_test \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@am__append_5 = tls_shared_gnu2_gd_to_ie_test
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_DESCRIPTORS_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@am__append_6 = tls_shared_gnu2_test
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@STATIC_TLS_TRUE@@TLS_TRUE@am__append_7 = tls_static_test \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@STATIC_TLS_TRUE@@TLS_TRUE@ tls_static_pic_test
|
||||
@FN_PTRS_IN_SO_WITHOUT_PIC_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@am__append_6 = tls_shared_nonpic_test
|
||||
@CONSTRUCTOR_PRIORITY_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_7 = initpri1
|
||||
@FN_PTRS_IN_SO_WITHOUT_PIC_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@am__append_8 = tls_shared_nonpic_test
|
||||
@CONSTRUCTOR_PRIORITY_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_9 = initpri1
|
||||
@CONSTRUCTOR_PRIORITY_FALSE@initpri1_DEPENDENCIES = libgoldtest.a \
|
||||
@CONSTRUCTOR_PRIORITY_FALSE@ ../libgold.a \
|
||||
@CONSTRUCTOR_PRIORITY_FALSE@ ../../libiberty/libiberty.a \
|
||||
@ -170,7 +173,7 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
|
||||
# Test --detect-odr-violations
|
||||
|
||||
# Similar to --detect-odr-violations: check for undefined symbols in .so's
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_8 = debug_msg.sh \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_10 = debug_msg.sh \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ undef_symbol.sh ver_test_2.sh \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_4.sh ver_test_5.sh \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_7.sh \
|
||||
@ -183,7 +186,7 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
|
||||
|
||||
# We also want to make sure we do something reasonable when there's no
|
||||
# debug info available. For the best test, we use .so's.
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_9 = debug_msg.err \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_11 = debug_msg.err \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ debug_msg_so.err \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ debug_msg_ndebug.err \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ undef_symbol.err ver_test_2.syms \
|
||||
@ -191,7 +194,7 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_7.syms \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_matching_test.stdout \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_3.stdout
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_10 = debug_msg.err \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_12 = debug_msg.err \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ debug_msg_so.err \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ debug_msg_ndebug.err \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ undef_symbol.err \
|
||||
@ -199,17 +202,17 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_3.stdout
|
||||
|
||||
# Test -o when emitting to a special file (such as something in /dev).
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_11 = flagstest_o_specialfile
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_13 = flagstest_o_specialfile
|
||||
|
||||
# Test --compress-debug-sections. FIXME: check we actually compress.
|
||||
|
||||
# The specialfile output has a tricky case when we also compress debug
|
||||
# sections, because it requires output-file resizing.
|
||||
@GCC_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_LINKER_TRUE@am__append_12 = flagstest_compress_debug_sections \
|
||||
@GCC_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_LINKER_TRUE@am__append_14 = flagstest_compress_debug_sections \
|
||||
@GCC_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_LINKER_TRUE@ flagstest_o_specialfile_and_compress_debug_sections
|
||||
|
||||
# Test symbol versioning.
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_13 = ver_test ver_test_2 \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_15 = ver_test ver_test_2 \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_6 script_test_1 \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_2 justsyms \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ binary_test script_test_3
|
||||
@ -304,15 +307,18 @@ libgoldtest_a_OBJECTS = $(am_libgoldtest_a_OBJECTS)
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@ tls_test$(EXEEXT) \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@ tls_pic_test$(EXEEXT) \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@ tls_shared_test$(EXEEXT) \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@ tls_shared_ie_test$(EXEEXT)
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@STATIC_TLS_TRUE@@TLS_TRUE@am__EXEEXT_5 = tls_static_test$(EXEEXT) \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@ tls_shared_ie_test$(EXEEXT) \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@ tls_shared_gd_to_ie_test$(EXEEXT)
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@am__EXEEXT_5 = tls_shared_gnu2_gd_to_ie_test$(EXEEXT)
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_DESCRIPTORS_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@am__EXEEXT_6 = tls_shared_gnu2_test$(EXEEXT)
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@STATIC_TLS_TRUE@@TLS_TRUE@am__EXEEXT_7 = tls_static_test$(EXEEXT) \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@STATIC_TLS_TRUE@@TLS_TRUE@ tls_static_pic_test$(EXEEXT)
|
||||
@FN_PTRS_IN_SO_WITHOUT_PIC_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@am__EXEEXT_6 = tls_shared_nonpic_test$(EXEEXT)
|
||||
@CONSTRUCTOR_PRIORITY_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@am__EXEEXT_7 = initpri1$(EXEEXT)
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__EXEEXT_8 = flagstest_o_specialfile$(EXEEXT)
|
||||
@GCC_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_LINKER_TRUE@am__EXEEXT_9 = flagstest_compress_debug_sections$(EXEEXT) \
|
||||
@FN_PTRS_IN_SO_WITHOUT_PIC_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@am__EXEEXT_8 = tls_shared_nonpic_test$(EXEEXT)
|
||||
@CONSTRUCTOR_PRIORITY_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@am__EXEEXT_9 = initpri1$(EXEEXT)
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__EXEEXT_10 = flagstest_o_specialfile$(EXEEXT)
|
||||
@GCC_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_LINKER_TRUE@am__EXEEXT_11 = flagstest_compress_debug_sections$(EXEEXT) \
|
||||
@GCC_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_LINKER_TRUE@ flagstest_o_specialfile_and_compress_debug_sections$(EXEEXT)
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__EXEEXT_10 = ver_test$(EXEEXT) \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__EXEEXT_12 = ver_test$(EXEEXT) \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_2$(EXEEXT) \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_6$(EXEEXT) \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_1$(EXEEXT) \
|
||||
@ -482,6 +488,17 @@ script_test_3_DEPENDENCIES = libgoldtest.a ../libgold.a \
|
||||
am__tls_pic_test_SOURCES_DIST = tls_test_main.cc
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@am_tls_pic_test_OBJECTS = tls_test_main.$(OBJEXT)
|
||||
tls_pic_test_OBJECTS = $(am_tls_pic_test_OBJECTS)
|
||||
am__tls_shared_gd_to_ie_test_SOURCES_DIST = tls_test_main.cc
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@am_tls_shared_gd_to_ie_test_OBJECTS = tls_test_main.$(OBJEXT)
|
||||
tls_shared_gd_to_ie_test_OBJECTS = \
|
||||
$(am_tls_shared_gd_to_ie_test_OBJECTS)
|
||||
am__tls_shared_gnu2_gd_to_ie_test_SOURCES_DIST = tls_test_main.cc
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@am_tls_shared_gnu2_gd_to_ie_test_OBJECTS = tls_test_main.$(OBJEXT)
|
||||
tls_shared_gnu2_gd_to_ie_test_OBJECTS = \
|
||||
$(am_tls_shared_gnu2_gd_to_ie_test_OBJECTS)
|
||||
am__tls_shared_gnu2_test_SOURCES_DIST = tls_test_main.cc
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_DESCRIPTORS_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@am_tls_shared_gnu2_test_OBJECTS = tls_test_main.$(OBJEXT)
|
||||
tls_shared_gnu2_test_OBJECTS = $(am_tls_shared_gnu2_test_OBJECTS)
|
||||
am__tls_shared_ie_test_SOURCES_DIST = tls_test_main.cc
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@am_tls_shared_ie_test_OBJECTS = tls_test_main.$(OBJEXT)
|
||||
tls_shared_ie_test_OBJECTS = $(am_tls_shared_ie_test_OBJECTS)
|
||||
@ -685,7 +702,9 @@ SOURCES = $(libgoldtest_a_SOURCES) basic_pic_test.c \
|
||||
$(initpri1_SOURCES) $(justsyms_SOURCES) \
|
||||
$(object_unittest_SOURCES) $(script_test_1_SOURCES) \
|
||||
$(script_test_2_SOURCES) script_test_3.c \
|
||||
$(tls_pic_test_SOURCES) $(tls_shared_ie_test_SOURCES) \
|
||||
$(tls_pic_test_SOURCES) $(tls_shared_gd_to_ie_test_SOURCES) \
|
||||
$(tls_shared_gnu2_gd_to_ie_test_SOURCES) \
|
||||
$(tls_shared_gnu2_test_SOURCES) $(tls_shared_ie_test_SOURCES) \
|
||||
$(tls_shared_nonpic_test_SOURCES) $(tls_shared_test_SOURCES) \
|
||||
$(tls_static_pic_test_SOURCES) $(tls_static_test_SOURCES) \
|
||||
$(tls_test_SOURCES) $(two_file_mixed_2_shared_test_SOURCES) \
|
||||
@ -729,6 +748,9 @@ DIST_SOURCES = $(libgoldtest_a_SOURCES) basic_pic_test.c \
|
||||
$(object_unittest_SOURCES) $(am__script_test_1_SOURCES_DIST) \
|
||||
$(am__script_test_2_SOURCES_DIST) script_test_3.c \
|
||||
$(am__tls_pic_test_SOURCES_DIST) \
|
||||
$(am__tls_shared_gd_to_ie_test_SOURCES_DIST) \
|
||||
$(am__tls_shared_gnu2_gd_to_ie_test_SOURCES_DIST) \
|
||||
$(am__tls_shared_gnu2_test_SOURCES_DIST) \
|
||||
$(am__tls_shared_ie_test_SOURCES_DIST) \
|
||||
$(am__tls_shared_nonpic_test_SOURCES_DIST) \
|
||||
$(am__tls_shared_test_SOURCES_DIST) \
|
||||
@ -797,7 +819,6 @@ GCC_FALSE = @GCC_FALSE@
|
||||
GCC_TRUE = @GCC_TRUE@
|
||||
GENCAT = @GENCAT@
|
||||
GMSGFMT = @GMSGFMT@
|
||||
GREP = @GREP@
|
||||
HAVE_ZLIB_FALSE = @HAVE_ZLIB_FALSE@
|
||||
HAVE_ZLIB_TRUE = @HAVE_ZLIB_TRUE@
|
||||
INCINTL = @INCINTL@
|
||||
@ -842,7 +863,11 @@ STRIP = @STRIP@
|
||||
TARGETOBJS = @TARGETOBJS@
|
||||
THREADS_FALSE = @THREADS_FALSE@
|
||||
THREADS_TRUE = @THREADS_TRUE@
|
||||
TLS_DESCRIPTORS_FALSE = @TLS_DESCRIPTORS_FALSE@
|
||||
TLS_DESCRIPTORS_TRUE = @TLS_DESCRIPTORS_TRUE@
|
||||
TLS_FALSE = @TLS_FALSE@
|
||||
TLS_GNU2_DIALECT_FALSE = @TLS_GNU2_DIALECT_FALSE@
|
||||
TLS_GNU2_DIALECT_TRUE = @TLS_GNU2_DIALECT_TRUE@
|
||||
TLS_TRUE = @TLS_TRUE@
|
||||
USE_NLS = @USE_NLS@
|
||||
VERSION = @VERSION@
|
||||
@ -850,9 +875,10 @@ WARN_CFLAGS = @WARN_CFLAGS@
|
||||
WARN_CXXFLAGS = @WARN_CXXFLAGS@
|
||||
XGETTEXT = @XGETTEXT@
|
||||
YACC = @YACC@
|
||||
YFLAGS = @YFLAGS@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_RANLIB = @ac_ct_RANLIB@
|
||||
ac_ct_STRIP = @ac_ct_STRIP@
|
||||
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
|
||||
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
|
||||
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
|
||||
@ -869,30 +895,23 @@ build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
sysconfdir = @sysconfdir@
|
||||
@ -923,13 +942,13 @@ TEST_STRIP = $(top_builddir)/../binutils/strip-new
|
||||
# .o's), but not all of them (such as .so's and .err files). We
|
||||
# improve on that here. automake-1.9 info docs say "mostlyclean" is
|
||||
# the right choice for files 'make' builds that people rebuild.
|
||||
MOSTLYCLEANFILES = *.so $(am__append_10)
|
||||
MOSTLYCLEANFILES = *.so $(am__append_12)
|
||||
|
||||
# We will add to these later, for each individual test. Note
|
||||
# that we add each test under check_SCRIPTS or check_PROGRAMS;
|
||||
# the TESTS variable is automatically populated from these.
|
||||
check_SCRIPTS = $(am__append_8)
|
||||
check_DATA = $(am__append_9)
|
||||
check_SCRIPTS = $(am__append_10)
|
||||
check_DATA = $(am__append_11)
|
||||
TESTS = $(check_SCRIPTS) $(check_PROGRAMS)
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
@ -1143,6 +1162,18 @@ binary_unittest_SOURCES = binary_unittest.cc
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@tls_shared_ie_test_DEPENDENCIES = gcctestdir/ld tls_test_ie_shared.so
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@tls_shared_ie_test_LDFLAGS = -Bgcctestdir/ -Wl,-R,.
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@tls_shared_ie_test_LDADD = tls_test_ie_shared.so -lpthread
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@tls_shared_gd_to_ie_test_SOURCES = tls_test_main.cc
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@tls_shared_gd_to_ie_test_DEPENDENCIES = gcctestdir/ld tls_test_pic.o tls_test_shared2.so
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@tls_shared_gd_to_ie_test_LDFLAGS = -Bgcctestdir/ -Wl,-R,.
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@tls_shared_gd_to_ie_test_LDADD = tls_test_pic.o tls_test_shared2.so -lpthread
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@tls_shared_gnu2_gd_to_ie_test_SOURCES = tls_test_main.cc
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@tls_shared_gnu2_gd_to_ie_test_DEPENDENCIES = gcctestdir/ld tls_test_gnu2.o tls_test_gnu2_shared2.so
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@tls_shared_gnu2_gd_to_ie_test_LDFLAGS = -Bgcctestdir/ -Wl,-R,.
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@tls_shared_gnu2_gd_to_ie_test_LDADD = tls_test_gnu2.o tls_test_gnu2_shared2.so -lpthread
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_DESCRIPTORS_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@tls_shared_gnu2_test_SOURCES = tls_test_main.cc
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_DESCRIPTORS_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@tls_shared_gnu2_test_DEPENDENCIES = gcctestdir/ld tls_test_gnu2_shared.so
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_DESCRIPTORS_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@tls_shared_gnu2_test_LDFLAGS = -Bgcctestdir/ -Wl,-R,.
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_DESCRIPTORS_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@tls_shared_gnu2_test_LDADD = tls_test_gnu2_shared.so -lpthread
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@STATIC_TLS_TRUE@@TLS_TRUE@tls_static_test_SOURCES = $(tls_test_SOURCES)
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@STATIC_TLS_TRUE@@TLS_TRUE@tls_static_test_DEPENDENCIES = $(tls_test_DEPENDENCIES)
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@STATIC_TLS_TRUE@@TLS_TRUE@tls_static_test_LDFLAGS = $(tls_test_LDFLAGS) -static
|
||||
@ -1333,6 +1364,15 @@ script_test_2$(EXEEXT): $(script_test_2_OBJECTS) $(script_test_2_DEPENDENCIES)
|
||||
tls_pic_test$(EXEEXT): $(tls_pic_test_OBJECTS) $(tls_pic_test_DEPENDENCIES)
|
||||
@rm -f tls_pic_test$(EXEEXT)
|
||||
$(CXXLINK) $(tls_pic_test_LDFLAGS) $(tls_pic_test_OBJECTS) $(tls_pic_test_LDADD) $(LIBS)
|
||||
tls_shared_gd_to_ie_test$(EXEEXT): $(tls_shared_gd_to_ie_test_OBJECTS) $(tls_shared_gd_to_ie_test_DEPENDENCIES)
|
||||
@rm -f tls_shared_gd_to_ie_test$(EXEEXT)
|
||||
$(CXXLINK) $(tls_shared_gd_to_ie_test_LDFLAGS) $(tls_shared_gd_to_ie_test_OBJECTS) $(tls_shared_gd_to_ie_test_LDADD) $(LIBS)
|
||||
tls_shared_gnu2_gd_to_ie_test$(EXEEXT): $(tls_shared_gnu2_gd_to_ie_test_OBJECTS) $(tls_shared_gnu2_gd_to_ie_test_DEPENDENCIES)
|
||||
@rm -f tls_shared_gnu2_gd_to_ie_test$(EXEEXT)
|
||||
$(CXXLINK) $(tls_shared_gnu2_gd_to_ie_test_LDFLAGS) $(tls_shared_gnu2_gd_to_ie_test_OBJECTS) $(tls_shared_gnu2_gd_to_ie_test_LDADD) $(LIBS)
|
||||
tls_shared_gnu2_test$(EXEEXT): $(tls_shared_gnu2_test_OBJECTS) $(tls_shared_gnu2_test_DEPENDENCIES)
|
||||
@rm -f tls_shared_gnu2_test$(EXEEXT)
|
||||
$(CXXLINK) $(tls_shared_gnu2_test_LDFLAGS) $(tls_shared_gnu2_test_OBJECTS) $(tls_shared_gnu2_test_LDADD) $(LIBS)
|
||||
tls_shared_ie_test$(EXEEXT): $(tls_shared_ie_test_OBJECTS) $(tls_shared_ie_test_DEPENDENCIES)
|
||||
@rm -f tls_shared_ie_test$(EXEEXT)
|
||||
$(CXXLINK) $(tls_shared_ie_test_LDFLAGS) $(tls_shared_ie_test_OBJECTS) $(tls_shared_ie_test_LDADD) $(LIBS)
|
||||
@ -1854,6 +1894,8 @@ uninstall-am: uninstall-info-am
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@ $(CXXCOMPILE) -c -fpic -o $@ $<
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@tls_test_shared.so: tls_test_pic.o tls_test_file2_pic.o gcctestdir/ld
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@ $(CXXLINK) -Bgcctestdir/ -shared tls_test_pic.o tls_test_file2_pic.o
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@tls_test_shared2.so: tls_test_file2_pic.o gcctestdir/ld
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@ $(CXXLINK) -Bgcctestdir/ -shared tls_test_file2_pic.o
|
||||
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@tls_test_pic_ie.o: tls_test.cc
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@ $(CXXCOMPILE) -c -fpic -ftls-model=initial-exec -o $@ $<
|
||||
@ -1861,6 +1903,16 @@ uninstall-am: uninstall-info-am
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@ $(CXXCOMPILE) -c -fpic -ftls-model=initial-exec -o $@ $<
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@tls_test_ie_shared.so: tls_test_pic_ie.o tls_test_file2_pic_ie.o gcctestdir/ld
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@ $(CXXLINK) -Bgcctestdir/ -shared tls_test_pic_ie.o tls_test_file2_pic_ie.o
|
||||
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@tls_test_gnu2.o: tls_test.cc
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@ $(CXXCOMPILE) -c -fpic -mtls-dialect=gnu2 -o $@ $<
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@tls_test_file2_gnu2.o: tls_test_file2.cc
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@ $(CXXCOMPILE) -c -fpic -mtls-dialect=gnu2 -o $@ $<
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@tls_test_gnu2_shared2.so: tls_test_file2_gnu2.o gcctestdir/ld
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@ $(CXXLINK) -Bgcctestdir/ -shared tls_test_file2_gnu2.o
|
||||
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_DESCRIPTORS_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@tls_test_gnu2_shared.so: tls_test_gnu2.o tls_test_file2_gnu2.o gcctestdir/ld
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_DESCRIPTORS_TRUE@@TLS_GNU2_DIALECT_TRUE@@TLS_TRUE@ $(CXXLINK) -Bgcctestdir/ -shared tls_test_gnu2.o tls_test_file2_gnu2.o
|
||||
@FN_PTRS_IN_SO_WITHOUT_PIC_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@tls_test_shared_nonpic.so: tls_test.o tls_test_file2.o gcctestdir/ld
|
||||
@FN_PTRS_IN_SO_WITHOUT_PIC_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@@TLS_TRUE@ $(CXXLINK) -Bgcctestdir/ -shared tls_test.o tls_test_file2.o
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@debug_msg.o: debug_msg.cc
|
||||
|
386
gold/x86_64.cc
386
gold/x86_64.cc
@ -227,13 +227,14 @@ class Target_x86_64 : public Sized_target<64, false>
|
||||
unsigned char*, elfcpp::Elf_types<64>::Elf_Addr,
|
||||
section_size_type);
|
||||
|
||||
// Do a TLS General-Dynamic to Local-Exec transition.
|
||||
// Do a TLS General-Dynamic to Initial-Exec transition.
|
||||
inline void
|
||||
tls_gd_to_ie(const Relocate_info<64, false>*, size_t relnum,
|
||||
Output_segment* tls_segment,
|
||||
const elfcpp::Rela<64, false>&, unsigned int r_type,
|
||||
elfcpp::Elf_types<64>::Elf_Addr value,
|
||||
unsigned char* view,
|
||||
elfcpp::Elf_types<64>::Elf_Addr,
|
||||
section_size_type view_size);
|
||||
|
||||
// Do a TLS General-Dynamic to Local-Exec transition.
|
||||
@ -245,6 +246,25 @@ class Target_x86_64 : public Sized_target<64, false>
|
||||
unsigned char* view,
|
||||
section_size_type view_size);
|
||||
|
||||
// Do a TLSDESC-style General-Dynamic to Initial-Exec transition.
|
||||
inline void
|
||||
tls_desc_gd_to_ie(const Relocate_info<64, false>*, size_t relnum,
|
||||
Output_segment* tls_segment,
|
||||
const elfcpp::Rela<64, false>&, unsigned int r_type,
|
||||
elfcpp::Elf_types<64>::Elf_Addr value,
|
||||
unsigned char* view,
|
||||
elfcpp::Elf_types<64>::Elf_Addr,
|
||||
section_size_type view_size);
|
||||
|
||||
// Do a TLSDESC-style General-Dynamic to Local-Exec transition.
|
||||
inline void
|
||||
tls_desc_gd_to_le(const Relocate_info<64, false>*, size_t relnum,
|
||||
Output_segment* tls_segment,
|
||||
const elfcpp::Rela<64, false>&, unsigned int r_type,
|
||||
elfcpp::Elf_types<64>::Elf_Addr value,
|
||||
unsigned char* view,
|
||||
section_size_type view_size);
|
||||
|
||||
// Do a TLS Local-Dynamic to Local-Exec transition.
|
||||
inline void
|
||||
tls_ld_to_le(const Relocate_info<64, false>*, size_t relnum,
|
||||
@ -294,10 +314,18 @@ class Target_x86_64 : public Sized_target<64, false>
|
||||
return this->got_plt_;
|
||||
}
|
||||
|
||||
// Create the PLT section.
|
||||
void
|
||||
make_plt_section(Symbol_table* symtab, Layout* layout);
|
||||
|
||||
// Create a PLT entry for a global symbol.
|
||||
void
|
||||
make_plt_entry(Symbol_table*, Layout*, Symbol*);
|
||||
|
||||
// Create the reserved PLT and GOT entries for the TLS descriptor resolver.
|
||||
void
|
||||
reserve_tlsdesc_entries(Symbol_table* symtab, Layout* layout);
|
||||
|
||||
// Create a GOT entry for the TLS module index.
|
||||
unsigned int
|
||||
got_mod_index_entry(Symbol_table* symtab, Layout* layout,
|
||||
@ -356,7 +384,7 @@ class Target_x86_64 : public Sized_target<64, false>
|
||||
Copy_relocs<64, false>* copy_relocs_;
|
||||
// Space for variables copied with a COPY reloc.
|
||||
Output_data_space* dynbss_;
|
||||
// Offset of the GOT entry for the TLS module index;
|
||||
// Offset of the GOT entry for the TLS module index.
|
||||
unsigned int got_mod_index_offset_;
|
||||
};
|
||||
|
||||
@ -437,12 +465,33 @@ class Output_data_plt_x86_64 : public Output_section_data
|
||||
public:
|
||||
typedef Output_data_reloc<elfcpp::SHT_RELA, true, 64, false> Reloc_section;
|
||||
|
||||
Output_data_plt_x86_64(Layout*, Output_data_space*);
|
||||
Output_data_plt_x86_64(Layout*, Output_data_got<64, false>*,
|
||||
Output_data_space*);
|
||||
|
||||
// Add an entry to the PLT.
|
||||
void
|
||||
add_entry(Symbol* gsym);
|
||||
|
||||
// Add the reserved TLSDESC_PLT entry to the PLT.
|
||||
void
|
||||
reserve_tlsdesc_entry(unsigned int got_offset)
|
||||
{ this->tlsdesc_got_offset_ = got_offset; }
|
||||
|
||||
// Return true if a TLSDESC_PLT entry has been reserved.
|
||||
bool
|
||||
has_tlsdesc_entry() const
|
||||
{ return this->tlsdesc_got_offset_ != -1U; }
|
||||
|
||||
// Return the GOT offset for the reserved TLSDESC_PLT entry.
|
||||
unsigned int
|
||||
get_tlsdesc_got_offset() const
|
||||
{ return this->tlsdesc_got_offset_; }
|
||||
|
||||
// Return the offset of the reserved TLSDESC_PLT entry.
|
||||
unsigned int
|
||||
get_tlsdesc_plt_offset() const
|
||||
{ return (this->count_ + 1) * plt_entry_size; }
|
||||
|
||||
// Return the .rel.plt section data.
|
||||
const Reloc_section*
|
||||
rel_plt() const
|
||||
@ -464,10 +513,12 @@ class Output_data_plt_x86_64 : public Output_section_data
|
||||
// Other entries in the PLT for an executable.
|
||||
static unsigned char plt_entry[plt_entry_size];
|
||||
|
||||
// The reserved TLSDESC entry in the PLT for an executable.
|
||||
static unsigned char tlsdesc_plt_entry[plt_entry_size];
|
||||
|
||||
// Set the final size.
|
||||
void
|
||||
set_final_data_size()
|
||||
{ this->set_data_size((this->count_ + 1) * plt_entry_size); }
|
||||
set_final_data_size();
|
||||
|
||||
// Write out the PLT data.
|
||||
void
|
||||
@ -475,10 +526,14 @@ class Output_data_plt_x86_64 : public Output_section_data
|
||||
|
||||
// The reloc section.
|
||||
Reloc_section* rel_;
|
||||
// The .got section.
|
||||
Output_data_got<64, false>* got_;
|
||||
// The .got.plt section.
|
||||
Output_data_space* got_plt_;
|
||||
// The number of PLT entries.
|
||||
unsigned int count_;
|
||||
// Offset of the reserved TLSDESC_GOT entry when needed.
|
||||
unsigned int tlsdesc_got_offset_;
|
||||
};
|
||||
|
||||
// Create the PLT section. The ordinary .got section is an argument,
|
||||
@ -486,8 +541,10 @@ class Output_data_plt_x86_64 : public Output_section_data
|
||||
// section just for PLT entries.
|
||||
|
||||
Output_data_plt_x86_64::Output_data_plt_x86_64(Layout* layout,
|
||||
Output_data_got<64, false>* got,
|
||||
Output_data_space* got_plt)
|
||||
: Output_section_data(8), got_plt_(got_plt), count_(0)
|
||||
: Output_section_data(8), got_(got), got_plt_(got_plt), count_(0),
|
||||
tlsdesc_got_offset_(-1U)
|
||||
{
|
||||
this->rel_ = new Reloc_section();
|
||||
layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
|
||||
@ -532,6 +589,16 @@ Output_data_plt_x86_64::add_entry(Symbol* gsym)
|
||||
// appear in the relocations.
|
||||
}
|
||||
|
||||
// Set the final size.
|
||||
void
|
||||
Output_data_plt_x86_64::set_final_data_size()
|
||||
{
|
||||
unsigned int count = this->count_;
|
||||
if (this->has_tlsdesc_entry())
|
||||
++count;
|
||||
this->set_data_size((count + 1) * plt_entry_size);
|
||||
}
|
||||
|
||||
// The first entry in the PLT for an executable.
|
||||
|
||||
unsigned char Output_data_plt_x86_64::first_plt_entry[plt_entry_size] =
|
||||
@ -557,6 +624,20 @@ unsigned char Output_data_plt_x86_64::plt_entry[plt_entry_size] =
|
||||
0, 0, 0, 0 // replaced with offset to start of .plt
|
||||
};
|
||||
|
||||
// The reserved TLSDESC entry in the PLT for an executable.
|
||||
|
||||
unsigned char Output_data_plt_x86_64::tlsdesc_plt_entry[plt_entry_size] =
|
||||
{
|
||||
// From Alexandre Oliva, "Thread-Local Storage Descriptors for IA32
|
||||
// and AMD64/EM64T", Version 0.9.4 (2005-10-10).
|
||||
0xff, 0x35, // pushq x(%rip)
|
||||
0, 0, 0, 0, // replaced with address of linkmap GOT entry (at PLTGOT + 8)
|
||||
0xff, 0x25, // jmpq *y(%rip)
|
||||
0, 0, 0, 0, // replaced with offset of reserved TLSDESC_GOT entry
|
||||
0x0f, 0x1f, // nop
|
||||
0x40, 0
|
||||
};
|
||||
|
||||
// Write out the PLT. This uses the hand-coded instructions above,
|
||||
// and adjusts them as needed. This is specified by the AMD64 ABI.
|
||||
|
||||
@ -576,7 +657,13 @@ Output_data_plt_x86_64::do_write(Output_file* of)
|
||||
|
||||
unsigned char* pov = oview;
|
||||
|
||||
// The base address of the .plt section.
|
||||
elfcpp::Elf_types<32>::Elf_Addr plt_address = this->address();
|
||||
// The base address of the .got section.
|
||||
elfcpp::Elf_types<32>::Elf_Addr got_base = this->got_->address();
|
||||
// The base address of the PLT portion of the .got section,
|
||||
// which is where the GOT pointer will point, and where the
|
||||
// three reserved GOT entries are located.
|
||||
elfcpp::Elf_types<32>::Elf_Addr got_address = this->got_plt_->address();
|
||||
|
||||
memcpy(pov, first_plt_entry, plt_entry_size);
|
||||
@ -618,6 +705,23 @@ Output_data_plt_x86_64::do_write(Output_file* of)
|
||||
elfcpp::Swap<64, false>::writeval(got_pov, plt_address + plt_offset + 6);
|
||||
}
|
||||
|
||||
if (this->has_tlsdesc_entry())
|
||||
{
|
||||
// Set and adjust the reserved TLSDESC PLT entry.
|
||||
unsigned int tlsdesc_got_offset = this->get_tlsdesc_got_offset();
|
||||
memcpy(pov, tlsdesc_plt_entry, plt_entry_size);
|
||||
elfcpp::Swap_unaligned<32, false>::writeval(pov + 2,
|
||||
(got_address + 8
|
||||
- (plt_address + plt_offset
|
||||
+ 6)));
|
||||
elfcpp::Swap_unaligned<32, false>::writeval(pov + 8,
|
||||
(got_base
|
||||
+ tlsdesc_got_offset
|
||||
- (plt_address + plt_offset
|
||||
+ 12)));
|
||||
pov += plt_entry_size;
|
||||
}
|
||||
|
||||
gold_assert(static_cast<section_size_type>(pov - oview) == oview_size);
|
||||
gold_assert(static_cast<section_size_type>(got_pov - got_view) == got_size);
|
||||
|
||||
@ -625,6 +729,25 @@ Output_data_plt_x86_64::do_write(Output_file* of)
|
||||
of->write_output_view(got_file_offset, got_size, got_view);
|
||||
}
|
||||
|
||||
// Create the PLT section.
|
||||
|
||||
void
|
||||
Target_x86_64::make_plt_section(Symbol_table* symtab, Layout* layout)
|
||||
{
|
||||
if (this->plt_ == NULL)
|
||||
{
|
||||
// Create the GOT sections first.
|
||||
this->got_section(symtab, layout);
|
||||
|
||||
this->plt_ = new Output_data_plt_x86_64(layout, this->got_,
|
||||
this->got_plt_);
|
||||
layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
|
||||
(elfcpp::SHF_ALLOC
|
||||
| elfcpp::SHF_EXECINSTR),
|
||||
this->plt_);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a PLT entry for a global symbol.
|
||||
|
||||
void
|
||||
@ -635,20 +758,31 @@ Target_x86_64::make_plt_entry(Symbol_table* symtab, Layout* layout,
|
||||
return;
|
||||
|
||||
if (this->plt_ == NULL)
|
||||
{
|
||||
// Create the GOT sections first.
|
||||
this->got_section(symtab, layout);
|
||||
|
||||
this->plt_ = new Output_data_plt_x86_64(layout, this->got_plt_);
|
||||
layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
|
||||
(elfcpp::SHF_ALLOC
|
||||
| elfcpp::SHF_EXECINSTR),
|
||||
this->plt_);
|
||||
}
|
||||
this->make_plt_section(symtab, layout);
|
||||
|
||||
this->plt_->add_entry(gsym);
|
||||
}
|
||||
|
||||
// Create the reserved PLT and GOT entries for the TLS descriptor resolver.
|
||||
|
||||
void
|
||||
Target_x86_64::reserve_tlsdesc_entries(Symbol_table* symtab,
|
||||
Layout* layout)
|
||||
{
|
||||
if (this->plt_ == NULL)
|
||||
this->make_plt_section(symtab, layout);
|
||||
|
||||
if (!this->plt_->has_tlsdesc_entry())
|
||||
{
|
||||
// Allocate the TLSDESC_GOT entry.
|
||||
Output_data_got<64, false>* got = this->got_section(symtab, layout);
|
||||
unsigned int got_offset = got->add_constant(0);
|
||||
|
||||
// Allocate the TLSDESC_PLT entry.
|
||||
this->plt_->reserve_tlsdesc_entry(got_offset);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a GOT entry for the TLS module index.
|
||||
|
||||
unsigned int
|
||||
@ -663,7 +797,6 @@ Target_x86_64::got_mod_index_entry(Symbol_table* symtab, Layout* layout,
|
||||
unsigned int got_offset = got->add_constant(0);
|
||||
rela_dyn->add_local(object, 0, elfcpp::R_X86_64_DTPMOD64, got,
|
||||
got_offset, 0);
|
||||
got->add_constant(0);
|
||||
this->got_mod_index_offset_ = got_offset;
|
||||
}
|
||||
return this->got_mod_index_offset_;
|
||||
@ -1032,13 +1165,28 @@ Target_x86_64::Scan::local(const General_options&,
|
||||
break;
|
||||
|
||||
case elfcpp::R_X86_64_GOTPC32_TLSDESC:
|
||||
case elfcpp::R_X86_64_TLSDESC_CALL:
|
||||
// FIXME: If not relaxing to LE, we need to generate
|
||||
// a GOT entry with a R_x86_64_TLSDESC reloc.
|
||||
if (optimized_type != tls::TLSOPT_TO_LE)
|
||||
if (optimized_type == tls::TLSOPT_NONE)
|
||||
{
|
||||
// Create reserved PLT and GOT entries for the resolver.
|
||||
target->reserve_tlsdesc_entries(symtab, layout);
|
||||
|
||||
// Generate a double GOT entry with an R_X86_64_TLSDESC reloc.
|
||||
Output_data_got<64, false>* got
|
||||
= target->got_section(symtab, layout);
|
||||
unsigned int r_sym = elfcpp::elf_r_sym<64>(reloc.get_r_info());
|
||||
got->add_local_pair_with_rela(object, r_sym,
|
||||
lsym.get_st_shndx(),
|
||||
GOT_TYPE_TLS_DESC,
|
||||
target->rela_dyn_section(layout),
|
||||
elfcpp::R_X86_64_TLSDESC, 0);
|
||||
}
|
||||
else if (optimized_type != tls::TLSOPT_TO_LE)
|
||||
unsupported_reloc_local(object, r_type);
|
||||
break;
|
||||
|
||||
case elfcpp::R_X86_64_TLSDESC_CALL:
|
||||
break;
|
||||
|
||||
case elfcpp::R_X86_64_TLSLD: // Local-dynamic
|
||||
if (optimized_type == tls::TLSOPT_NONE)
|
||||
{
|
||||
@ -1317,13 +1465,34 @@ Target_x86_64::Scan::global(const General_options& options,
|
||||
break;
|
||||
|
||||
case elfcpp::R_X86_64_GOTPC32_TLSDESC:
|
||||
case elfcpp::R_X86_64_TLSDESC_CALL:
|
||||
// FIXME: If not relaxing to LE, we need to generate
|
||||
// DTPMOD64 and DTPOFF64, or TLSDESC, relocs.
|
||||
if (optimized_type != tls::TLSOPT_TO_LE)
|
||||
if (optimized_type == tls::TLSOPT_NONE)
|
||||
{
|
||||
// Create reserved PLT and GOT entries for the resolver.
|
||||
target->reserve_tlsdesc_entries(symtab, layout);
|
||||
|
||||
// Create a double GOT entry with an R_X86_64_TLSDESC reloc.
|
||||
Output_data_got<64, false>* got
|
||||
= target->got_section(symtab, layout);
|
||||
got->add_global_pair_with_rela(gsym, GOT_TYPE_TLS_DESC,
|
||||
target->rela_dyn_section(layout),
|
||||
elfcpp::R_X86_64_TLSDESC, 0);
|
||||
}
|
||||
else if (optimized_type == tls::TLSOPT_TO_IE)
|
||||
{
|
||||
// Create a GOT entry for the tp-relative offset.
|
||||
Output_data_got<64, false>* got
|
||||
= target->got_section(symtab, layout);
|
||||
got->add_global_with_rela(gsym, GOT_TYPE_TLS_OFFSET,
|
||||
target->rela_dyn_section(layout),
|
||||
elfcpp::R_X86_64_TPOFF64);
|
||||
}
|
||||
else if (optimized_type != tls::TLSOPT_TO_LE)
|
||||
unsupported_reloc_global(object, r_type, gsym);
|
||||
break;
|
||||
|
||||
case elfcpp::R_X86_64_TLSDESC_CALL:
|
||||
break;
|
||||
|
||||
case elfcpp::R_X86_64_TLSLD: // Local-dynamic
|
||||
if (optimized_type == tls::TLSOPT_NONE)
|
||||
{
|
||||
@ -1432,6 +1601,16 @@ Target_x86_64::do_finalize_sections(Layout* layout)
|
||||
odyn->add_section_size(elfcpp::DT_PLTRELSZ, od);
|
||||
odyn->add_section_address(elfcpp::DT_JMPREL, od);
|
||||
odyn->add_constant(elfcpp::DT_PLTREL, elfcpp::DT_RELA);
|
||||
if (this->plt_->has_tlsdesc_entry())
|
||||
{
|
||||
unsigned int plt_offset = this->plt_->get_tlsdesc_plt_offset();
|
||||
unsigned int got_offset = this->plt_->get_tlsdesc_got_offset();
|
||||
this->got_->finalize_data_size();
|
||||
odyn->add_section_plus_offset(elfcpp::DT_TLSDESC_PLT,
|
||||
this->plt_, plt_offset);
|
||||
odyn->add_section_plus_offset(elfcpp::DT_TLSDESC_GOT,
|
||||
this->got_, got_offset);
|
||||
}
|
||||
}
|
||||
|
||||
if (this->rela_dyn_ != NULL)
|
||||
@ -1746,8 +1925,6 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
|
||||
switch (r_type)
|
||||
{
|
||||
case elfcpp::R_X86_64_TLSGD: // Global-dynamic
|
||||
case elfcpp::R_X86_64_GOTPC32_TLSDESC: // Global-dynamic (from ~oliva url)
|
||||
case elfcpp::R_X86_64_TLSDESC_CALL:
|
||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
@ -1758,26 +1935,28 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int got_type = (optimized_type == tls::TLSOPT_TO_IE
|
||||
? GOT_TYPE_TLS_OFFSET
|
||||
: GOT_TYPE_TLS_PAIR);
|
||||
unsigned int got_offset;
|
||||
if (gsym != NULL)
|
||||
{
|
||||
gold_assert(gsym->has_got_offset(GOT_TYPE_TLS_PAIR));
|
||||
got_offset = (gsym->got_offset(GOT_TYPE_TLS_PAIR)
|
||||
- target->got_size());
|
||||
gold_assert(gsym->has_got_offset(got_type));
|
||||
got_offset = gsym->got_offset(got_type) - target->got_size();
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int r_sym = elfcpp::elf_r_sym<64>(rela.get_r_info());
|
||||
gold_assert(object->local_has_got_offset(r_sym,
|
||||
GOT_TYPE_TLS_PAIR));
|
||||
got_offset = (object->local_got_offset(r_sym, GOT_TYPE_TLS_PAIR)
|
||||
gold_assert(object->local_has_got_offset(r_sym, got_type));
|
||||
got_offset = (object->local_got_offset(r_sym, got_type)
|
||||
- target->got_size());
|
||||
}
|
||||
if (optimized_type == tls::TLSOPT_TO_IE)
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
value = target->got_plt_section()->address() + got_offset;
|
||||
this->tls_gd_to_ie(relinfo, relnum, tls_segment, rela, r_type,
|
||||
got_offset, view, view_size);
|
||||
value, view, address, view_size);
|
||||
break;
|
||||
}
|
||||
else if (optimized_type == tls::TLSOPT_NONE)
|
||||
@ -1794,6 +1973,60 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
|
||||
_("unsupported reloc %u"), r_type);
|
||||
break;
|
||||
|
||||
case elfcpp::R_X86_64_GOTPC32_TLSDESC: // Global-dynamic (from ~oliva url)
|
||||
case elfcpp::R_X86_64_TLSDESC_CALL:
|
||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
this->tls_desc_gd_to_le(relinfo, relnum, tls_segment,
|
||||
rela, r_type, value, view,
|
||||
view_size);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int got_type = (optimized_type == tls::TLSOPT_TO_IE
|
||||
? GOT_TYPE_TLS_OFFSET
|
||||
: GOT_TYPE_TLS_DESC);
|
||||
unsigned int got_offset;
|
||||
if (gsym != NULL)
|
||||
{
|
||||
gold_assert(gsym->has_got_offset(got_type));
|
||||
got_offset = gsym->got_offset(got_type) - target->got_size();
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int r_sym = elfcpp::elf_r_sym<64>(rela.get_r_info());
|
||||
gold_assert(object->local_has_got_offset(r_sym, got_type));
|
||||
got_offset = (object->local_got_offset(r_sym, got_type)
|
||||
- target->got_size());
|
||||
}
|
||||
if (optimized_type == tls::TLSOPT_TO_IE)
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
value = target->got_plt_section()->address() + got_offset;
|
||||
this->tls_desc_gd_to_ie(relinfo, relnum, tls_segment,
|
||||
rela, r_type, value, view, address,
|
||||
view_size);
|
||||
break;
|
||||
}
|
||||
else if (optimized_type == tls::TLSOPT_NONE)
|
||||
{
|
||||
if (r_type == elfcpp::R_X86_64_GOTPC32_TLSDESC)
|
||||
{
|
||||
// Relocate the field with the offset of the pair of GOT
|
||||
// entries.
|
||||
value = target->got_plt_section()->address() + got_offset;
|
||||
Relocate_functions<64, false>::pcrela32(view, value, addend,
|
||||
address);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
|
||||
_("unsupported reloc %u"), r_type);
|
||||
break;
|
||||
|
||||
case elfcpp::R_X86_64_TLSLD: // Local-dynamic
|
||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||
{
|
||||
@ -1882,11 +2115,12 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
|
||||
inline void
|
||||
Target_x86_64::Relocate::tls_gd_to_ie(const Relocate_info<64, false>* relinfo,
|
||||
size_t relnum,
|
||||
Output_segment* tls_segment,
|
||||
Output_segment*,
|
||||
const elfcpp::Rela<64, false>& rela,
|
||||
unsigned int,
|
||||
elfcpp::Elf_types<64>::Elf_Addr value,
|
||||
unsigned char* view,
|
||||
elfcpp::Elf_types<64>::Elf_Addr address,
|
||||
section_size_type view_size)
|
||||
{
|
||||
// .byte 0x66; leaq foo@tlsgd(%rip),%rdi;
|
||||
@ -1903,8 +2137,8 @@ Target_x86_64::Relocate::tls_gd_to_ie(const Relocate_info<64, false>* relinfo,
|
||||
|
||||
memcpy(view - 4, "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0\0", 16);
|
||||
|
||||
value -= tls_segment->memsz();
|
||||
Relocate_functions<64, false>::rela32(view + 8, value, 0);
|
||||
const elfcpp::Elf_Xword addend = rela.get_r_addend();
|
||||
Relocate_functions<64, false>::pcrela32(view + 8, value, addend - 8, address);
|
||||
|
||||
// The next reloc should be a PLT32 reloc against __tls_get_addr.
|
||||
// We can skip it.
|
||||
@ -1946,6 +2180,84 @@ Target_x86_64::Relocate::tls_gd_to_le(const Relocate_info<64, false>* relinfo,
|
||||
this->skip_call_tls_get_addr_ = true;
|
||||
}
|
||||
|
||||
// Do a TLSDESC-style General-Dynamic to Initial-Exec transition.
|
||||
|
||||
inline void
|
||||
Target_x86_64::Relocate::tls_desc_gd_to_ie(
|
||||
const Relocate_info<64, false>* relinfo,
|
||||
size_t relnum,
|
||||
Output_segment*,
|
||||
const elfcpp::Rela<64, false>& rela,
|
||||
unsigned int r_type,
|
||||
elfcpp::Elf_types<64>::Elf_Addr value,
|
||||
unsigned char* view,
|
||||
elfcpp::Elf_types<64>::Elf_Addr address,
|
||||
section_size_type view_size)
|
||||
{
|
||||
if (r_type == elfcpp::R_X86_64_GOTPC32_TLSDESC)
|
||||
{
|
||||
// leaq foo@tlsdesc(%rip), %rax
|
||||
// ==> movq foo@gottpoff(%rip), %rax
|
||||
tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, -3);
|
||||
tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, 4);
|
||||
tls::check_tls(relinfo, relnum, rela.get_r_offset(),
|
||||
view[-3] == 0x48 && view[-2] == 0x8d && view[-1] == 0x05);
|
||||
view[-2] = 0x8b;
|
||||
const elfcpp::Elf_Xword addend = rela.get_r_addend();
|
||||
Relocate_functions<64, false>::pcrela32(view, value, addend, address);
|
||||
}
|
||||
else
|
||||
{
|
||||
// call *foo@tlscall(%rax)
|
||||
// ==> nop; nop
|
||||
gold_assert(r_type == elfcpp::R_X86_64_TLSDESC_CALL);
|
||||
tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, 2);
|
||||
tls::check_tls(relinfo, relnum, rela.get_r_offset(),
|
||||
view[0] == 0xff && view[1] == 0x10);
|
||||
view[0] = 0x66;
|
||||
view[1] = 0x90;
|
||||
}
|
||||
}
|
||||
|
||||
// Do a TLSDESC-style General-Dynamic to Local-Exec transition.
|
||||
|
||||
inline void
|
||||
Target_x86_64::Relocate::tls_desc_gd_to_le(
|
||||
const Relocate_info<64, false>* relinfo,
|
||||
size_t relnum,
|
||||
Output_segment* tls_segment,
|
||||
const elfcpp::Rela<64, false>& rela,
|
||||
unsigned int r_type,
|
||||
elfcpp::Elf_types<64>::Elf_Addr value,
|
||||
unsigned char* view,
|
||||
section_size_type view_size)
|
||||
{
|
||||
if (r_type == elfcpp::R_X86_64_GOTPC32_TLSDESC)
|
||||
{
|
||||
// leaq foo@tlsdesc(%rip), %rax
|
||||
// ==> movq foo@tpoff, %rax
|
||||
tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, -3);
|
||||
tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, 4);
|
||||
tls::check_tls(relinfo, relnum, rela.get_r_offset(),
|
||||
view[-3] == 0x48 && view[-2] == 0x8d && view[-1] == 0x05);
|
||||
view[-2] = 0xc7;
|
||||
view[-1] = 0xc0;
|
||||
value -= tls_segment->memsz();
|
||||
Relocate_functions<64, false>::rela32(view, value, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// call *foo@tlscall(%rax)
|
||||
// ==> nop; nop
|
||||
gold_assert(r_type == elfcpp::R_X86_64_TLSDESC_CALL);
|
||||
tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, 2);
|
||||
tls::check_tls(relinfo, relnum, rela.get_r_offset(),
|
||||
view[0] == 0xff && view[1] == 0x10);
|
||||
view[0] = 0x66;
|
||||
view[1] = 0x90;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
Target_x86_64::Relocate::tls_ld_to_le(const Relocate_info<64, false>* relinfo,
|
||||
size_t relnum,
|
||||
|
Loading…
Reference in New Issue
Block a user