diff options
Diffstat (limited to 'ld')
120 files changed, 3220 insertions, 651 deletions
@@ -1,8 +1,25 @@ -*- text -*- +* On RISC-V, add new PLT formats, and GNU property merge rules for zicfiss and + zicfilp extensions. + +* The linker's --stats option can take an optional argument which if used is + interpreted as a filename into which resource usage information should be + stored. As an alternative mechanism the LD_STATS environment variable can + also be used to achieve the same results. Resource usage information for + various phases of the linking operation is now included in the report. + If a map file is being produced then the information is also included there. + The --no-stats option can be used to disable stat reporting, should it have + been enabled. + * Remove the linker -taso option for Alpha target, as Linux/Alpha kernel support for 32-bit pointers has been removed. +* On avr, the default linker scripts now assert that the .progmem sections + don't extend past 0xffff since they are accessed by means of LPM. + For data in program memory that may be located past 0xffff, a .progmemx + section should be used. + * On s390, generate ".eh_frame" unwind information for the linker generated .plt section. Enabled by default. Can be disabled using linker option --no-ld-generated-unwind-info. diff --git a/ld/config.in b/ld/config.in index 2d7b640..3781224 100644 --- a/ld/config.in +++ b/ld/config.in @@ -122,6 +122,9 @@ /* Define to 1 if you have the `getpagesize' function. */ #undef HAVE_GETPAGESIZE +/* Define to 1 if you have the `getrusage' function. */ +#undef HAVE_GETRUSAGE + /* Define if the GNU gettext() function is already present or preinstalled. */ #undef HAVE_GETTEXT @@ -231,9 +234,6 @@ /* Define to the version of this package. */ #undef PACKAGE_VERSION -/* The size of `void *', as computed by sizeof. */ -#undef SIZEOF_VOID_P - /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS diff --git a/ld/configure b/ld/configure index b7af25d..64b42f1 100755 --- a/ld/configure +++ b/ld/configure @@ -696,8 +696,6 @@ install_as_default TARGET_SYSTEM_ROOT_DEFINE TARGET_SYSTEM_ROOT use_sysroot -ENABLE_BFD_64_BIT_FALSE -ENABLE_BFD_64_BIT_TRUE LARGEFILE_CPPFLAGS CXXCPP OTOOL64 @@ -842,7 +840,6 @@ enable_largefile enable_checking with_lib_path enable_targets -enable_64_bit_bfd with_sysroot enable_gold enable_got @@ -1536,7 +1533,6 @@ Optional Features: --disable-largefile omit support for large files --enable-checking enable run-time checks --enable-targets alternative target configurations - --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes) --enable-gold[=ARG] build gold [ARG={default,yes,no}] --enable-got=<type> GOT handling scheme (target, single, negative, multigot) @@ -2177,189 +2173,6 @@ fi } # ac_fn_cxx_try_link -# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES -# -------------------------------------------- -# Tries to find the compile-time value of EXPR in a program that includes -# INCLUDES, setting VAR accordingly. Returns whether the value could be -# computed -ac_fn_c_compute_int () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) >= 0)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_lo=0 ac_mid=0 - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) <= $ac_mid)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_hi=$ac_mid; break -else - as_fn_arith $ac_mid + 1 && ac_lo=$as_val - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) < 0)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_hi=-1 ac_mid=-1 - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) >= $ac_mid)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_lo=$ac_mid; break -else - as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - ac_lo= ac_hi= -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) <= $ac_mid)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_hi=$ac_mid -else - as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in #(( -?*) eval "$3=\$ac_lo"; ac_retval=0 ;; -'') ac_retval=1 ;; -esac - else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -static long int longval () { return $2; } -static unsigned long int ulongval () { return $2; } -#include <stdio.h> -#include <stdlib.h> -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - return 1; - if (($2) < 0) - { - long int i = longval (); - if (i != ($2)) - return 1; - fprintf (f, "%ld", i); - } - else - { - unsigned long int i = ulongval (); - if (i != ($2)) - return 1; - fprintf (f, "%lu", i); - } - /* Do not output a trailing newline, as this causes \r\n confusion - on some platforms. */ - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - echo >>conftest.val; read $3 <conftest.val; ac_retval=0 -else - ac_retval=1 -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -rm -f conftest.val - - fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_compute_int - # ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES # --------------------------------------------- # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR @@ -11688,7 +11501,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11691 "configure" +#line 11504 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11794,7 +11607,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11797 "configure" +#line 11610 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -15462,70 +15275,40 @@ if test "${enable_targets+set}" = set; then : esac fi -# Check whether --enable-64-bit-bfd was given. -if test "${enable_64_bit_bfd+set}" = set; then : - enableval=$enable_64_bit_bfd; case $enableval in #( - yes|no) : - ;; #( - *) : - as_fn_error $? "bad value ${enableval} for 64-bit-bfd option" "$LINENO" 5 ;; #( - *) : - ;; -esac -else - enable_64_bit_bfd=no -fi - - -if test "x$enable_64_bit_bfd" = "xno"; then : - # The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5 -$as_echo_n "checking size of void *... " >&6; } -if ${ac_cv_sizeof_void_p+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_void_p" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (void *) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_void_p=0 - fi -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5 -$as_echo "$ac_cv_sizeof_void_p" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_VOID_P $ac_cv_sizeof_void_p +# See whether 64-bit bfd lib has been enabled. +OLD_CPPFLAGS=$CPPFLAGS +# Put the old CPPFLAGS last, in case the user's CPPFLAGS point somewhere +# with bfd, with -I/foo/include. We always want our bfd. +CPPFLAGS="-I${srcdir}/../include -I../bfd -I${srcdir}/../bfd $CPPFLAGS" +# Note we cannot cache the result of this check because BFD64 may change +# when a secondary target has been added or removed and we have no access +# to this information here. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether BFD is 64-bit" >&5 +$as_echo_n "checking whether BFD is 64-bit... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include "bfd.h" +int +main () +{ +#ifdef BFD64 +HAVE_BFD64 +#endif + ; + return 0; +} _ACEOF - - - if test "x$ac_cv_sizeof_void_p" = "x8"; then : - enable_64_bit_bfd=yes -fi - -fi - - if test "x$enable_64_bit_bfd" = "xyes"; then - ENABLE_BFD_64_BIT_TRUE= - ENABLE_BFD_64_BIT_FALSE='#' +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "HAVE_BFD64" >/dev/null 2>&1; then : + have_64_bit_bfd=yes else - ENABLE_BFD_64_BIT_TRUE='#' - ENABLE_BFD_64_BIT_FALSE= + have_64_bit_bfd=no fi +rm -f conftest* - +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_64_bit_bfd" >&5 +$as_echo "$have_64_bit_bfd" >&6; } +CPPFLAGS=$OLD_CPPFLAGS # Check whether --with-sysroot was given. @@ -18753,7 +18536,7 @@ fi done -for ac_func in close glob lseek mkstemp open realpath waitpid +for ac_func in close getrusage glob lseek mkstemp open realpath waitpid do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -19306,11 +19089,11 @@ do EMUL=$targ_emul fi - if test x${enable_64_bit_bfd} = xno; then + if test x${have_64_bit_bfd} = xno; then . ${srcdir}/../bfd/config.bfd fi - if test x${enable_64_bit_bfd} = xyes; then + if test x${have_64_bit_bfd} = xyes; then targ_extra_emuls="$targ_extra_emuls $targ64_extra_emuls" targ_extra_libpath="$targ_extra_libpath $targ64_extra_libpath" fi @@ -19534,7 +19317,7 @@ _ACEOF if test x${all_targets} = xtrue; then - if test x${enable_64_bit_bfd} = xyes; then + if test x${have_64_bit_bfd} = xyes; then EMULATION_OFILES='$(ALL_EMULATIONS) $(ALL_64_EMULATIONS)' EMUL_EXTRA_OFILES='$(ALL_EMUL_EXTRA_OFILES) $(ALL_64_EMUL_EXTRA_OFILES)' else @@ -19737,10 +19520,6 @@ if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi -if test -z "${ENABLE_BFD_64_BIT_TRUE}" && test -z "${ENABLE_BFD_64_BIT_FALSE}"; then - as_fn_error $? "conditional \"ENABLE_BFD_64_BIT\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi if test -z "${ENABLE_LIBCTF_TRUE}" && test -z "${ENABLE_LIBCTF_FALSE}"; then as_fn_error $? "conditional \"ENABLE_LIBCTF\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/ld/configure.ac b/ld/configure.ac index 228f2ee..e5f56dd 100644 --- a/ld/configure.ac +++ b/ld/configure.ac @@ -414,7 +414,7 @@ AC_SUBST(NATIVE_LIB_DIRS) AC_CHECK_HEADERS(fcntl.h elf-hints.h limits.h inttypes.h stdint.h \ sys/file.h sys/mman.h sys/param.h sys/stat.h sys/time.h \ sys/types.h unistd.h) -AC_CHECK_FUNCS(close glob lseek mkstemp open realpath waitpid) +AC_CHECK_FUNCS(close getrusage glob lseek mkstemp open realpath waitpid) BFD_BINARY_FOPEN @@ -495,11 +495,11 @@ do EMUL=$targ_emul fi - if test x${enable_64_bit_bfd} = xno; then + if test x${have_64_bit_bfd} = xno; then . ${srcdir}/../bfd/config.bfd fi - if test x${enable_64_bit_bfd} = xyes; then + if test x${have_64_bit_bfd} = xyes; then targ_extra_emuls="$targ_extra_emuls $targ64_extra_emuls" targ_extra_libpath="$targ_extra_libpath $targ64_extra_libpath" fi @@ -686,7 +686,7 @@ AC_SUBST(TDIRS) AM_SUBST_NOTMAKE(TDIRS) if test x${all_targets} = xtrue; then - if test x${enable_64_bit_bfd} = xyes; then + if test x${have_64_bit_bfd} = xyes; then EMULATION_OFILES='$(ALL_EMULATIONS) $(ALL_64_EMULATIONS)' EMUL_EXTRA_OFILES='$(ALL_EMUL_EXTRA_OFILES) $(ALL_64_EMUL_EXTRA_OFILES)' else diff --git a/ld/emultempl/emulation.em b/ld/emultempl/emulation.em index 7fe821a..8ff71d6 100644 --- a/ld/emultempl/emulation.em +++ b/ld/emultempl/emulation.em @@ -36,6 +36,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = ${LDEMUL_EMIT_CTF_EARLY-NULL}, ${LDEMUL_ACQUIRE_STRINGS_FOR_CTF-NULL}, ${LDEMUL_NEW_DYNSYM_FOR_CTF-NULL}, - ${LDEMUL_PRINT_SYMBOL-NULL} + ${LDEMUL_PRINT_SYMBOL-NULL}, + ${LDEMUL_FIND_START_SYMBOL-NULL} }; EOF diff --git a/ld/emultempl/kvxelf.em b/ld/emultempl/kvxelf.em index 186f148..c9a83f7 100644 --- a/ld/emultempl/kvxelf.em +++ b/ld/emultempl/kvxelf.em @@ -173,7 +173,7 @@ elf${ELFSIZE}_kvx_add_stub_section (const char *stub_sec_name, return stub_sec; err_ret: - einfo ("%X%P: can not make stub section: %E\n"); + einfo (_("%X%P: can not make stub section: %E\n")); return NULL; } @@ -216,7 +216,7 @@ gld${EMULATION_NAME}_after_allocation (void) ret = bfd_elf_discard_info (link_info.output_bfd, & link_info); if (ret < 0) { - einfo ("%X%P: .eh_frame/.stab edit: %E\n"); + einfo (_("%X%P: .eh_frame/.stab edit: %E\n")); return; } else if (ret > 0) @@ -232,7 +232,7 @@ gld${EMULATION_NAME}_after_allocation (void) { if (ret < 0) { - einfo ("%X%P: could not compute sections lists for stub generation: %E\n"); + einfo (_("%X%P: could not compute sections lists for stub generation: %E\n")); return; } @@ -246,7 +246,7 @@ gld${EMULATION_NAME}_after_allocation (void) & elf${ELFSIZE}_kvx_add_stub_section, & gldkvx_layout_sections_again)) { - einfo ("%X%P: cannot size stub section: %E\n"); + einfo (_("%X%P: cannot size stub section: %E\n")); return; } } @@ -266,7 +266,7 @@ gld${EMULATION_NAME}_finish (void) && stub_file->the_bfd->sections != NULL) { if (! elf${ELFSIZE}_kvx_build_stubs (& link_info)) - einfo ("%X%P: can not build stubs: %E\n"); + einfo (_("%X%P: can not build stubs: %E\n")); } } @@ -291,7 +291,7 @@ kvx_elf_create_output_section_statements (void) bfd_get_arch (link_info.output_bfd), bfd_get_mach (link_info.output_bfd))) { - einfo ("%X%P: can not create BFD %E\n"); + fatal (_("%P: can not create BFD %E\n")); return; } @@ -299,7 +299,7 @@ kvx_elf_create_output_section_statements (void) ldlang_add_file (stub_file); if (!kvx_elf${ELFSIZE}_init_stub_bfd (&link_info, stub_file->the_bfd)) - einfo ("%P: can not init BFD: %E\n"); + fatal (_("%P: can not init BFD: %E\n")); } diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em index 9a2b576..b522687 100644 --- a/ld/emultempl/pe.em +++ b/ld/emultempl/pe.em @@ -7,11 +7,11 @@ else fi case ${target} in - *-*-cygwin*) - cygwin_behavior=1 + *-*-mingw*) + mingw_behavior=1 ;; *) - cygwin_behavior=0; + mingw_behavior=0 ;; esac @@ -126,9 +126,10 @@ fragment <<EOF #define DEFAULT_PSEUDO_RELOC_VERSION 1 #endif -#define DEFAULT_DLL_CHARACTERISTICS (${cygwin_behavior} ? 0 : \ - IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE \ - | IMAGE_DLL_CHARACTERISTICS_NX_COMPAT) +#define DEFAULT_DLL_CHARACTERISTICS (${mingw_behavior} \ + ? IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE \ + | IMAGE_DLL_CHARACTERISTICS_NX_COMPAT \ + : 0) #if defined(TARGET_IS_i386pe) || ! defined(DLL_SUPPORT) #define PE_DEF_SUBSYSTEM IMAGE_SUBSYSTEM_WINDOWS_CUI @@ -2447,6 +2448,55 @@ gld${EMULATION_NAME}_find_potential_libraries { return ldfile_open_file_search (name, entry, "", ".lib"); } + +static struct bfd_link_hash_entry * +gld${EMULATION_NAME}_find_alt_start_symbol + (struct bfd_sym_chain *entry) +{ +#if defined (TARGET_IS_i386pe) + bool entry_has_stdcall_suffix; +#endif + struct bfd_link_hash_entry *h; + size_t entry_name_len; + char *symbol_name; + const char *prefix; + const char *suffix; + + entry_name_len = strlen (entry->name); + + if (is_underscoring ()) + prefix = "_"; + else + prefix = ""; + +#if defined (TARGET_IS_i386pe) + if ((entry_name_len > 2 && entry->name[entry_name_len-2] == '@' && ISDIGIT (entry->name[entry_name_len-1])) + || (entry_name_len > 3 && entry->name[entry_name_len-3] == '@' && ISDIGIT (entry->name[entry_name_len-2]) && ISDIGIT (entry->name[entry_name_len-1])) + || (entry_name_len > 4 && entry->name[entry_name_len-4] == '@' && ISDIGIT (entry->name[entry_name_len-3]) && ISDIGIT (entry->name[entry_name_len-2]) && ISDIGIT (entry->name[entry_name_len-1]))) + entry_has_stdcall_suffix = true; + else + entry_has_stdcall_suffix = false; + + if (!entry_has_stdcall_suffix && (bfd_link_dll (&link_info) || dll)) + suffix = "@12"; + else if (!entry_has_stdcall_suffix && pe_subsystem == 1 /* NT kernel driver */) + suffix = "@8"; + else +#endif + suffix = ""; + + if (*prefix == '\0' && *suffix == '\0') + return NULL; + + symbol_name = xmalloc (entry_name_len + 5); + strcpy (symbol_name, prefix); + strcat (symbol_name, entry->name); + strcat (symbol_name, suffix); + + h = bfd_link_hash_lookup (link_info.hash, symbol_name, false, false, true); + free (symbol_name); + return h; +} static char * gld${EMULATION_NAME}_get_script (int *isfile) @@ -2525,5 +2575,6 @@ LDEMUL_UNRECOGNIZED_FILE=gld${EMULATION_NAME}_unrecognized_file LDEMUL_LIST_OPTIONS=gld${EMULATION_NAME}_list_options LDEMUL_RECOGNIZED_FILE=gld${EMULATION_NAME}_recognized_file LDEMUL_FIND_POTENTIAL_LIBRARIES=gld${EMULATION_NAME}_find_potential_libraries +LDEMUL_FIND_START_SYMBOL=gld${EMULATION_NAME}_find_alt_start_symbol source_em ${srcdir}/emultempl/emulation.em diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em index 440c0bf..60a8339 100644 --- a/ld/emultempl/pep.em +++ b/ld/emultempl/pep.em @@ -9,11 +9,15 @@ fi case ${target} in *-*-cygwin*) move_default_addr_high=1 - cygwin_behavior=1 + mingw_behavior=0 + ;; + *-*-mingw*) + move_default_addr_high=0 + mingw_behavior=1 ;; *) - move_default_addr_high=0; - cygwin_behavior=0; + move_default_addr_high=0 + mingw_behavior=0 ;; esac @@ -126,10 +130,11 @@ fragment <<EOF #define DLL_SUPPORT #endif -#define DEFAULT_DLL_CHARACTERISTICS (${cygwin_behavior} ? 0 : \ - IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE \ - | IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA \ - | IMAGE_DLL_CHARACTERISTICS_NX_COMPAT) +#define DEFAULT_DLL_CHARACTERISTICS (${mingw_behavior} \ + ? IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE \ + | IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA \ + | IMAGE_DLL_CHARACTERISTICS_NX_COMPAT \ + : 0) #if defined(TARGET_IS_i386pep) || defined(COFF_WITH_peAArch64) || ! defined(DLL_SUPPORT) #define PE_DEF_SUBSYSTEM IMAGE_SUBSYSTEM_WINDOWS_CUI diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em index f7a8f1e..857cf54 100644 --- a/ld/emultempl/ppc64elf.em +++ b/ld/emultempl/ppc64elf.em @@ -606,14 +606,15 @@ gld${EMULATION_NAME}_finish (void) einfo (_("%X%P: can not build stubs: %E\n")); fflush (stdout); + FILE * out = config.stats_file ? config.stats_file : stderr; for (line = msg; line != NULL; line = endline) { endline = strchr (line, '\n'); if (endline != NULL) *endline++ = '\0'; - fprintf (stderr, "%s: %s\n", program_name, line); + fprintf (out, "%s: %s\n", program_name, line); } - fflush (stderr); + fflush (out); free (msg); ldelf_finish (); @@ -295,6 +295,10 @@ typedef struct char *map_filename; FILE *map_file; + char *stats_filename; + /* If non-NULL then resource use information should be written to this file. */ + FILE *stats_file; + char *dependency_file; unsigned int split_by_reloc; @@ -330,6 +334,39 @@ typedef struct enum compressed_debug_section_type compress_debug; } ld_config_type; +/* An enumeration of the linker phases for which resource usage information + is recorded. PHASE_ALL is special as it covers the entire link process. + + Instructions for adding a new phase: + 1. Add an entry to this enumeration. + 2. Add an entry for the phase to the phase_data[] structure in ldmain.c. + 3. Add calls to ld_start_phase(PHASE_xxx) and ld_stop_phase(PHASE_xxx) + at the appropriate place(s) in the code. It does not matter if the + new phase overlaps with or is contained by any other phase. + + Instructions for adding a new resource: + 1. If necessary add a new field to the phase_data structure defined in + ldmain.c. + 2. Add code to initialise the field in ld_main.c:ld_start_phase(). + 3. Add code to finalise the field in ld_main.c:ld_stop_phase(). + 4. Add code to report the field in ld_main.c:report_phases(). */ +typedef enum +{ + PHASE_ALL = 0, + PHASE_CTF, + PHASE_MERGE, + PHASE_PARSE, + PHASE_PLUGINS, + PHASE_PROCESS, + PHASE_WRITE, + + NUM_PHASES /* This must be the last entry. */ +} +ld_phase; + +extern void ld_start_phase (ld_phase); +extern void ld_stop_phase (ld_phase); + extern ld_config_type config; extern FILE * saved_script_handle; @@ -531,7 +531,9 @@ named @var{entry}, the linker will try to parse @var{entry} as a number, and use that as the entry address (the number will be interpreted in base 10; you may use a leading @samp{0x} for base 16, or a leading @samp{0} for base 8). @xref{Entry Point}, for a discussion of defaults -and other ways of specifying the entry point. +and other ways of specifying the entry point. For i386 PE, @var{entry} +can be also the original function name (without the leading underscore +and/or the trailing stdcall @samp{@@number} when applicable). @kindex --exclude-libs @item --exclude-libs @var{lib},@var{lib},... @@ -1022,7 +1024,7 @@ Write a @dfn{dependency file} to @var{depfile}. This file contains a rule suitable for @code{make} describing the output file and all the input files that were read to produce it. The output is similar to the compiler's output with @samp{-M -MP} (@pxref{Preprocessor Options,, Options -Controlling the Preprocessor, gcc.info, Using the GNU Compiler +Controlling the Preprocessor, gcc, Using the GNU Compiler Collection}). Note that there is no option like the compiler's @samp{-MM}, to exclude ``system files'' (which is not a well-specified concept in the linker, unlike ``system headers'' in the compiler). So the output from @@ -2184,6 +2186,9 @@ Memory region Used Size Region Size %age Used RAM: 32 B 2 GB 0.00% @end smallexample +Note: if you want to find out about the memory usage of the linker +itself, then the @option{--stats} option will do this. + @cindex help @cindex usage @kindex --help @@ -2706,10 +2711,76 @@ more than @var{count} relocations one output section will contain that many relocations. @var{count} defaults to a value of 32768. @kindex --stats -@item --stats +@item --stats[=@var{filename}] Compute and display statistics about the operation of the linker, such as execution time and memory usage. +If the optional @var{filename} argument is not supplied then only +basic information is reported, and it is sent to the standard error +output stream. If the @var{filename} argument is supplied then +extended information is written to the named file. If @var{filename} +is set to just the @var{-} symbol, then the extended information is +sent to the standard output stream. If the @var{filename} starts with +@var{+} then the file is opened in append mode rather than overwrite +mode. + +If the @option{-Map} option has been enabled then the information is +also recorded in the map file as well. Note: if both the +@option{--stats} option and the @option{-Map} options have been given +@var{filename} arguments and they match, then the information will +only be written out once not twice. + +If the @code{LD_STATS} environment variable is defined then this +behaves likes the @option{--stats} option. If the variable's value is +a string then this will used as the name of a file into which the +information should be recorded. Otherwise the information +will be sent to the standard output stream. Using the environment +variable allows stats to be recorded without having to alter the +linker's command line. Note: if both the environment variable and the +@option{--stats} option are used then the @option{--stats} option +takes precedence. + +The extended information reported includes the cpu time used and, if +the @var{getrusage()} system library call is available then memory use +is recorded as well. This information is reported for individual +parts of the linking process which are referred to as @emph{phases}. +In addition the information is also reported for a special phase +called @emph{ALL} which covers the entire linking process. Note that +individual phases can contain or overlap with each other so it should +not be assumed that the overall resources used by the linker is the +sum of the resources used by the individual phases. + +In addition when extended information is being reported the linker +version, command line arguments and linker start time are also +included. This makes it easier to handle the situation where multiple +links are being invoked by a build system and to indentify exactly +which arguments were responsible for producing the statistics that are +reported. + +The extended output looks something like this: + +@smallexample +Stats: linker version: (GNU Binutils) 2.44.50.20250401 +Stats: linker started: Wed Apr 2 09:36:41 2025 +Stats: args: ld -z norelro -z nomemory-seal -z no-separate-code -o a.out [...] + +Stats: phase cpu time memory user time system time +Stats: name (microsec) (KiB) (seconds) (seconds) +Stats: ALL 390082 217740 0 0 +Stats: ctf processing 12 0 0 0 +Stats: string merge 1324 0 0 0 +Stats: parsing 349 288 0 0 +Stats: plugins 1 0 0 0 +Stats: processing files 259616 214524 0 0 +Stats: write 116493 0 0 0 +@end smallexample + +@kindex --no-stats +@item --no-stats +Disables the reporting of usage statistics, should it have been +enabled via the @option{--stats} command line option or the +@var{LD_STATS} environment variable. + @kindex --sysroot=@var{directory} @item --sysroot=@var{directory} Use @var{directory} as the location of the sysroot, overriding the @@ -3712,7 +3783,8 @@ of the PE file header: @item --high-entropy-va @itemx --disable-high-entropy-va Image is compatible with 64-bit address space layout randomization -(ASLR). This option is enabled by default for 64-bit PE images. +(ASLR). This option is enabled by default for 64-bit PE images in +MinGW targets. This option also implies @option{--dynamicbase} and @option{--enable-reloc-section}. @@ -3722,9 +3794,9 @@ This option also implies @option{--dynamicbase} and @itemx --disable-dynamicbase The image base address may be relocated using address space layout randomization (ASLR). This feature was introduced with MS Windows -Vista for i386 PE targets. This option is enabled by default but -can be disabled via the @option{--disable-dynamicbase} option. -This option also implies @option{--enable-reloc-section}. +Vista for i386 PE targets. This option is enabled by default for MinGW +targets but can be disabled via the @option{--disable-dynamicbase} +option. This option also implies @option{--enable-reloc-section}. @kindex --forceinteg @item --forceinteg @@ -3737,7 +3809,7 @@ default. @item --disable-nxcompat The image is compatible with the Data Execution Prevention. This feature was introduced with MS Windows XP SP2 for i386 PE -targets. The option is enabled by default. +targets. The option is enabled by default for MinGW targets. @kindex --no-isolation @item --no-isolation @@ -4078,6 +4150,15 @@ If the PE/COFF specific @option{--insert-timestamp} is active and the timestamp value in this variable will be inserted into the COFF header instead of the current time. +@kindex LD_STATS +@cindex LD_STATS +If the @code{LD_STATS} environment variable is defined then linker +resource use information will be recorded, just as if the +@option{--stats} option had been used. If the @code{LD_STATS} +variable has a string value then this will used as the name of a file +into which the information should be stored. Otherwise the information +will be sent to the standard output stream. + @c man end @end ifset @@ -9605,7 +9686,7 @@ format can be supported simply by creating a new BFD back end and adding it to the library. To conserve runtime memory, however, the linker and associated tools are usually configured to support only a subset of the object file formats available. You can use @code{objdump -i} -(@pxref{objdump,,objdump,binutils.info,The GNU Binary Utilities}) to +(@pxref{objdump,,objdump,binutils,The GNU Binary Utilities}) to list all the formats available for your configuration. @cindex BFD requirements diff --git a/ld/ldemul.c b/ld/ldemul.c index dce0d38..35f91a2 100644 --- a/ld/ldemul.c +++ b/ld/ldemul.c @@ -35,6 +35,14 @@ static ld_emulation_xfer_type *ld_emulation; +struct bfd_link_hash_entry * +ldemul_find_alt_start_symbol (struct bfd_sym_chain *entry) +{ + if (ld_emulation->find_alt_start_symbol) + return ld_emulation->find_alt_start_symbol (entry); + return NULL; +} + void ldemul_hll (char *name) { diff --git a/ld/ldemul.h b/ld/ldemul.h index aa014ae..c58d4c2 100644 --- a/ld/ldemul.h +++ b/ld/ldemul.h @@ -115,9 +115,10 @@ extern void ldemul_acquire_strings_for_ctf (struct ctf_dict *, struct elf_strtab_hash *); extern void ldemul_new_dynsym_for_ctf (struct ctf_dict *, int symidx, struct elf_internal_sym *); - extern bool ldemul_print_symbol (struct bfd_link_hash_entry *hash_entry, void *ptr); +extern struct bfd_link_hash_entry * ldemul_find_alt_start_symbol + (struct bfd_sym_chain *); typedef struct ld_emulation_xfer_struct { /* Run before parsing the command line and script file. @@ -259,6 +260,11 @@ typedef struct ld_emulation_xfer_struct { bool (*print_symbol) (struct bfd_link_hash_entry *hash_entry, void *ptr); + /* Called when ENTRY->name cannot be found by a direct lookup in INFO->hash. + Allows emulations to try variations of the name. */ + struct bfd_link_hash_entry * (*find_alt_start_symbol) + (struct bfd_sym_chain *entry); + } ld_emulation_xfer_type; typedef enum { diff --git a/ld/ldlang.c b/ld/ldlang.c index 0048dfa..32e6e7a 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -322,7 +322,7 @@ spec_match (const struct wildcard_spec *spec, const char *name) } static char * -ldirname (const char *name) +stat_ldirname (const char *name) { const char *base = lbasename (name); @@ -1266,7 +1266,7 @@ new_afile (const char *name, /* If name is a relative path, search the directory of the current linker script first. */ if (from_filename && !IS_ABSOLUTE_PATH (name)) - p->extra_search_path = ldirname (from_filename); + p->extra_search_path = stat_ldirname (from_filename); p->flags.real = true; p->flags.search_dirs = true; break; @@ -2486,11 +2486,18 @@ lang_map (void) } static bool +is_defined (struct bfd_link_hash_entry *h) +{ + return h != NULL + && (h->type == bfd_link_hash_defined + || h->type == bfd_link_hash_defweak); +} + +static bool sort_def_symbol (struct bfd_link_hash_entry *hash_entry, void *info ATTRIBUTE_UNUSED) { - if ((hash_entry->type == bfd_link_hash_defined - || hash_entry->type == bfd_link_hash_defweak) + if (is_defined (hash_entry) && hash_entry->u.def.section->owner != link_info.output_bfd && hash_entry->u.def.section->owner != NULL) { @@ -3807,6 +3814,8 @@ ldlang_open_ctf (void) int any_ctf = 0; int err; + ld_start_phase (PHASE_CTF); + LANG_FOR_EACH_INPUT_STATEMENT (file) { asection *sect; @@ -3844,17 +3853,23 @@ ldlang_open_ctf (void) if (!any_ctf) { ctf_output = NULL; + ld_stop_phase (PHASE_CTF); return; } if ((ctf_output = ctf_create (&err)) != NULL) - return; + { + ld_stop_phase (PHASE_CTF); + return; + } einfo (_("%P: warning: CTF output not created: `%s'\n"), ctf_errmsg (err)); LANG_FOR_EACH_INPUT_STATEMENT (errfile) ctf_close (errfile->the_ctf); + + ld_stop_phase (PHASE_CTF); } /* Merge together CTF sections. After this, only the symtab-dependent @@ -3869,6 +3884,8 @@ lang_merge_ctf (void) if (!ctf_output) return; + ld_start_phase (PHASE_CTF); + output_sect = bfd_get_section_by_name (link_info.output_bfd, ".ctf"); /* If the section was discarded, don't waste time merging. */ @@ -3882,6 +3899,8 @@ lang_merge_ctf (void) ctf_close (file->the_ctf); file->the_ctf = NULL; } + + ld_stop_phase (PHASE_CTF); return; } @@ -3924,6 +3943,8 @@ lang_merge_ctf (void) } /* Output any lingering errors that didn't come from ctf_link. */ lang_ctf_errs_warnings (ctf_output); + + ld_stop_phase (PHASE_CTF); } /* Let the emulation acquire strings from the dynamic strtab to help it optimize @@ -3932,7 +3953,9 @@ lang_merge_ctf (void) void ldlang_ctf_acquire_strings (struct elf_strtab_hash *dynstrtab) { + ld_start_phase (PHASE_CTF); ldemul_acquire_strings_for_ctf (ctf_output, dynstrtab); + ld_stop_phase (PHASE_CTF); } /* Inform the emulation about the addition of a new dynamic symbol, in BFD @@ -3954,16 +3977,24 @@ lang_write_ctf (int late) if (!ctf_output) return; + ld_start_phase (PHASE_CTF); + if (late) { /* Emit CTF late if this emulation says it can do so. */ if (ldemul_emit_ctf_early ()) - return; + { + ld_stop_phase (PHASE_CTF); + return; + } } else { if (!ldemul_emit_ctf_early ()) - return; + { + ld_stop_phase (PHASE_CTF); + return; + } } /* Inform the emulation that all the symbols that will be received have @@ -3998,6 +4029,8 @@ lang_write_ctf (int late) LANG_FOR_EACH_INPUT_STATEMENT (file) file->the_ctf = NULL; + + ld_stop_phase (PHASE_CTF); } /* Write out the CTF section late, if the emulation needs that. */ @@ -4158,9 +4191,7 @@ ldlang_check_require_defined_symbols (void) h = bfd_link_hash_lookup (link_info.hash, ptr->name, false, false, true); - if (h == NULL - || (h->type != bfd_link_hash_defined - && h->type != bfd_link_hash_defweak)) + if (! is_defined (h)) einfo(_("%X%P: required symbol `%s' not defined\n"), ptr->name); } } @@ -4866,9 +4897,7 @@ print_assignment (lang_assignment_statement_type *assignment, h = bfd_link_hash_lookup (link_info.hash, assignment->exp->assign.dst, false, false, true); - if (h != NULL - && (h->type == bfd_link_hash_defined - || h->type == bfd_link_hash_defweak)) + if (is_defined (h)) { value = h->u.def.value; value += h->u.def.section->output_section->vma; @@ -4913,8 +4942,7 @@ print_one_symbol (struct bfd_link_hash_entry *hash_entry, void *ptr) { asection *sec = (asection *) ptr; - if ((hash_entry->type == bfd_link_hash_defined - || hash_entry->type == bfd_link_hash_defweak) + if (is_defined (hash_entry) && sec == hash_entry->u.def.section) { print_spaces (SECTION_NAME_MAP_LENGTH); @@ -5036,7 +5064,8 @@ print_input_section (asection *i, bool is_discarded) } print_spaces (SECTION_NAME_MAP_LENGTH - len); - if (i->output_section != NULL + if ((i->flags & SEC_EXCLUDE) == 0 + && i->output_section != NULL && i->output_section->owner == link_info.output_bfd) addr = i->output_section->vma + i->output_offset; else @@ -7207,9 +7236,7 @@ lang_end (void) { h = bfd_link_hash_lookup (link_info.hash, sym->name, false, false, false); - if (h != NULL - && (h->type == bfd_link_hash_defined - || h->type == bfd_link_hash_defweak) + if (is_defined (h) && !bfd_is_const_section (h->u.def.section)) break; } @@ -7228,9 +7255,11 @@ lang_end (void) h = bfd_link_hash_lookup (link_info.hash, entry_symbol.name, false, false, true); - if (h != NULL - && (h->type == bfd_link_hash_defined - || h->type == bfd_link_hash_defweak) + + if (! is_defined (h) || h->u.def.section->output_section == NULL) + h = ldemul_find_alt_start_symbol (&entry_symbol); + + if (is_defined (h) && h->u.def.section->output_section != NULL) { bfd_vma val; @@ -8547,6 +8576,8 @@ lang_process (void) { asection *found; + ld_start_phase (PHASE_MERGE); + /* Merge SEC_MERGE sections. This has to be done after GC of sections, so that GCed sections are not merged, but before assigning dynamic symbols, since removing whole input sections @@ -8554,6 +8585,8 @@ lang_process (void) if (!bfd_merge_sections (link_info.output_bfd, &link_info)) fatal (_("%P: bfd_merge_sections failed: %E\n")); + ld_stop_phase (PHASE_MERGE); + /* Look for a text section and set the readonly attribute in it. */ found = bfd_get_section_by_name (link_info.output_bfd, ".text"); @@ -46,6 +46,7 @@ enum option_values OPTION_MAP, OPTION_NO_DEMANGLE, OPTION_NO_KEEP_MEMORY, + OPTION_NO_STATS, OPTION_NO_WARN_MISMATCH, OPTION_NO_WARN_SEARCH_MISMATCH, OPTION_NOINHIBIT_EXEC, diff --git a/ld/ldmain.c b/ld/ldmain.c index 54a834e..67c60c3 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -21,6 +21,7 @@ #include "sysdep.h" #include "bfd.h" +#include "bfdver.h" #include "safe-ctype.h" #include "libiberty.h" #include "bfdlink.h" @@ -51,6 +52,10 @@ #include <string.h> +#if defined (HAVE_GETRUSAGE) +#include <sys/resource.h> +#endif + #ifndef TARGET_SYSTEM_ROOT #define TARGET_SYSTEM_ROOT "" #endif @@ -224,6 +229,10 @@ ld_cleanup (void) bfd_close_all_done (ibfd); } #if BFD_SUPPORTS_PLUGINS + /* Note - we do not call ld_plugin_start (PHASE_PLUGINS) here as this + function is only called when the linker is exiting - ie after any + stats may have been reported, and potentially in the middle of a + phase where we have already started recording plugin stats. */ plugin_call_cleanup (); #endif if (output_filename && delete_output_file_on_failure) @@ -270,11 +279,305 @@ display_external_script (void) free (buf); } +struct ld_phase_data +{ + const char * name; + + unsigned long start; + unsigned long duration; + + bool started; + bool broken; + +#if defined (HAVE_GETRUSAGE) + struct rusage begin; + struct rusage use; +#endif +}; + +static struct ld_phase_data phase_data [NUM_PHASES] = +{ + [PHASE_ALL] = { .name = "ALL" }, + [PHASE_CTF] = { .name = "ctf processing" }, + [PHASE_MERGE] = { .name = "string merge" }, + [PHASE_PARSE] = { .name = "parsing" }, + [PHASE_PLUGINS] = { .name = "plugins" }, + [PHASE_PROCESS] = { .name = "processing files" }, + [PHASE_WRITE] = { .name = "write" }, +}; + +void +ld_start_phase (ld_phase phase) +{ + struct ld_phase_data * pd = phase_data + phase; + + /* We record data even if config.stats_file is NULL. This allows + us to record data about phases that start before the command line + arguments have been parsed. ie PHASE_ALL and PHASE_PARSE. */ + + /* Do not overwrite the fields if we have already started recording. */ + if (pd->started) + { + /* Since we do not queue phase starts and stops, if a phase is started + multiple times there is a likelyhood that it will be stopped multiple + times as well. This is problematic as we will only record the data + for the first time the phase stops and ignore all of the other stops. + + So let the user know. Ideally real users will never actually see + this message, and instead only developers who are adding new phase + tracking code will ever encounter it. */ + einfo ("%P: --stats: phase %s started twice - data may be unreliable\n", + pd->name); + return; + } + + /* It is OK if other phases are also active at this point. + It just means that the phases overlap or that one phase is a sub-task + of another. Since we record resources on a per-phase basis, this + should not matter. */ + + pd->started = true; + pd->start = get_run_time (); + +#if defined (HAVE_GETRUSAGE) + /* Record the resource usage at the start of the phase. */ + struct rusage usage; + + if (getrusage (RUSAGE_SELF, & usage) != 0) + /* FIXME: Complain ? */ + return; + + memcpy (& pd->begin, & usage, sizeof usage); +#endif +} + +void +ld_stop_phase (ld_phase phase) +{ + struct ld_phase_data * pd = phase_data + phase; + + if (!pd->started) + { + /* We set the broken flag to indicate that the data + recorded for this phase is inconsistent. */ + pd->broken = true; + return; + } + + pd->duration += get_run_time () - pd->start; + pd->started = false; + +#if defined (HAVE_GETRUSAGE) + struct rusage usage; + + if (getrusage (RUSAGE_SELF, & usage) != 0) + /* FIXME: Complain ? */ + return; + + if (phase == PHASE_ALL) + memcpy (& pd->use, & usage, sizeof usage); + else + { + struct timeval t; + + /* For sub-phases we record the increase in specific fields. */ + /* FIXME: Most rusage{} fields appear to be irrelevent to when considering + linker resource usage. Currently we record maxrss and user and system + cpu times. Are there any other fields that might be useful ? */ + +#ifndef timeradd /* Macros copied from <sys/time.h>. */ +#define timeradd(a, b, result) \ + do \ + { \ + (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \ + if ((result)->tv_usec >= 1000000) \ + { \ + ++(result)->tv_sec; \ + (result)->tv_usec -= 1000000; \ + } \ + } \ + while (0) +#endif + +#ifndef timersub +#define timersub(a, b, result) \ + do \ + { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) \ + { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000; \ + } \ + } \ + while (0) +#endif + + timersub (& usage.ru_utime, & pd->begin.ru_utime, & t); + timeradd (& pd->use.ru_utime, &t, & pd->use.ru_utime); + + timersub (& usage.ru_stime, & pd->begin.ru_stime, & t); + timeradd (& pd->use.ru_stime, &t, & pd->use.ru_stime); + + if (pd->begin.ru_maxrss < usage.ru_maxrss) + pd->use.ru_maxrss += usage.ru_maxrss - pd->begin.ru_maxrss; + } +#endif +} + +static void +report_phases (FILE * file, time_t * start, char ** argv) +{ + unsigned long i; + + if (file == NULL) + return; + + /* We might be writing to stdout, so make sure + that we do not have any pending error output. */ + fflush (stderr); + + /* We do not translate "Stats" as we provide this as a key + word that can be searched for by grep and the like. */ +#define STATS_PREFIX "Stats: " + + fprintf (file, STATS_PREFIX "linker version: %s\n", BFD_VERSION_STRING); + + /* No \n at the end of the string as ctime() provides its own. */ + fprintf (file, STATS_PREFIX "linker started: %s", ctime (start)); + + /* We include the linker command line arguments since + they can be hard to track down by other means. */ + if (argv != NULL) + { + fprintf (file, STATS_PREFIX "args: "); + for (i = 0; argv[i] != NULL; i++) + fprintf (file, "%s ", argv[i]); + fprintf (file, "\n\n"); /* Blank line to separate the args from the stats. */ + } + + /* All of this song and dance with the column_info struct and printf + formatting is so that we can have a nicely formated table with regular + column spacing, whilst allowing for the column headers to be translated, + and coping nicely with extra long strings or numbers. */ + struct column_info + { + const char * header; + const char * sub_header; + int width; + int pad; + } columns[] = +#define COLUMNS_FIELD(HEADER,SUBHEADER) \ + { .header = N_( HEADER ), .sub_header = N_( SUBHEADER ) }, + { + COLUMNS_FIELD ("phase", "name") + COLUMNS_FIELD ("cpu time", "(microsec)") +#if defined (HAVE_GETRUSAGE) + /* Note: keep these columns in sync with the + information recorded in ld_stop_phase(). */ + COLUMNS_FIELD ("memory", "(KiB)") + COLUMNS_FIELD ("user time", "(seconds)") + COLUMNS_FIELD ("system time", "(seconds)") +#endif + }; + +#ifndef max +#define max(A,B) ((A) < (B) ? (B) : (A)) +#endif + + size_t maxwidth = 1; + for (i = 0; i < NUM_PHASES; i++) + maxwidth = max (maxwidth, strlen (phase_data[i].name)); + + fprintf (file, "%s", STATS_PREFIX); + + for (i = 0; i < ARRAY_SIZE (columns); i++) + { + int padding; + + if (i == 0) + columns[i].width = fprintf (file, "%-*s", (int) maxwidth, columns[i].header); + else + columns[i].width = fprintf (file, "%s", columns[i].header); + padding = columns[i].width % 8; + if (padding < 4) + padding = 4; + columns[i].pad = fprintf (file, "%*c", padding, ' '); + } + + fprintf (file, "\n"); + + int bias = 0; +#define COLUMN_ENTRY(VAL, FORMAT, N) \ + do \ + { \ + int l; \ + \ + if (N == 0) \ + l = fprintf (file, "%-*" FORMAT, columns[N].width, VAL); \ + else \ + l = fprintf (file, "%*" FORMAT, columns[N].width - bias, VAL); \ + bias = 0; \ + if (l < columns[N].width) \ + l = columns[N].pad; \ + else if (l < columns[N].width + columns[N].pad) \ + l = columns[N].pad - (l - columns[N].width); \ + else \ + { \ + bias = l - (columns[N].width + columns[N].pad); \ + l = 0; \ + } \ + if (l) \ + fprintf (file, "%*c", l, ' '); \ + } \ + while (0) + + fprintf (file, "%s", STATS_PREFIX); + + for (i = 0; i < ARRAY_SIZE (columns); i++) + COLUMN_ENTRY (columns[i].sub_header, "s", i); + + fprintf (file, "\n"); + + for (i = 0; i < NUM_PHASES; i++) + { + struct ld_phase_data * pd = phase_data + i; + /* This should not be needed... */ + const char * name = pd->name ? pd->name : "<unnamed>"; + + if (pd->broken) + { + fprintf (file, "%s %s: %s", + STATS_PREFIX, name, _("WARNING: Data is unreliable!\n")); + continue; + } + + fprintf (file, "%s", STATS_PREFIX); + + /* Care must be taken to keep the lines below in sync with + entries in the columns_info array. + FIXME: There ought to be a better way to do this... */ + COLUMN_ENTRY (name, "s", 0); + COLUMN_ENTRY (pd->duration, "ld", 1); +#if defined (HAVE_GETRUSAGE) + COLUMN_ENTRY (pd->use.ru_maxrss, "ld", 2); + COLUMN_ENTRY ((int64_t) pd->use.ru_utime.tv_sec, PRId64, 3); + COLUMN_ENTRY ((int64_t) pd->use.ru_stime.tv_sec, PRId64, 4); +#endif + fprintf (file, "\n"); + } + + fflush (file); +} + int main (int argc, char **argv) { char *emulation; long start_time = get_run_time (); + time_t start_seconds = time (NULL); #ifdef HAVE_LC_MESSAGES setlocale (LC_MESSAGES, ""); @@ -286,7 +589,23 @@ main (int argc, char **argv) program_name = argv[0]; xmalloc_set_program_name (program_name); + /* Check the LD_STATS environment variable before parsing the command line + so that the --stats option, if used, can override the environment variable. */ + char * stats_filename; + if ((stats_filename = getenv ("LD_STATS")) != NULL) + { + if (ISPRINT (stats_filename[0])) + config.stats_filename = stats_filename; + else + config.stats_filename = "-"; + config.stats = true; + } + + ld_start_phase (PHASE_ALL); + ld_start_phase (PHASE_PARSE); + expandargv (&argc, &argv); + char ** saved_argv = dupargv (argv); if (bfd_init () != BFD_INIT_MAGIC) fatal (_("%P: fatal error: libbfd ABI mismatch\n")); @@ -404,11 +723,17 @@ main (int argc, char **argv) if (config.hash_table_size != 0) bfd_hash_set_default_size (config.hash_table_size); + ld_stop_phase (PHASE_PARSE); + #if BFD_SUPPORTS_PLUGINS + ld_start_phase (PHASE_PLUGINS); /* Now all the plugin arguments have been gathered, we can load them. */ plugin_load_plugins (); + ld_stop_phase (PHASE_PLUGINS); #endif /* BFD_SUPPORTS_PLUGINS */ + ld_start_phase (PHASE_PARSE); + ldemul_set_symbols (); /* If we have not already opened and parsed a linker script, @@ -531,7 +856,31 @@ main (int argc, char **argv) link_info.has_map_file = true; } + if (config.stats_filename != NULL) + { + if (config.map_filename != NULL + && strcmp (config.stats_filename, config.map_filename) == 0) + config.stats_file = NULL; + else if (strcmp (config.stats_filename, "-") == 0) + config.stats_file = stdout; + else + { + if (config.stats_filename[0] == '+') + config.stats_file = fopen (config.stats_filename + 1, "a"); + else + config.stats_file = fopen (config.stats_filename, "w"); + + if (config.stats_file == NULL) + einfo ("%P: Warning: failed to open resource record file: %s\n", + config.stats_filename); + } + } + + ld_stop_phase (PHASE_PARSE); + + ld_start_phase (PHASE_PROCESS); lang_process (); + ld_stop_phase (PHASE_PROCESS); /* Print error messages for any missing symbols, for any warning symbols, and possibly multiple definitions. */ @@ -558,7 +907,11 @@ main (int argc, char **argv) link_info.output_bfd->flags |= flags & bfd_applicable_file_flags (link_info.output_bfd); + + ld_start_phase (PHASE_WRITE); ldwrite (); + ld_stop_phase (PHASE_WRITE); + if (config.map_file != NULL) lang_map (); @@ -653,19 +1006,38 @@ main (int argc, char **argv) if (config.emit_gnu_object_only) cmdline_emit_object_only_section (); + ld_stop_phase (PHASE_ALL); + if (config.stats) { - long run_time = get_run_time () - start_time; + report_phases (config.map_file, & start_seconds, saved_argv); + + if (config.stats_filename) + { + report_phases (config.stats_file, & start_seconds, saved_argv); + + if (config.stats_file != stdout && config.stats_file != stderr) + { + fclose (config.stats_file); + config.stats_file = NULL; + } + } + else /* This is for backwards compatibility. */ + { + long run_time = get_run_time () - start_time; - fflush (stdout); - fprintf (stderr, _("%s: total time in link: %ld.%06ld\n"), - program_name, run_time / 1000000, run_time % 1000000); - fflush (stderr); + fflush (stdout); + fprintf (stderr, _("%s: total time in link: %ld.%06ld\n"), + program_name, run_time / 1000000, run_time % 1000000); + fflush (stderr); + } } /* Prevent ld_cleanup from deleting the output file. */ output_filename = NULL; + freeargv (saved_argv); + xexit (0); return 0; } @@ -942,8 +1314,11 @@ add_archive_element (struct bfd_link_info *info, && (!no_more_claiming || bfd_get_lto_type (abfd) != lto_fat_ir_object)) { + ld_start_phase (PHASE_PLUGINS); /* We must offer this archive member to the plugins to claim. */ plugin_maybe_claim (input); + ld_stop_phase (PHASE_PLUGINS); + if (input->flags.claimed) { if (no_more_claiming) diff --git a/ld/ldmisc.c b/ld/ldmisc.c index 9ee0781..3f305fa 100644 --- a/ld/ldmisc.c +++ b/ld/ldmisc.c @@ -42,7 +42,6 @@ %C clever filename:linenumber with function %D like %C, but no function name %E current bfd error or errno - %F error is fatal %G like %D, but only function name %H like %C but in addition emit section+offset %P print program name @@ -70,7 +69,6 @@ void vfinfo (FILE *fp, const char *fmt, va_list ap, bool is_warning) { - bool isfatal = false; const char *scan; int arg_type; unsigned int arg_count = 0; @@ -280,11 +278,6 @@ vfinfo (FILE *fp, const char *fmt, va_list ap, bool is_warning) } break; - case 'F': - /* Error is fatal. */ - isfatal = true; - break; - case 'P': /* Print program name. */ fprintf (fp, "%s", program_name); @@ -586,9 +579,6 @@ vfinfo (FILE *fp, const char *fmt, va_list ap, bool is_warning) if (is_warning && config.fatal_warnings) config.make_executable = false; - - if (isfatal) - xexit (1); } /* Format info message and print on stdout. */ diff --git a/ld/lexsup.c b/ld/lexsup.c index 7de6e25..bde2046 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -499,8 +499,10 @@ static const struct ld_option ld_options[] = { {"split-by-reloc", optional_argument, NULL, OPTION_SPLIT_BY_RELOC}, '\0', N_("[=COUNT]"), N_("Split output sections every COUNT relocs"), TWO_DASHES }, - { {"stats", no_argument, NULL, OPTION_STATS}, - '\0', NULL, N_("Print memory usage statistics"), TWO_DASHES }, + { {"stats", optional_argument, NULL, OPTION_STATS}, + '\0', NULL, N_("Print resource usage statistics"), TWO_DASHES }, + { {"no-stats", optional_argument, NULL, OPTION_NO_STATS}, + '\0', NULL, N_("Do not print resource usage statistics"), TWO_DASHES }, { {"target-help", no_argument, NULL, OPTION_TARGET_HELP}, '\0', NULL, N_("Display target specific options"), TWO_DASHES }, { {"task-link", required_argument, NULL, OPTION_TASK_LINK}, @@ -1412,6 +1414,17 @@ parse_args (unsigned argc, char **argv) break; case OPTION_STATS: config.stats = true; + if (optarg) + config.stats_filename = optarg; + else + { + config.stats_filename = NULL; + config.stats_file = stderr; + } + break; + case OPTION_NO_STATS: + config.stats = false; + config.stats_filename = NULL; break; case OPTION_NO_SYMBOLIC: opt_symbolic = symbolic_unset; diff --git a/ld/pe-dll.c b/ld/pe-dll.c index de1cfaf..210b77e 100644 --- a/ld/pe-dll.c +++ b/ld/pe-dll.c @@ -1620,10 +1620,11 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info) printf ("rel: %s\n", sym->name); } if (!relocs[i]->howto->pc_relative - && relocs[i]->howto->type != pe_details->imagebase_reloc - && (relocs[i]->howto->type < pe_details->secrel_reloc_lo - || relocs[i]->howto->type > pe_details->secrel_reloc_hi) - && relocs[i]->howto->type != pe_details->section_reloc) + && (bfd_get_flavour (b) != bfd_target_coff_flavour + || (relocs[i]->howto->type != pe_details->imagebase_reloc + && (relocs[i]->howto->type < pe_details->secrel_reloc_lo + || relocs[i]->howto->type > pe_details->secrel_reloc_hi) + && relocs[i]->howto->type != pe_details->section_reloc))) { struct bfd_symbol *sym = *relocs[i]->sym_ptr_ptr; const struct bfd_link_hash_entry *blhe @@ -2639,9 +2640,9 @@ make_import_fixup_mark (arelent *rel, char *name) memcpy (fixup_name, buf, prefix_len); bh = NULL; - bfd_coff_link_add_one_symbol (&link_info, abfd, fixup_name, BSF_GLOBAL, - current_sec, /* sym->section, */ - rel->address, NULL, true, false, &bh); + _bfd_generic_link_add_one_symbol (&link_info, abfd, fixup_name, BSF_GLOBAL, + current_sec, /* sym->section, */ + rel->address, NULL, true, false, &bh); return bh->root.string; } diff --git a/ld/scripttempl/avr.sc b/ld/scripttempl/avr.sc index 8479ec3..4d9af7f 100644 --- a/ld/scripttempl/avr.sc +++ b/ld/scripttempl/avr.sc @@ -189,11 +189,16 @@ SECTIONS ${RELOCATING+*(.vectors) KEEP(*(.vectors)) - /* For data that needs to reside in the lower 64k of progmem. */ - *(.progmem.gcc*) + /* For data that needs to reside in the lower 64k of progmem. + For data accessed with ELPM use .progmemx.* instead + so that no lower 64k .progmem addresses are wasted. */ + __progmem_start = . ; + *(.progmem) + *(.progmem.*) + __progmem_end = . ; + ASSERT (__progmem_start == __progmem_end || __progmem_end <= 0x10000, + \".progmem section exceeds 0x10000\"); - /* PR 13812: Placing the trampolines here gives a better chance - that they will be in range of the code that uses them. */ . = ALIGN(2); __trampolines_start = . ; /* The jump trampolines for the 16-bit limited relocs will reside here. */ @@ -201,12 +206,6 @@ SECTIONS *(.trampolines*) __trampolines_end = . ; - /* avr-libc expects these data to reside in lower 64K. */ - *libprintf_flt.a:*(.progmem.data) - *libc.a:*(.progmem.data) - - *(.progmem.*) - . = ALIGN(2); /* For code that needs to reside in the lower 128k progmem. */ @@ -273,6 +272,7 @@ SECTIONS *(.hightext) *(.hightext*) + *(.progmemx) *(.progmemx.*) . = ALIGN(2); diff --git a/ld/scripttempl/pe.sc b/ld/scripttempl/pe.sc index 96a4751..8fb98b2 100644 --- a/ld/scripttempl/pe.sc +++ b/ld/scripttempl/pe.sc @@ -14,7 +14,7 @@ fi # substitution, so we do this instead. # Sorting of the .foo$* sections is required by the definition of # grouped sections in PE. -# Sorting of the file names in R_IDATA is required by the +# Sorting of the file names in R_IDATA and R_DIDAT is required by the # current implementation of dlltool (this could probably be changed to # use grouped sections instead). if test "${RELOCATING}"; then @@ -39,6 +39,18 @@ if test "${RELOCATING}"; then R_IDATA67=' KEEP (SORT(*)(.idata$6)) KEEP (SORT(*)(.idata$7))' + R_DIDAT234=' + __DELAY_IMPORT_DIRECTORY_start__ = .; + KEEP (SORT(*)(.didat$2)) + KEEP (SORT(*)(.didat$3)) + __DELAY_IMPORT_DIRECTORY_end__ = .; + /* These zeroes mark the end of the import list. */ + . += (__DELAY_IMPORT_DIRECTORY_end__ - __DELAY_IMPORT_DIRECTORY_start__) ? 8*4 : 0; + KEEP (SORT(*)(.didat$4))' + R_DIDAT5='KEEP (SORT(*)(.didat$5))' + R_DIDAT67=' + KEEP (SORT(*)(.didat$6)) + KEEP (SORT(*)(.didat$7))' R_CRT_XC='KEEP (*(SORT(.CRT$XC*))) /* C initialization */' R_CRT_XI='KEEP (*(SORT(.CRT$XI*))) /* C++ initialization */' R_CRT_XL='KEEP (*(SORT(.CRT$XL*))) /* TLS callbacks */' @@ -61,6 +73,9 @@ else R_IDATA234= R_IDATA5= R_IDATA67= + R_DIDAT234= + R_DIDAT5= + R_DIDAT67= R_CRT_XC= R_CRT_XI= R_CRT_XL= @@ -131,6 +146,11 @@ SECTIONS ${RELOCATING+__rt_psrelocs_start = .;} ${RELOCATING+KEEP(*(.rdata_runtime_pseudo_reloc))} ${RELOCATING+__rt_psrelocs_end = .;} + /* read-only parts of .didat */ + /* This cannot currently be handled with grouped sections. + See pe.em:sort_sections. */ + ${R_DIDAT234} + ${R_DIDAT67} /* .ctors & .dtors */ ${CONSTRUCTING+ @@ -244,6 +264,13 @@ SECTIONS ${R_IDATA67} } + .didat ${RELOCATING+BLOCK(__section_alignment__)} : + { + /* This cannot currently be handled with grouped sections. + See pe.em:sort_sections. */ + ${R_DIDAT5} + } + /* Windows TLS expects .tls\$AAA to be at the start and .tls\$ZZZ to be at the end of section. This is important because _tls_start MUST be at the beginning of the section to enable SECREL32 relocations with TLS diff --git a/ld/scripttempl/pep.sc b/ld/scripttempl/pep.sc index e2c6c2c..841ee35 100644 --- a/ld/scripttempl/pep.sc +++ b/ld/scripttempl/pep.sc @@ -14,7 +14,7 @@ fi # substitution, so we do this instead. # Sorting of the .foo$* sections is required by the definition of # grouped sections in PE. -# Sorting of the file names in R_IDATA is required by the +# Sorting of the file names in R_IDATA and R_DIDAT is required by the # current implementation of dlltool (this could probably be changed to # use grouped sections instead). if test "${RELOCATING}"; then @@ -40,6 +40,19 @@ if test "${RELOCATING}"; then R_IDATA67=' KEEP (SORT(*)(.idata$6)) KEEP (SORT(*)(.idata$7))' + R_DIDAT234=' + __DELAY_IMPORT_DIRECTORY_start__ = .; + KEEP (SORT(*)(.didat$2)) + KEEP (SORT(*)(.didat$3)) + __DELAY_IMPORT_DIRECTORY_end__ = .; + /* These zeroes mark the end of the import list. */ + . += (__DELAY_IMPORT_DIRECTORY_end__ - __DELAY_IMPORT_DIRECTORY_start__) ? 8*4 : 0; + . = ALIGN(8); + KEEP (SORT(*)(.didat$4))' + R_DIDAT5='SORT(*)(.didat$5)' + R_DIDAT67=' + KEEP (SORT(*)(.didat$6)) + KEEP (SORT(*)(.didat$7))' R_CRT_XC='KEEP (*(SORT(.CRT$XC*))) /* C initialization */' R_CRT_XI='KEEP (*(SORT(.CRT$XI*))) /* C++ initialization */' R_CRT_XL='KEEP (*(SORT(.CRT$XL*))) /* TLS callbacks */' @@ -62,6 +75,9 @@ else R_IDATA234= R_IDATA5= R_IDATA67= + R_DIDAT234= + R_DIDAT5= + R_DIDAT67= R_CRT_XC= R_CRT_XI= R_CRT_XL= @@ -132,6 +148,12 @@ SECTIONS ${RELOCATING+__rt_psrelocs_start = .;} ${RELOCATING+KEEP(*(.rdata_runtime_pseudo_reloc))} ${RELOCATING+__rt_psrelocs_end = .;} + /* read-only parts of .didat */ + /* This cannot currently be handled with grouped sections. + See pe.em:sort_sections. */ + ${RELOCATING+. = ALIGN(8);} + ${R_DIDAT234} + ${R_DIDAT67} /* .ctors & .dtors */ ${CONSTRUCTING+. = ALIGN(8);} @@ -251,6 +273,13 @@ SECTIONS ${R_IDATA67} } + .didat ${RELOCATING+BLOCK(__section_alignment__)} : + { + /* This cannot currently be handled with grouped sections. + See pep.em:sort_sections. */ + ${R_DIDAT5} + } + /* Windows TLS expects .tls\$AAA to be at the start and .tls\$ZZZ to be at the end of the .tls section. This is important because _tls_start MUST be at the beginning of the section to enable SECREL32 relocations with TLS diff --git a/ld/testsuite/config/default.exp b/ld/testsuite/config/default.exp index 66721ff..1d69681 100644 --- a/ld/testsuite/config/default.exp +++ b/ld/testsuite/config/default.exp @@ -538,10 +538,11 @@ if { [check_compiler_available] } { } } -if {[file exists .libs/libdep.so]} { - set dep_plug_opt "--plugin .libs/libdep.so" -} elseif {[file exists .libs/libdep.dll]} { - set dep_plug_opt "--plugin .libs/libdep.dll" -} else { - set dep_plug_opt "" +set dep_plug_opt "" +if [check_plugin_api_available] { + if {[file exists .libs/libdep.so]} { + set dep_plug_opt "--plugin .libs/libdep.so" + } elseif {[file exists .libs/libdep.dll]} { + set dep_plug_opt "--plugin .libs/libdep.dll" + } } diff --git a/ld/testsuite/ld-aarch64/aarch64.ld b/ld/testsuite/ld-aarch64/aarch64.ld index 75ee3b5..765ddf5 100644 --- a/ld/testsuite/ld-aarch64/aarch64.ld +++ b/ld/testsuite/ld-aarch64/aarch64.ld @@ -3,17 +3,23 @@ OUTPUT_ARCH(aarch64) ENTRY(_start) SECTIONS { - /* Read-only sections, merged into text segment: */ - PROVIDE (__executable_start = 0x8000); . = 0x8000; - .text : + PROVIDE (__executable_start = 0x8000); + . = SEGMENT_START("text-segment", 0x8000) + SIZEOF_HEADERS; + /* Start of the executable code region. */ + . = 0x9000; + .plt : ALIGN(16) { *(.plt) *(.iplt) } + . = 0x10000; + .text : { *(.before) *(.text) *(.after) } =0 - . = 0x9000; - .got : { *(.got) *(.got.plt)} . = 0x12340000; - .far : { *(.far) } - .ARM.attributes 0 : { *(.ARM.atttributes) } + .far : { *(.far) } + /* Start of the Read Write Data region. */ + . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); + .got : { *(.got) *(.got.plt)} + /* Start of the metadata region. */ + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) } } diff --git a/ld/testsuite/ld-aarch64/gc-got-relocs.d b/ld/testsuite/ld-aarch64/gc-got-relocs.d index 6525d10..a1821c3 100644 --- a/ld/testsuite/ld-aarch64/gc-got-relocs.d +++ b/ld/testsuite/ld-aarch64/gc-got-relocs.d @@ -12,15 +12,14 @@ .*: file format elf64-(little|big)aarch64 SYMBOL TABLE: -0+8000 l d \.text 0+ \.text -0+0000 l df \*ABS\* 0+ .* -0+8000 g \.text 0+ _start +0+10000 l d \.text 0+ \.text +0+00000 l df \*ABS\* 0+ .* +0+10000 g \.text 0+ _start Contents of section .text: - 8000 1f2003d5 .* + 10000 1f2003d5 .* -Disassembly of section .text: - -0+8000 \<_start>: - 8000: d503201f nop +Disassembly of section \.text: +0+10000 \<_start>: + 10000: d503201f nop diff --git a/ld/testsuite/ld-aarch64/gc-plt-relocs.d b/ld/testsuite/ld-aarch64/gc-plt-relocs.d index 5c9b5fe..ac455f8 100644 --- a/ld/testsuite/ld-aarch64/gc-plt-relocs.d +++ b/ld/testsuite/ld-aarch64/gc-plt-relocs.d @@ -13,36 +13,36 @@ .*: file format elf64-(little|big)aarch64 DYNAMIC SYMBOL TABLE: -0+8000 g DF \.text 0+4 _start -0+0000 D \*UND\* 0+ foo -0+8008 g DF \.text 0+ bar +0+10000 g DF \.text 0+4 _start +0+00000 D \*UND\* 0+ foo +0+10008 g DF \.text 0+ bar + +Disassembly of section \.plt: + +0+9000 \<\.plt\>: + 9000: a9bf7bf0 stp x16, x30, \[sp, #-16\]! + 9004: f00919b0 adrp x16, 12340000 \<_GLOBAL_OFFSET_TABLE_\> + 9008: f9400e11 ldr x17, \[x16, #24\] + 900c: 91006210 add x16, x16, #0x18 + 9010: d61f0220 br x17 + 9014: d503201f nop + 9018: d503201f nop + 901c: d503201f nop + 9020: f00919b0 adrp x16, 12340000 \<_GLOBAL_OFFSET_TABLE_\> + 9024: f9401211 ldr x17, \[x16, #32\] + 9028: 91008210 add x16, x16, #0x20 + 902c: d61f0220 br x17 Disassembly of section .text: -0+8000 \<_start\>: - 8000: 9400000c bl 8030 \<.*> - -0+8004 \<hidfn\>: - 8004: 8a000000 and x0, x0, x0 - -0+8008 \<bar\>: - 8008: 14000001 b 800c \<foo\> - -0+800c \<foo\>: - 800c: 97fffffe bl 8004 \<hidfn\> - -Disassembly of section .plt: - -0+8010 \<\.plt\>: - 8010: a9bf7bf0 stp x16, x30, \[sp, #-16\]! - 8014: b0000010 adrp x16, 9000 .* - 8018: f9400e11 ldr x17, \[x16, #24\] - 801c: 91006210 add x16, x16, #0x18 - 8020: d61f0220 br x17 - 8024: d503201f nop - 8028: d503201f nop - 802c: d503201f nop - 8030: b0000010 adrp x16, 9000 .* - 8034: f9401211 ldr x17, \[x16, #32\] - 8038: 91008210 add x16, x16, #0x20 - 803c: d61f0220 br x17 +0+10000 \<_start\>: + 10000: 97ffe408 bl 9020 \<\.plt\+0x20> + +0+10004 \<hidfn\>: + 10004: 8a000000 and x0, x0, x0 + +0+10008 \<bar\>: + 10008: 14000001 b 1000c \<foo\> + +0+1000c \<foo\>: + 1000c: 97fffffe bl 10004 \<hidfn\> diff --git a/ld/testsuite/ld-aarch64/gc-relocs-257-dyn.d b/ld/testsuite/ld-aarch64/gc-relocs-257-dyn.d index 56fcfa4..2e5e4c6 100644 --- a/ld/testsuite/ld-aarch64/gc-relocs-257-dyn.d +++ b/ld/testsuite/ld-aarch64/gc-relocs-257-dyn.d @@ -13,5 +13,5 @@ Disassembly of section .text: -0+8000 \<_start\>: - 8000: d503201f nop +0+10000 \<_start\>: + 10000: d503201f nop diff --git a/ld/testsuite/ld-aarch64/gc-relocs-257.d b/ld/testsuite/ld-aarch64/gc-relocs-257.d index ffa7571..022b407 100644 --- a/ld/testsuite/ld-aarch64/gc-relocs-257.d +++ b/ld/testsuite/ld-aarch64/gc-relocs-257.d @@ -12,5 +12,5 @@ Disassembly of section .text: -0+8000 \<_start\>: - 8000: d503201f nop +0+10000 \<_start\>: + 10000: d503201f nop diff --git a/ld/testsuite/ld-aarch64/gc-tls-relocs.d b/ld/testsuite/ld-aarch64/gc-tls-relocs.d index 38637dc..2f2210c 100644 --- a/ld/testsuite/ld-aarch64/gc-tls-relocs.d +++ b/ld/testsuite/ld-aarch64/gc-tls-relocs.d @@ -13,15 +13,15 @@ .*: file format elf64-(little|big)aarch64 SYMBOL TABLE: -0+8000 l d \.text 0+ \.text -0+0000 l df \*ABS\* 0+ .* -0+8000 g \.text 0+ _start +0+10000 l d \.text 0+ \.text +0+00000 l df \*ABS\* 0+ .* +0+10000 g \.text 0+ _start Contents of section .text: - 8000 1f2003d5 .* + 10000 1f2003d5 .* -Disassembly of section .text: +Disassembly of section \.text: -0+8000 \<_start>: - 8000: d503201f nop +0+10000 \<_start>: + 10000: d503201f nop diff --git a/ld/testsuite/ld-aarch64/protections/bti-and-memory-seal-plt-1-a.d b/ld/testsuite/ld-aarch64/protections/bti-and-memory-seal-plt-1-a.d new file mode 100644 index 0000000..7409525 --- /dev/null +++ b/ld/testsuite/ld-aarch64/protections/bti-and-memory-seal-plt-1-a.d @@ -0,0 +1,45 @@ +#name: No '-z force-bti' with '-z memory-seal' with feature properties (BTI) forces the generation of BTI PLT (shared) +#source: bti-plt-1.s +#source: bti-plt-2.s +#target: [check_shared_lib_support] +#as: -mabi=lp64 -defsym __property_bti__=1 +#ld: -shared -z memory-seal -T bti-plt.ld -L./tmpdir -lbti-plt-so +#objdump: -dr -j .plt + +[^:]*: *file format elf64-.*aarch64 + +Disassembly of section \.plt: + +[0-9]+ <\.plt>: +.*: d503245f bti c +.*: a9bf7bf0 stp x16, x30, \[sp, #-16\]! +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> +.*: f9400e11 ldr x17, \[x16, #24\] +.*: 91006210 add x16, x16, #0x18 +.*: d61f0220 br x17 +.*: d503201f nop +.*: d503201f nop + +[0-9]+ <.*>: +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> +.*: f9401211 ldr x17, \[x16, #32\] +.*: 91008210 add x16, x16, #0x20 +.*: d61f0220 br x17 + +[0-9]+ <.*>: +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> +.*: f9401611 ldr x17, \[x16, #40\] +.*: 9100a210 add x16, x16, #0x28 +.*: d61f0220 br x17 + +[0-9]+ <.*>: +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> +.*: f9401a11 ldr x17, \[x16, #48\] +.*: 9100c210 add x16, x16, #0x30 +.*: d61f0220 br x17 + +[0-9]+ <.*>: +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> +.*: f9401e11 ldr x17, \[x16, #56\] +.*: 9100e210 add x16, x16, #0x38 +.*: d61f0220 br x17 diff --git a/ld/testsuite/ld-aarch64/protections/bti-and-memory-seal-plt-1-b.d b/ld/testsuite/ld-aarch64/protections/bti-and-memory-seal-plt-1-b.d new file mode 100644 index 0000000..0dadcc9 --- /dev/null +++ b/ld/testsuite/ld-aarch64/protections/bti-and-memory-seal-plt-1-b.d @@ -0,0 +1,14 @@ +#name: No '-z force-bti' with '-z memory-seal' all input objects have BTI emits BTI feature (shared) +#source: bti-plt-1.s +#source: bti-plt-2.s +#target: [check_shared_lib_support] +#as: -mabi=lp64 -defsym __property_bti__=1 +#ld: -z memory-seal -shared -T bti-plt.ld +#readelf: -n + +Displaying notes found in: .note.gnu.property +[ ]+Owner[ ]+Data size[ ]+Description + GNU 0x00000018 NT_GNU_PROPERTY_TYPE_0 + Properties: memory seal\s +\s+AArch64 feature: BTI +#pass diff --git a/ld/testsuite/ld-aarch64/protections/bti-far-1.d b/ld/testsuite/ld-aarch64/protections/bti-far-1.d index 63fbb43..eb295cf 100644 --- a/ld/testsuite/ld-aarch64/protections/bti-far-1.d +++ b/ld/testsuite/ld-aarch64/protections/bti-far-1.d @@ -13,7 +13,7 @@ Disassembly of section \.plt: 0000000000018000 <\.plt>: 18000: d503245f bti c 18004: a9bf7bf0 stp x16, x30, \[sp, #-16\]! - 18008: 900000d0 adrp x16, 30000 <_GLOBAL_OFFSET_TABLE_> + 18008: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> 1800c: f9400e11 ldr x17, \[x16, #24\] 18010: 91006210 add x16, x16, #0x18 18014: d61f0220 br x17 @@ -21,7 +21,7 @@ Disassembly of section \.plt: 1801c: d503201f nop 0000000000018020 <foo@plt>: - 18020: 900000d0 adrp x16, 30000 <_GLOBAL_OFFSET_TABLE_> + 18020: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> 18024: f9401211 ldr x17, \[x16, #32\] 18028: 91008210 add x16, x16, #0x20 1802c: d61f0220 br x17 diff --git a/ld/testsuite/ld-aarch64/protections/bti-far-opt.d b/ld/testsuite/ld-aarch64/protections/bti-far-opt.d index cb293b6..f5038c0 100644 --- a/ld/testsuite/ld-aarch64/protections/bti-far-opt.d +++ b/ld/testsuite/ld-aarch64/protections/bti-far-opt.d @@ -13,7 +13,7 @@ Disassembly of section \.plt: 0000000000018000 <\.plt>: 18000: d503245f bti c 18004: a9bf7bf0 stp x16, x30, \[sp, #-16\]! - 18008: 900000d0 adrp x16, 30000 <_GLOBAL_OFFSET_TABLE_> + 18008: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> 1800c: f9400e11 ldr x17, \[x16, #24\] 18010: 91006210 add x16, x16, #0x18 18014: d61f0220 br x17 @@ -21,7 +21,7 @@ Disassembly of section \.plt: 1801c: d503201f nop 0000000000018020 <foo@plt>: - 18020: 900000d0 adrp x16, 30000 <_GLOBAL_OFFSET_TABLE_> + 18020: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> 18024: f9401211 ldr x17, \[x16, #32\] 18028: 91008210 add x16, x16, #0x20 1802c: d61f0220 br x17 diff --git a/ld/testsuite/ld-aarch64/protections/bti-far.ld b/ld/testsuite/ld-aarch64/protections/bti-far.ld index 214b8cb..1568f18 100644 --- a/ld/testsuite/ld-aarch64/protections/bti-far.ld +++ b/ld/testsuite/ld-aarch64/protections/bti-far.ld @@ -2,14 +2,28 @@ OUTPUT_ARCH(aarch64) ENTRY(_start) SECTIONS { + PROVIDE(__executable_start = 0x8000); + . = SEGMENT_START("text-segment", 0x8000) + SIZEOF_HEADERS; + /* Start of the executable code region. */ + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } . = 0x10000; - .rela.plt : { *(.rela.plt) *(.rela.iplt) } + .rela.dyn : { *(.rela.ifunc) } + .rela.plt : { *(.rela.plt) *(.rela.iplt) } . = 0x18000; - .plt : { *(.plt) *(.iplt) } + .plt : { *(.plt) *(.iplt) } . = 0x20000; - .text : { *(.text) } - . = 0x30000; - .got : { *(.got) *(.got.plt) } + .text : { *(.text) } . = 0x12340000; - .far : { *(.far) } + .far : { *(.far) } + /* Start of the Read Only Data region. */ + .note.gnu-property : { *(.note.gnu-property) } + + /* Start of the Read Write Data region. */ + . = ALIGN (CONSTANT (MAXPAGESIZE)); + .got : { *(.got) *(.got.plt) } + /* Start of the metadata region. */ + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) } } diff --git a/ld/testsuite/ld-aarch64/protections/bti-pac-plt-1-a.d b/ld/testsuite/ld-aarch64/protections/bti-pac-plt-1-a.d index 96268d3..4ab1ca8 100644 --- a/ld/testsuite/ld-aarch64/protections/bti-pac-plt-1-a.d +++ b/ld/testsuite/ld-aarch64/protections/bti-pac-plt-1-a.d @@ -11,7 +11,7 @@ Disassembly of section \.plt: [0-9a-f]+ <\.plt>: .*: a9bf7bf0 stp x16, x30, \[sp, #-16\]! -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9400e11 ldr x17, \[x16, #24\] .*: 91006210 add x16, x16, #0x18 .*: d61f0220 br x17 @@ -20,13 +20,13 @@ Disassembly of section \.plt: .*: d503201f nop [0-9a-f]+ <.*>: -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401211 ldr x17, \[x16, #32\] .*: 91008210 add x16, x16, #0x20 .*: d61f0220 br x17 [0-9a-f]+ <.*>: -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401611 ldr x17, \[x16, #40\] .*: 9100a210 add x16, x16, #0x28 .*: d61f0220 br x17 diff --git a/ld/testsuite/ld-aarch64/protections/bti-pac-plt-1-b.d b/ld/testsuite/ld-aarch64/protections/bti-pac-plt-1-b.d index 041bf22..ef744e1 100644 --- a/ld/testsuite/ld-aarch64/protections/bti-pac-plt-1-b.d +++ b/ld/testsuite/ld-aarch64/protections/bti-pac-plt-1-b.d @@ -16,7 +16,7 @@ Disassembly of section \.plt: [0-9a-f]+ <\.plt>: .*: d503245f bti c .*: a9bf7bf0 stp x16, x30, \[sp, #-16\]! -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9400e11 ldr x17, \[x16, #24\] .*: 91006210 add x16, x16, #0x18 .*: d61f0220 br x17 @@ -24,13 +24,13 @@ Disassembly of section \.plt: .*: d503201f nop [0-9a-f]+ <.*>: -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401211 ldr x17, \[x16, #32\] .*: 91008210 add x16, x16, #0x20 .*: d61f0220 br x17 [0-9a-f]+ <.*>: -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401611 ldr x17, \[x16, #40\] .*: 9100a210 add x16, x16, #0x28 .*: d61f0220 br x17 diff --git a/ld/testsuite/ld-aarch64/protections/bti-pac-plt-2-a.d b/ld/testsuite/ld-aarch64/protections/bti-pac-plt-2-a.d index f1ae3cd..0e87bcc 100644 --- a/ld/testsuite/ld-aarch64/protections/bti-pac-plt-2-a.d +++ b/ld/testsuite/ld-aarch64/protections/bti-pac-plt-2-a.d @@ -12,7 +12,7 @@ Disassembly of section \.plt: [0-9a-f]+ <\.plt>: .*: d503245f bti c .*: a9bf7bf0 stp x16, x30, \[sp, #-16\]! -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9400e11 ldr x17, \[x16, #24\] .*: 91006210 add x16, x16, #0x18 .*: d61f0220 br x17 @@ -20,7 +20,7 @@ Disassembly of section \.plt: .*: d503201f nop [0-9a-f]+ <.*>: -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401211 ldr x17, \[x16, #32\] .*: 91008210 add x16, x16, #0x20 .*: d503219f autia1716 @@ -28,7 +28,7 @@ Disassembly of section \.plt: .*: d503201f nop [0-9a-f]+ <.*>: -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401611 ldr x17, \[x16, #40\] .*: 9100a210 add x16, x16, #0x28 .*: d503219f autia1716 diff --git a/ld/testsuite/ld-aarch64/protections/bti-pac-plt-2-b.d b/ld/testsuite/ld-aarch64/protections/bti-pac-plt-2-b.d index 69ccaab..199585c 100644 --- a/ld/testsuite/ld-aarch64/protections/bti-pac-plt-2-b.d +++ b/ld/testsuite/ld-aarch64/protections/bti-pac-plt-2-b.d @@ -12,7 +12,7 @@ Disassembly of section \.plt: [0-9]+ <\.plt>: .*: d503245f bti c .*: a9bf7bf0 stp x16, x30, \[sp, #-16\]! -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9400e11 ldr x17, \[x16, #24\] .*: 91006210 add x16, x16, #0x18 .*: d61f0220 br x17 @@ -21,7 +21,7 @@ Disassembly of section \.plt: [0-9]+ <.*>: .*: d503245f bti c -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401211 ldr x17, \[x16, #32\] .*: 91008210 add x16, x16, #0x20 .*: d503219f autia1716 @@ -29,7 +29,7 @@ Disassembly of section \.plt: [0-9]+ <.*>: .*: d503245f bti c -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401611 ldr x17, \[x16, #40\] .*: 9100a210 add x16, x16, #0x28 .*: d503219f autia1716 diff --git a/ld/testsuite/ld-aarch64/protections/bti-pac-plt-3-a.d b/ld/testsuite/ld-aarch64/protections/bti-pac-plt-3-a.d index c0c0bdb..1789a98 100644 --- a/ld/testsuite/ld-aarch64/protections/bti-pac-plt-3-a.d +++ b/ld/testsuite/ld-aarch64/protections/bti-pac-plt-3-a.d @@ -12,7 +12,7 @@ Disassembly of section \.plt: [0-9a-f]+ <\.plt>: .*: d503245f bti c .*: a9bf7bf0 stp x16, x30, \[sp, #-16\]! -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9400e11 ldr x17, \[x16, #24\] .*: 91006210 add x16, x16, #0x18 .*: d61f0220 br x17 @@ -20,7 +20,7 @@ Disassembly of section \.plt: .*: d503201f nop [0-9a-f]+ <.*>: -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401211 ldr x17, \[x16, #32\] .*: 91008210 add x16, x16, #0x20 .*: d503219f autia1716 @@ -28,7 +28,7 @@ Disassembly of section \.plt: .*: d503201f nop [0-9a-f]+ <.*>: -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401611 ldr x17, \[x16, #40\] .*: 9100a210 add x16, x16, #0x28 .*: d503219f autia1716 diff --git a/ld/testsuite/ld-aarch64/protections/bti-pac-plt-3-b.d b/ld/testsuite/ld-aarch64/protections/bti-pac-plt-3-b.d index 89a08ae..a0643ab 100644 --- a/ld/testsuite/ld-aarch64/protections/bti-pac-plt-3-b.d +++ b/ld/testsuite/ld-aarch64/protections/bti-pac-plt-3-b.d @@ -12,7 +12,7 @@ Disassembly of section \.plt: [0-9]+ <\.plt>: .*: d503245f bti c .*: a9bf7bf0 stp x16, x30, \[sp, #-16\]! -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9400e11 ldr x17, \[x16, #24\] .*: 91006210 add x16, x16, #0x18 .*: d61f0220 br x17 @@ -21,7 +21,7 @@ Disassembly of section \.plt: [0-9]+ <.*>: .*: d503245f bti c -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401211 ldr x17, \[x16, #32\] .*: 91008210 add x16, x16, #0x20 .*: d503219f autia1716 @@ -29,7 +29,7 @@ Disassembly of section \.plt: [0-9]+ <.*>: .*: d503245f bti c -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401611 ldr x17, \[x16, #40\] .*: 9100a210 add x16, x16, #0x28 .*: d503219f autia1716 diff --git a/ld/testsuite/ld-aarch64/protections/bti-plt-1-a.d b/ld/testsuite/ld-aarch64/protections/bti-plt-1-a.d index 2dc3864..89c0abc 100644 --- a/ld/testsuite/ld-aarch64/protections/bti-plt-1-a.d +++ b/ld/testsuite/ld-aarch64/protections/bti-plt-1-a.d @@ -12,7 +12,7 @@ Disassembly of section \.plt: [0-9]+ <\.plt>: .*: d503245f bti c .*: a9bf7bf0 stp x16, x30, \[sp, #-16\]! -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9400e11 ldr x17, \[x16, #24\] .*: 91006210 add x16, x16, #0x18 .*: d61f0220 br x17 @@ -20,13 +20,13 @@ Disassembly of section \.plt: .*: d503201f nop [0-9]+ <.*>: -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401211 ldr x17, \[x16, #32\] .*: 91008210 add x16, x16, #0x20 .*: d61f0220 br x17 [0-9]+ <.*>: -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401611 ldr x17, \[x16, #40\] .*: 9100a210 add x16, x16, #0x28 .*: d61f0220 br x17 diff --git a/ld/testsuite/ld-aarch64/protections/bti-plt-1-b.d b/ld/testsuite/ld-aarch64/protections/bti-plt-1-b.d index 1bf956c..c889c1c 100644 --- a/ld/testsuite/ld-aarch64/protections/bti-plt-1-b.d +++ b/ld/testsuite/ld-aarch64/protections/bti-plt-1-b.d @@ -2,7 +2,7 @@ #source: bti-plt-1.s #target: [check_shared_lib_support] #as: -mabi=lp64 -defsym __property_bti__=1 -#ld: -shared -z force-bti -T bti-plt.ld -L./tmpdir -lbti-plt-so +#ld: -shared -T bti-plt.ld -L./tmpdir -lbti-plt-so #objdump: -dr -j .plt [^:]*: *file format elf64-.*aarch64 @@ -12,7 +12,7 @@ Disassembly of section \.plt: [0-9]+ <\.plt>: .*: d503245f bti c .*: a9bf7bf0 stp x16, x30, \[sp, #-16\]! -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9400e11 ldr x17, \[x16, #24\] .*: 91006210 add x16, x16, #0x18 .*: d61f0220 br x17 @@ -20,13 +20,13 @@ Disassembly of section \.plt: .*: d503201f nop [0-9]+ <.*>: -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401211 ldr x17, \[x16, #32\] .*: 91008210 add x16, x16, #0x20 .*: d61f0220 br x17 [0-9]+ <.*>: -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401611 ldr x17, \[x16, #40\] .*: 9100a210 add x16, x16, #0x28 .*: d61f0220 br x17 diff --git a/ld/testsuite/ld-aarch64/protections/bti-plt-1-c.d b/ld/testsuite/ld-aarch64/protections/bti-plt-1-c.d index 2fd0dea..c200b0c 100644 --- a/ld/testsuite/ld-aarch64/protections/bti-plt-1-c.d +++ b/ld/testsuite/ld-aarch64/protections/bti-plt-1-c.d @@ -13,7 +13,7 @@ Disassembly of section \.plt: [0-9]+ <\.plt>: .*: d503245f bti c .*: a9bf7bf0 stp x16, x30, \[sp, #-16\]! -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9400e11 ldr x17, \[x16, #24\] .*: 91006210 add x16, x16, #0x18 .*: d61f0220 br x17 @@ -21,13 +21,13 @@ Disassembly of section \.plt: .*: d503201f nop [0-9]+ <.*>: -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401211 ldr x17, \[x16, #32\] .*: 91008210 add x16, x16, #0x20 .*: d61f0220 br x17 [0-9]+ <.*>: -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401611 ldr x17, \[x16, #40\] .*: 9100a210 add x16, x16, #0x28 .*: d61f0220 br x17 diff --git a/ld/testsuite/ld-aarch64/protections/bti-plt-3.d b/ld/testsuite/ld-aarch64/protections/bti-plt-3.d index e457bab..48db434 100644 --- a/ld/testsuite/ld-aarch64/protections/bti-plt-3.d +++ b/ld/testsuite/ld-aarch64/protections/bti-plt-3.d @@ -12,7 +12,7 @@ Disassembly of section \.plt: [0-9]+ <\.plt>: .*: d503245f bti c .*: a9bf7bf0 stp x16, x30, \[sp, #-16\]! -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9400e11 ldr x17, \[x16, #24\] .*: 91006210 add x16, x16, #0x18 .*: d61f0220 br x17 @@ -21,7 +21,7 @@ Disassembly of section \.plt: [0-9]+ <.*>: .*: d503245f bti c -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401211 ldr x17, \[x16, #32\] .*: 91008210 add x16, x16, #0x20 .*: d61f0220 br x17 @@ -29,7 +29,7 @@ Disassembly of section \.plt: [0-9]+ <.*>: .*: d503245f bti c -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401611 ldr x17, \[x16, #40\] .*: 9100a210 add x16, x16, #0x28 .*: d61f0220 br x17 diff --git a/ld/testsuite/ld-aarch64/protections/bti-plt.ld b/ld/testsuite/ld-aarch64/protections/bti-plt.ld index 8682623..c930fc8 100644 --- a/ld/testsuite/ld-aarch64/protections/bti-plt.ld +++ b/ld/testsuite/ld-aarch64/protections/bti-plt.ld @@ -2,13 +2,26 @@ OUTPUT_ARCH(aarch64) ENTRY(_start) SECTIONS { + PROVIDE(__executable_start = 0x8000); + . = SEGMENT_START("text-segment", 0x8000) + SIZEOF_HEADERS; + /* Start of the executable code region. */ + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } . = 0x10000; - .rela.plt : { *(.rela.plt) *(.rela.iplt) } + .rela.dyn : { *(.rela.ifunc) } + .rela.plt : { *(.rela.plt) *(.rela.iplt) } . = 0x18000; - .plt : { *(.plt) *(.iplt) } + .plt : { *(.plt) *(.iplt) } . = 0x20000; - .text : { *(.text) } - . = 0x28000; - .got : { *(.got) *(.got.plt) } - .ARM.attributes 0 : { *(.ARM.atttributes) } + .text : { *(.text) } + /* Start of the Read Only Data region. */ + .note.gnu-property : { *(.note.gnu-property) } + + /* Start of the Read Write Data region. */ + . = ALIGN (CONSTANT (MAXPAGESIZE)); + .got : { *(.got) *(.got.plt) } + /* Start of the metadata region. */ + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) } } diff --git a/ld/testsuite/ld-aarch64/protections/pac-plt-1-a.d b/ld/testsuite/ld-aarch64/protections/pac-plt-1-a.d index fc10ec7..203cb12 100644 --- a/ld/testsuite/ld-aarch64/protections/pac-plt-1-a.d +++ b/ld/testsuite/ld-aarch64/protections/pac-plt-1-a.d @@ -11,7 +11,7 @@ Disassembly of section \.plt: [0-9]+ <.*>: .*: a9bf7bf0 stp x16, x30, \[sp, #-16\]! -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9400e11 ldr x17, \[x16, #24\] .*: 91006210 add x16, x16, #0x18 .*: d61f0220 br x17 @@ -20,7 +20,7 @@ Disassembly of section \.plt: .*: d503201f nop [0-9]+ <.*>: -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401211 ldr x17, \[x16, #32\] .*: 91008210 add x16, x16, #0x20 .*: d503219f autia1716 @@ -28,7 +28,7 @@ Disassembly of section \.plt: .*: d503201f nop [0-9]+ <.*>: -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401611 ldr x17, \[x16, #40\] .*: 9100a210 add x16, x16, #0x28 .*: d503219f autia1716 diff --git a/ld/testsuite/ld-aarch64/protections/pac-plt-1-b.d b/ld/testsuite/ld-aarch64/protections/pac-plt-1-b.d index 7a0fd59..6592689 100644 --- a/ld/testsuite/ld-aarch64/protections/pac-plt-1-b.d +++ b/ld/testsuite/ld-aarch64/protections/pac-plt-1-b.d @@ -15,7 +15,7 @@ Disassembly of section \.plt: [0-9a-f]+ <\.plt>: .*: a9bf7bf0 stp x16, x30, \[sp, #-16\]! -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9400e11 ldr x17, \[x16, #24\] .*: 91006210 add x16, x16, #0x18 .*: d61f0220 br x17 @@ -24,13 +24,13 @@ Disassembly of section \.plt: .*: d503201f nop [0-9a-f]+ <.*>: -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401211 ldr x17, \[x16, #32\] .*: 91008210 add x16, x16, #0x20 .*: d61f0220 br x17 [0-9a-f]+ <.*>: -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401611 ldr x17, \[x16, #40\] .*: 9100a210 add x16, x16, #0x28 .*: d61f0220 br x17 diff --git a/ld/testsuite/ld-aarch64/protections/pac-plt-2.d b/ld/testsuite/ld-aarch64/protections/pac-plt-2.d index 1c3d7f4..6795645 100644 --- a/ld/testsuite/ld-aarch64/protections/pac-plt-2.d +++ b/ld/testsuite/ld-aarch64/protections/pac-plt-2.d @@ -9,7 +9,7 @@ Disassembly of section \.plt: .* \<.plt\>: .*: a9bf7bf0 stp x16, x30, \[sp, #-16\]! -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401a11 ldr x17, \[x16, #48\] .*: 9100c210 add x16, x16, #0x30 .*: d61f0220 br x17 @@ -19,7 +19,7 @@ Disassembly of section \.plt: .* \<__tls_get_addr@plt\>: -.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_> +.*: [[:xdigit:]]{8} adrp x16, [[:xdigit:]]+ <_GLOBAL_OFFSET_TABLE_> .*: f9401e11 ldr x17, \[x16, #56\] .*: 9100e210 add x16, x16, #0x38 .*: d503219f autia1716 diff --git a/ld/testsuite/ld-aarch64/relocs-ilp32.ld b/ld/testsuite/ld-aarch64/relocs-ilp32.ld index 4ddba91..3958ad8 100644 --- a/ld/testsuite/ld-aarch64/relocs-ilp32.ld +++ b/ld/testsuite/ld-aarch64/relocs-ilp32.ld @@ -15,7 +15,7 @@ SECTIONS .got : { *(.got) *(.got.plt)} . = 0x12340000; .far : { *(.far) } - .ARM.attributes 0 : { *(.ARM.atttributes) } + .ARM.attributes 0 : { *(.ARM.attributes) } /* Providing a .data section triggers a non-executable segment to be generated, which gives somewhere else for the linker to put the TLS segment without creating a RWX permissioned one. */ diff --git a/ld/testsuite/ld-aarch64/relocs.ld b/ld/testsuite/ld-aarch64/relocs.ld index 77adac8..b0e75e0 100644 --- a/ld/testsuite/ld-aarch64/relocs.ld +++ b/ld/testsuite/ld-aarch64/relocs.ld @@ -15,7 +15,7 @@ SECTIONS .got : { *(.got) *(.got.plt)} . = 0x12340000; .far : { *(.far) } - .ARM.attributes 0 : { *(.ARM.atttributes) } + .ARM.attributes 0 : { *(.ARM.attributes) } /* Providing a .data section triggers a non-executable segment to be generated, which gives somewhere else for the linker to put the TLS segment without creating a RWX permissioned one. */ diff --git a/ld/testsuite/ld-aarch64/variant_pcs-now.d b/ld/testsuite/ld-aarch64/variant_pcs-now.d index 5007632..1add2bb 100644 --- a/ld/testsuite/ld-aarch64/variant_pcs-now.d +++ b/ld/testsuite/ld-aarch64/variant_pcs-now.d @@ -4,65 +4,65 @@ #ld: -shared --hash-style=sysv -T variant_pcs.ld -z now #readelf: -rsW -Relocation section '\.rela\.plt' at offset 0x11000 contains 12 entries: +Relocation section '\.rela\.plt' at offset 0x[[:xdigit:]]+ contains 12 entries: Offset Info Type Symbol's Value Symbol's Name \+ Addend -0000000000009020 0000000100000402 R_AARCH64_JUMP_SLOT 0000000000000000 f_base_global_default_undef \+ 0 -0000000000009028 0000000200000402 R_AARCH64_JUMP_SLOT 0000000000000000 f_spec_global_default_undef \+ 0 -0000000000009030 0000000400000402 R_AARCH64_JUMP_SLOT 0000000000008000 f_base_global_default_def \+ 0 -0000000000009038 0000000500000402 R_AARCH64_JUMP_SLOT 0000000000008000 f_spec_global_default_def \+ 0 -0000000000009040 0000000000000408 R_AARCH64_IRELATIVE 8000 -0000000000009048 0000000300000402 R_AARCH64_JUMP_SLOT f_spec_global_default_ifunc\(\) f_spec_global_default_ifunc \+ 0 -0000000000009050 0000000000000408 R_AARCH64_IRELATIVE 8000 -0000000000009058 0000000600000402 R_AARCH64_JUMP_SLOT f_base_global_default_ifunc\(\) f_base_global_default_ifunc \+ 0 -0000000000009060 0000000000000408 R_AARCH64_IRELATIVE 8038 -0000000000009068 0000000000000408 R_AARCH64_IRELATIVE 8000 -0000000000009070 0000000000000408 R_AARCH64_IRELATIVE 8000 -0000000000009078 0000000000000408 R_AARCH64_IRELATIVE 8038 +00000000000[[:xdigit:]]{2}020 0000000100000402 R_AARCH64_JUMP_SLOT 0000000000000000 f_base_global_default_undef \+ 0 +00000000000[[:xdigit:]]{2}028 0000000200000402 R_AARCH64_JUMP_SLOT 0000000000000000 f_spec_global_default_undef \+ 0 +00000000000[[:xdigit:]]{2}030 0000000400000402 R_AARCH64_JUMP_SLOT 0000000000011000 f_base_global_default_def \+ 0 +00000000000[[:xdigit:]]{2}038 0000000500000402 R_AARCH64_JUMP_SLOT 0000000000011000 f_spec_global_default_def \+ 0 +00000000000[[:xdigit:]]{2}040 0000000000000408 R_AARCH64_IRELATIVE 11000 +00000000000[[:xdigit:]]{2}048 0000000300000402 R_AARCH64_JUMP_SLOT f_spec_global_default_ifunc\(\) f_spec_global_default_ifunc \+ 0 +00000000000[[:xdigit:]]{2}050 0000000000000408 R_AARCH64_IRELATIVE 11000 +00000000000[[:xdigit:]]{2}058 0000000600000402 R_AARCH64_JUMP_SLOT f_base_global_default_ifunc\(\) f_base_global_default_ifunc \+ 0 +00000000000[[:xdigit:]]{2}060 0000000000000408 R_AARCH64_IRELATIVE 11038 +00000000000[[:xdigit:]]{2}068 0000000000000408 R_AARCH64_IRELATIVE 11000 +00000000000[[:xdigit:]]{2}070 0000000000000408 R_AARCH64_IRELATIVE 11000 +00000000000[[:xdigit:]]{2}078 0000000000000408 R_AARCH64_IRELATIVE 11038 Symbol table '\.dynsym' contains 7 entries: Num: Value Size Type Bind Vis Ndx Name - 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND + 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND\s 1: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND f_base_global_default_undef 2: 0000000000000000 0 NOTYPE GLOBAL DEFAULT \[VARIANT_PCS\] UND f_spec_global_default_undef - 3: 0000000000008000 0 IFUNC GLOBAL DEFAULT \[VARIANT_PCS\] 1 f_spec_global_default_ifunc - 4: 0000000000008000 0 NOTYPE GLOBAL DEFAULT 1 f_base_global_default_def - 5: 0000000000008000 0 NOTYPE GLOBAL DEFAULT \[VARIANT_PCS\] 1 f_spec_global_default_def - 6: 0000000000008000 0 IFUNC GLOBAL DEFAULT 1 f_base_global_default_ifunc + 3: 0000000000011000 0 IFUNC GLOBAL DEFAULT \[VARIANT_PCS\] 6 f_spec_global_default_ifunc + 4: 0000000000011000 0 NOTYPE GLOBAL DEFAULT 6 f_base_global_default_def + 5: 0000000000011000 0 NOTYPE GLOBAL DEFAULT \[VARIANT_PCS\] 6 f_spec_global_default_def + 6: 0000000000011000 0 IFUNC GLOBAL DEFAULT 6 f_base_global_default_ifunc Symbol table '\.symtab' contains 35 entries: Num: Value Size Type Bind Vis Ndx Name - 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND - 1: 0000000000008000 0 SECTION LOCAL DEFAULT 1.* - 2: 0000000000008070 0 SECTION LOCAL DEFAULT 2.* - 3: 0000000000009000 0 SECTION LOCAL DEFAULT 3.* - 4: 0000000000009080 0 SECTION LOCAL DEFAULT 4.* - 5: 0000000000011000 0 SECTION LOCAL DEFAULT 5.* - 6: 0000000000011120 0 SECTION LOCAL DEFAULT 6.* - 7: 00000000000111c8 0 SECTION LOCAL DEFAULT 7.* - 8: 0000000000011270 0 SECTION LOCAL DEFAULT 8.* + 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND\s + 1: 00000000000080e8 0 SECTION LOCAL DEFAULT 1 \.hash + 2: 0000000000008118 0 SECTION LOCAL DEFAULT 2 \.dynsym + 3: 00000000000081c0 0 SECTION LOCAL DEFAULT 3 \.dynstr + 4: 0000000000009000 0 SECTION LOCAL DEFAULT 4 \.rela\.plt + 5: 0000000000010000 0 SECTION LOCAL DEFAULT 5 \.plt + 6: 0000000000011000 0 SECTION LOCAL DEFAULT 6 \.text + 7: 0000000000020000 0 SECTION LOCAL DEFAULT 7 \.dynamic + 8: 0000000000021000 0 SECTION LOCAL DEFAULT 8 \.got 9: 0000000000000000 0 FILE LOCAL DEFAULT ABS .*variant_pcs-1\.o - 10: 0000000000008000 0 NOTYPE LOCAL DEFAULT \[VARIANT_PCS\] 1 f_spec_local - 11: 0000000000008000 0 IFUNC LOCAL DEFAULT \[VARIANT_PCS\] 1 f_spec_local_ifunc - 12: 0000000000008000 0 IFUNC LOCAL DEFAULT 1 f_base_local_ifunc - 13: 0000000000008000 0 NOTYPE LOCAL DEFAULT 1 f_base_local - 14: 0000000000008000 0 NOTYPE LOCAL DEFAULT 1 \$x + 10: 0000000000011000 0 NOTYPE LOCAL DEFAULT \[VARIANT_PCS\] 6 f_spec_local + 11: 0000000000011000 0 IFUNC LOCAL DEFAULT \[VARIANT_PCS\] 6 f_spec_local_ifunc + 12: 0000000000011000 0 IFUNC LOCAL DEFAULT 6 f_base_local_ifunc + 13: 0000000000011000 0 NOTYPE LOCAL DEFAULT 6 f_base_local + 14: 0000000000011000 0 NOTYPE LOCAL DEFAULT 6 \$x 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS .*variant_pcs-2\.o - 16: 0000000000008038 0 NOTYPE LOCAL DEFAULT \[VARIANT_PCS\] 1 f_spec_local2 - 17: 0000000000008038 0 IFUNC LOCAL DEFAULT \[VARIANT_PCS\] 1 f_spec_local2_ifunc - 18: 0000000000008038 0 IFUNC LOCAL DEFAULT 1 f_base_local2_ifunc - 19: 0000000000008038 0 NOTYPE LOCAL DEFAULT 1 f_base_local2 - 20: 0000000000008038 0 NOTYPE LOCAL DEFAULT 1 \$x - 21: 0000000000000000 0 FILE LOCAL DEFAULT ABS - 22: 0000000000009080 0 OBJECT LOCAL DEFAULT ABS _DYNAMIC - 23: 0000000000008000 0 NOTYPE LOCAL DEFAULT \[VARIANT_PCS\] 1 f_spec_global_hidden_def - 24: 0000000000008000 0 IFUNC LOCAL DEFAULT 1 f_base_global_hidden_ifunc - 25: 0000000000008000 0 NOTYPE LOCAL DEFAULT 1 f_base_global_hidden_def - 26: 0000000000009000 0 OBJECT LOCAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_ - 27: 0000000000008000 0 IFUNC LOCAL DEFAULT \[VARIANT_PCS\] 1 f_spec_global_hidden_ifunc - 28: 0000000000008070 0 NOTYPE LOCAL DEFAULT 2 \$x + 16: 0000000000011038 0 NOTYPE LOCAL DEFAULT \[VARIANT_PCS\] 6 f_spec_local2 + 17: 0000000000011038 0 IFUNC LOCAL DEFAULT \[VARIANT_PCS\] 6 f_spec_local2_ifunc + 18: 0000000000011038 0 IFUNC LOCAL DEFAULT 6 f_base_local2_ifunc + 19: 0000000000011038 0 NOTYPE LOCAL DEFAULT 6 f_base_local2 + 20: 0000000000011038 0 NOTYPE LOCAL DEFAULT 6 \$x + 21: 0000000000000000 0 FILE LOCAL DEFAULT ABS\s + 22: 0000000000020000 0 OBJECT LOCAL DEFAULT ABS _DYNAMIC + 23: 0000000000011000 0 NOTYPE LOCAL DEFAULT \[VARIANT_PCS\] 6 f_spec_global_hidden_def + 24: 0000000000011000 0 IFUNC LOCAL DEFAULT 6 f_base_global_hidden_ifunc + 25: 0000000000011000 0 NOTYPE LOCAL DEFAULT 6 f_base_global_hidden_def + 26: 0000000000021000 0 OBJECT LOCAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_ + 27: 0000000000011000 0 IFUNC LOCAL DEFAULT \[VARIANT_PCS\] 6 f_spec_global_hidden_ifunc + 28: 0000000000010000 0 NOTYPE LOCAL DEFAULT 5 \$x 29: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND f_base_global_default_undef 30: 0000000000000000 0 NOTYPE GLOBAL DEFAULT \[VARIANT_PCS\] UND f_spec_global_default_undef - 31: 0000000000008000 0 IFUNC GLOBAL DEFAULT \[VARIANT_PCS\] 1 f_spec_global_default_ifunc - 32: 0000000000008000 0 NOTYPE GLOBAL DEFAULT 1 f_base_global_default_def - 33: 0000000000008000 0 NOTYPE GLOBAL DEFAULT \[VARIANT_PCS\] 1 f_spec_global_default_def - 34: 0000000000008000 0 IFUNC GLOBAL DEFAULT 1 f_base_global_default_ifunc + 31: 0000000000011000 0 IFUNC GLOBAL DEFAULT \[VARIANT_PCS\] 6 f_spec_global_default_ifunc + 32: 0000000000011000 0 NOTYPE GLOBAL DEFAULT 6 f_base_global_default_def + 33: 0000000000011000 0 NOTYPE GLOBAL DEFAULT \[VARIANT_PCS\] 6 f_spec_global_default_def + 34: 0000000000011000 0 IFUNC GLOBAL DEFAULT 6 f_base_global_default_ifunc diff --git a/ld/testsuite/ld-aarch64/variant_pcs-r.d b/ld/testsuite/ld-aarch64/variant_pcs-r.d index 2651a68..65849e1 100644 --- a/ld/testsuite/ld-aarch64/variant_pcs-r.d +++ b/ld/testsuite/ld-aarch64/variant_pcs-r.d @@ -3,7 +3,7 @@ #ld: -r #readelf: -rsW -Relocation section '\.rela\.text' at offset .* contains 24 entries: +Relocation section '\.rela\.text' at offset 0x[[:xdigit:]]+ contains 24 entries: Offset Info Type Symbol's Value Symbol's Name \+ Addend 0000000000000000 000000180000011b R_AARCH64_CALL26 0000000000000000 f_spec_global_default_def \+ 0 0000000000000004 000000110000011b R_AARCH64_CALL26 0000000000000000 f_spec_global_default_undef \+ 0 @@ -32,10 +32,10 @@ Relocation section '\.rela\.text' at offset .* contains 24 entries: Symbol table '\.symtab' contains 26 entries: Num: Value Size Type Bind Vis Ndx Name - 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND - 1: 0000000000000000 0 SECTION LOCAL DEFAULT 1.* - 2: 0000000000000000 0 SECTION LOCAL DEFAULT 3.* - 3: 0000000000000000 0 SECTION LOCAL DEFAULT 4.* + 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND\s + 1: 0000000000000000 0 SECTION LOCAL DEFAULT 1 \.text + 2: 0000000000000000 0 SECTION LOCAL DEFAULT 3 \.data + 3: 0000000000000000 0 SECTION LOCAL DEFAULT 4 \.bss 4: 0000000000000000 0 FILE LOCAL DEFAULT ABS .*variant_pcs-1\.o 5: 0000000000000000 0 NOTYPE LOCAL DEFAULT \[VARIANT_PCS\] 1 f_spec_local 6: 0000000000000000 0 IFUNC LOCAL DEFAULT \[VARIANT_PCS\] 1 f_spec_local_ifunc diff --git a/ld/testsuite/ld-aarch64/variant_pcs-shared.d b/ld/testsuite/ld-aarch64/variant_pcs-shared.d index e021799..3a39d8c 100644 --- a/ld/testsuite/ld-aarch64/variant_pcs-shared.d +++ b/ld/testsuite/ld-aarch64/variant_pcs-shared.d @@ -4,65 +4,65 @@ #ld: -shared --hash-style=sysv -T variant_pcs.ld #readelf: -rsW -Relocation section '\.rela\.plt' at offset 0x11000 contains 12 entries: +Relocation section '\.rela\.plt' at offset 0x[[:xdigit:]]+ contains 12 entries: Offset Info Type Symbol's Value Symbol's Name \+ Addend -0000000000009020 0000000100000402 R_AARCH64_JUMP_SLOT 0000000000000000 f_base_global_default_undef \+ 0 -0000000000009028 0000000200000402 R_AARCH64_JUMP_SLOT 0000000000000000 f_spec_global_default_undef \+ 0 -0000000000009030 0000000400000402 R_AARCH64_JUMP_SLOT 0000000000008000 f_base_global_default_def \+ 0 -0000000000009038 0000000500000402 R_AARCH64_JUMP_SLOT 0000000000008000 f_spec_global_default_def \+ 0 -0000000000009040 0000000000000408 R_AARCH64_IRELATIVE 8000 -0000000000009048 0000000300000402 R_AARCH64_JUMP_SLOT f_spec_global_default_ifunc\(\) f_spec_global_default_ifunc \+ 0 -0000000000009050 0000000000000408 R_AARCH64_IRELATIVE 8000 -0000000000009058 0000000600000402 R_AARCH64_JUMP_SLOT f_base_global_default_ifunc\(\) f_base_global_default_ifunc \+ 0 -0000000000009060 0000000000000408 R_AARCH64_IRELATIVE 8038 -0000000000009068 0000000000000408 R_AARCH64_IRELATIVE 8000 -0000000000009070 0000000000000408 R_AARCH64_IRELATIVE 8000 -0000000000009078 0000000000000408 R_AARCH64_IRELATIVE 8038 +00000000000[[:xdigit:]]{2}020 0000000100000402 R_AARCH64_JUMP_SLOT 0000000000000000 f_base_global_default_undef \+ 0 +00000000000[[:xdigit:]]{2}028 0000000200000402 R_AARCH64_JUMP_SLOT 0000000000000000 f_spec_global_default_undef \+ 0 +00000000000[[:xdigit:]]{2}030 0000000400000402 R_AARCH64_JUMP_SLOT 0000000000011000 f_base_global_default_def \+ 0 +00000000000[[:xdigit:]]{2}038 0000000500000402 R_AARCH64_JUMP_SLOT 0000000000011000 f_spec_global_default_def \+ 0 +00000000000[[:xdigit:]]{2}040 0000000000000408 R_AARCH64_IRELATIVE 11000 +00000000000[[:xdigit:]]{2}048 0000000300000402 R_AARCH64_JUMP_SLOT f_spec_global_default_ifunc\(\) f_spec_global_default_ifunc \+ 0 +00000000000[[:xdigit:]]{2}050 0000000000000408 R_AARCH64_IRELATIVE 11000 +00000000000[[:xdigit:]]{2}058 0000000600000402 R_AARCH64_JUMP_SLOT f_base_global_default_ifunc\(\) f_base_global_default_ifunc \+ 0 +00000000000[[:xdigit:]]{2}060 0000000000000408 R_AARCH64_IRELATIVE 11038 +00000000000[[:xdigit:]]{2}068 0000000000000408 R_AARCH64_IRELATIVE 11000 +00000000000[[:xdigit:]]{2}070 0000000000000408 R_AARCH64_IRELATIVE 11000 +00000000000[[:xdigit:]]{2}078 0000000000000408 R_AARCH64_IRELATIVE 11038 Symbol table '\.dynsym' contains 7 entries: Num: Value Size Type Bind Vis Ndx Name - 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND + 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND\s 1: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND f_base_global_default_undef 2: 0000000000000000 0 NOTYPE GLOBAL DEFAULT \[VARIANT_PCS\] UND f_spec_global_default_undef - 3: 0000000000008000 0 IFUNC GLOBAL DEFAULT \[VARIANT_PCS\] 1 f_spec_global_default_ifunc - 4: 0000000000008000 0 NOTYPE GLOBAL DEFAULT 1 f_base_global_default_def - 5: 0000000000008000 0 NOTYPE GLOBAL DEFAULT \[VARIANT_PCS\] 1 f_spec_global_default_def - 6: 0000000000008000 0 IFUNC GLOBAL DEFAULT 1 f_base_global_default_ifunc + 3: 0000000000011000 0 IFUNC GLOBAL DEFAULT \[VARIANT_PCS\] 6 f_spec_global_default_ifunc + 4: 0000000000011000 0 NOTYPE GLOBAL DEFAULT 6 f_base_global_default_def + 5: 0000000000011000 0 NOTYPE GLOBAL DEFAULT \[VARIANT_PCS\] 6 f_spec_global_default_def + 6: 0000000000011000 0 IFUNC GLOBAL DEFAULT 6 f_base_global_default_ifunc Symbol table '\.symtab' contains 35 entries: Num: Value Size Type Bind Vis Ndx Name - 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND - 1: 0000000000008000 0 SECTION LOCAL DEFAULT 1.* - 2: 0000000000008070 0 SECTION LOCAL DEFAULT 2.* - 3: 0000000000009000 0 SECTION LOCAL DEFAULT 3.* - 4: 0000000000009080 0 SECTION LOCAL DEFAULT 4.* - 5: 0000000000011000 0 SECTION LOCAL DEFAULT 5.* - 6: 0000000000011120 0 SECTION LOCAL DEFAULT 6.* - 7: 00000000000111c8 0 SECTION LOCAL DEFAULT 7.* - 8: 0000000000011270 0 SECTION LOCAL DEFAULT 8.* + 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND\s + 1: 00000000000080e8 0 SECTION LOCAL DEFAULT 1 \.hash + 2: 0000000000008118 0 SECTION LOCAL DEFAULT 2 \.dynsym + 3: 00000000000081c0 0 SECTION LOCAL DEFAULT 3 \.dynstr + 4: 0000000000009000 0 SECTION LOCAL DEFAULT 4 \.rela\.plt + 5: 0000000000010000 0 SECTION LOCAL DEFAULT 5 \.plt + 6: 0000000000011000 0 SECTION LOCAL DEFAULT 6 \.text + 7: 0000000000020000 0 SECTION LOCAL DEFAULT 7 \.dynamic + 8: 0000000000021000 0 SECTION LOCAL DEFAULT 8 \.got 9: 0000000000000000 0 FILE LOCAL DEFAULT ABS .*variant_pcs-1\.o - 10: 0000000000008000 0 NOTYPE LOCAL DEFAULT \[VARIANT_PCS\] 1 f_spec_local - 11: 0000000000008000 0 IFUNC LOCAL DEFAULT \[VARIANT_PCS\] 1 f_spec_local_ifunc - 12: 0000000000008000 0 IFUNC LOCAL DEFAULT 1 f_base_local_ifunc - 13: 0000000000008000 0 NOTYPE LOCAL DEFAULT 1 f_base_local - 14: 0000000000008000 0 NOTYPE LOCAL DEFAULT 1 \$x + 10: 0000000000011000 0 NOTYPE LOCAL DEFAULT \[VARIANT_PCS\] 6 f_spec_local + 11: 0000000000011000 0 IFUNC LOCAL DEFAULT \[VARIANT_PCS\] 6 f_spec_local_ifunc + 12: 0000000000011000 0 IFUNC LOCAL DEFAULT 6 f_base_local_ifunc + 13: 0000000000011000 0 NOTYPE LOCAL DEFAULT 6 f_base_local + 14: 0000000000011000 0 NOTYPE LOCAL DEFAULT 6 \$x 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS .*variant_pcs-2\.o - 16: 0000000000008038 0 NOTYPE LOCAL DEFAULT \[VARIANT_PCS\] 1 f_spec_local2 - 17: 0000000000008038 0 IFUNC LOCAL DEFAULT \[VARIANT_PCS\] 1 f_spec_local2_ifunc - 18: 0000000000008038 0 IFUNC LOCAL DEFAULT 1 f_base_local2_ifunc - 19: 0000000000008038 0 NOTYPE LOCAL DEFAULT 1 f_base_local2 - 20: 0000000000008038 0 NOTYPE LOCAL DEFAULT 1 \$x - 21: 0000000000000000 0 FILE LOCAL DEFAULT ABS - 22: 0000000000009080 0 OBJECT LOCAL DEFAULT ABS _DYNAMIC - 23: 0000000000008000 0 NOTYPE LOCAL DEFAULT \[VARIANT_PCS\] 1 f_spec_global_hidden_def - 24: 0000000000008000 0 IFUNC LOCAL DEFAULT 1 f_base_global_hidden_ifunc - 25: 0000000000008000 0 NOTYPE LOCAL DEFAULT 1 f_base_global_hidden_def - 26: 0000000000009000 0 OBJECT LOCAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_ - 27: 0000000000008000 0 IFUNC LOCAL DEFAULT \[VARIANT_PCS\] 1 f_spec_global_hidden_ifunc - 28: 0000000000008070 0 NOTYPE LOCAL DEFAULT 2 \$x + 16: 0000000000011038 0 NOTYPE LOCAL DEFAULT \[VARIANT_PCS\] 6 f_spec_local2 + 17: 0000000000011038 0 IFUNC LOCAL DEFAULT \[VARIANT_PCS\] 6 f_spec_local2_ifunc + 18: 0000000000011038 0 IFUNC LOCAL DEFAULT 6 f_base_local2_ifunc + 19: 0000000000011038 0 NOTYPE LOCAL DEFAULT 6 f_base_local2 + 20: 0000000000011038 0 NOTYPE LOCAL DEFAULT 6 \$x + 21: 0000000000000000 0 FILE LOCAL DEFAULT ABS\s + 22: 0000000000020000 0 OBJECT LOCAL DEFAULT ABS _DYNAMIC + 23: 0000000000011000 0 NOTYPE LOCAL DEFAULT \[VARIANT_PCS\] 6 f_spec_global_hidden_def + 24: 0000000000011000 0 IFUNC LOCAL DEFAULT 6 f_base_global_hidden_ifunc + 25: 0000000000011000 0 NOTYPE LOCAL DEFAULT 6 f_base_global_hidden_def + 26: 0000000000021000 0 OBJECT LOCAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_ + 27: 0000000000011000 0 IFUNC LOCAL DEFAULT \[VARIANT_PCS\] 6 f_spec_global_hidden_ifunc + 28: 0000000000010000 0 NOTYPE LOCAL DEFAULT 5 \$x 29: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND f_base_global_default_undef 30: 0000000000000000 0 NOTYPE GLOBAL DEFAULT \[VARIANT_PCS\] UND f_spec_global_default_undef - 31: 0000000000008000 0 IFUNC GLOBAL DEFAULT \[VARIANT_PCS\] 1 f_spec_global_default_ifunc - 32: 0000000000008000 0 NOTYPE GLOBAL DEFAULT 1 f_base_global_default_def - 33: 0000000000008000 0 NOTYPE GLOBAL DEFAULT \[VARIANT_PCS\] 1 f_spec_global_default_def - 34: 0000000000008000 0 IFUNC GLOBAL DEFAULT 1 f_base_global_default_ifunc + 31: 0000000000011000 0 IFUNC GLOBAL DEFAULT \[VARIANT_PCS\] 6 f_spec_global_default_ifunc + 32: 0000000000011000 0 NOTYPE GLOBAL DEFAULT 6 f_base_global_default_def + 33: 0000000000011000 0 NOTYPE GLOBAL DEFAULT \[VARIANT_PCS\] 6 f_spec_global_default_def + 34: 0000000000011000 0 IFUNC GLOBAL DEFAULT 6 f_base_global_default_ifunc diff --git a/ld/testsuite/ld-aarch64/variant_pcs.ld b/ld/testsuite/ld-aarch64/variant_pcs.ld index a66a934..cadecd8 100644 --- a/ld/testsuite/ld-aarch64/variant_pcs.ld +++ b/ld/testsuite/ld-aarch64/variant_pcs.ld @@ -3,21 +3,31 @@ OUTPUT_ARCH(aarch64) ENTRY(_start) SECTIONS { - /* Read-only sections, merged into text segment: */ - PROVIDE (__executable_start = 0x8000); . = 0x8000; + PROVIDE(__executable_start = 0x8000); + . = SEGMENT_START("text-segment", 0x8000) + SIZEOF_HEADERS; + /* Start of the executable code region. */ + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + . = 0x9000; + .rela.plt : { *(.rela.plt) *(.rela.iplt) } + . = 0x10000; + .plt : { *(.plt) } + . = 0x11000; .text : { *(.before) *(.text) *(.after) - } =0 - . = 0x9000; + } + + /* Start of the Read Write Data region. */ + . = ALIGN (CONSTANT (MAXPAGESIZE)); + .dynamic : { *(.dynamic) } + . = ALIGN(4K); .got : { *(.got) *(.got.plt)} - . = 0x10000; - .rela.dyn : { *(.rela.ifunc) } - . = 0x11000; - .rela.plt : { *(.rela.plt) *(.rela.iplt) } - . = 0x12340000; - .far : { *(.far) } - .ARM.attributes 0 : { *(.ARM.atttributes) } + + /* Start of the metadata region. */ + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) } } diff --git a/ld/testsuite/ld-arm/arm.ld b/ld/testsuite/ld-arm/arm.ld index 8e3fac2..4b596ce 100644 --- a/ld/testsuite/ld-arm/arm.ld +++ b/ld/testsuite/ld-arm/arm.ld @@ -19,5 +19,5 @@ SECTIONS .got : { *(.got) *(.got.plt)} . = 0x12340000; .far : { *(.far) } - .ARM.attribues 0 : { *(.ARM.atttributes) } + .ARM.attributes 0 : { *(.ARM.attributes) } } diff --git a/ld/testsuite/ld-arm/arm_purecode.ld b/ld/testsuite/ld-arm/arm_purecode.ld index 195aca1..488e3dd 100644 --- a/ld/testsuite/ld-arm/arm_purecode.ld +++ b/ld/testsuite/ld-arm/arm_purecode.ld @@ -28,5 +28,5 @@ SECTIONS .got : { *(.got) *(.got.plt)} . = 0x12340000; .far : { *(.far) } - .ARM.attribues 0 : { *(.ARM.atttributes) } + .ARM.attributes 0 : { *(.ARM.attributes) } } diff --git a/ld/testsuite/ld-arm/discard-unwind.ld b/ld/testsuite/ld-arm/discard-unwind.ld index d8f6524..54418f7 100644 --- a/ld/testsuite/ld-arm/discard-unwind.ld +++ b/ld/testsuite/ld-arm/discard-unwind.ld @@ -15,5 +15,5 @@ SECTIONS *(.v4_bx) } =0 /DISCARD/ : { *(.ARM.exidx*) } - .ARM.attribues 0 : { *(.ARM.atttributes) } + .ARM.attributes 0 : { *(.ARM.attributes) } } diff --git a/ld/testsuite/ld-arm/script-type.ld b/ld/testsuite/ld-arm/script-type.ld index 01995eb..af34697 100644 --- a/ld/testsuite/ld-arm/script-type.ld +++ b/ld/testsuite/ld-arm/script-type.ld @@ -3,7 +3,7 @@ SECTIONS { foo_a = bar_a; foo_t = bar_t; foo_o = bar_o; - *(.text) + *(.text) } - .ARM.attribues 0 : { *(.ARM.attributes) } + .ARM.attributes 0 : { *(.ARM.attributes) } } diff --git a/ld/testsuite/ld-arm/unwind-1.d b/ld/testsuite/ld-arm/unwind-1.d index add5cb7..073d6a5 100644 --- a/ld/testsuite/ld-arm/unwind-1.d +++ b/ld/testsuite/ld-arm/unwind-1.d @@ -1,10 +1,7 @@ #ld: -T arm.ld -#objdump: -s +#objdump: -s -j .ARM.exidx .*: file format.* -#... -Contents of section .ARM.exidx: - 8008 (f8ffff7f b0b0a880 f4ffff7f 01000000|7ffffff8 80a8b0b0 7ffffff4 00000001) .* -Contents of section .far: -#... +Contents of section \.ARM\.exidx: + 8008 (f8ffff7f b0b0a880 f4ffff7f 01000000|7ffffff8 80a8b0b0 7ffffff4 00000001) \.+ diff --git a/ld/testsuite/ld-arm/unwind-2.d b/ld/testsuite/ld-arm/unwind-2.d index a096c9b..c9cd433 100644 --- a/ld/testsuite/ld-arm/unwind-2.d +++ b/ld/testsuite/ld-arm/unwind-2.d @@ -1,10 +1,7 @@ #ld: -T arm.ld -#objdump: -s +#objdump: -s -j .ARM.exidx .*: file format.* -#... -Contents of section .ARM.exidx: - 8004 (fcffff7f b0b0a880 f8ffff7f 01000000|7ffffffc 80a8b0b0 7ffffff8 00000001) .* -Contents of section .far: -#... +Contents of section \.ARM\.exidx: + 8004 (fcffff7f b0b0a880 f8ffff7f 01000000|7ffffffc 80a8b0b0 7ffffff8 00000001) \.+ diff --git a/ld/testsuite/ld-arm/unwind-3.d b/ld/testsuite/ld-arm/unwind-3.d index 0b8e85e..9da1484 100644 --- a/ld/testsuite/ld-arm/unwind-3.d +++ b/ld/testsuite/ld-arm/unwind-3.d @@ -1,11 +1,8 @@ #ld: -T arm.ld -#objdump: -s +#objdump: -s -j .ARM.exidx .*: file format.* -#... -Contents of section .ARM.exidx: - 800c (f4ffff7f b0b0a880 f0ffff7f 01000000|7ffffff4 80a8b0b0 7ffffff0 00000001) .* - 801c (ecffff7f b0b0a880 e8ffff7f 01000000|7fffffec 80a8b0b0 7fffffe8 00000001) .* -Contents of section .far: -#... +Contents of section \.ARM\.exidx: + 800c (f4ffff7f b0b0a880 f0ffff7f 01000000|7ffffff4 80a8b0b0 7ffffff0 00000001) \.+ + 801c (ecffff7f b0b0a880 e8ffff7f 01000000|7fffffec 80a8b0b0 7fffffe8 00000001) \.+ diff --git a/ld/testsuite/ld-arm/unwind-4.d b/ld/testsuite/ld-arm/unwind-4.d index ffc8725..7b71de88 100644 --- a/ld/testsuite/ld-arm/unwind-4.d +++ b/ld/testsuite/ld-arm/unwind-4.d @@ -1,9 +1,8 @@ #ld: -q -T arm.ld -#objdump: -sr +#objdump: -sr -j .ARM.exidx .*: file format.* -#... RELOCATION RECORDS FOR \[\.ARM\.exidx\]: OFFSET +TYPE +VALUE 00000000 R_ARM_PREL31 \.text @@ -17,11 +16,6 @@ OFFSET +TYPE +VALUE 00000010 R_ARM_NONE __aeabi_unwind_cpp_pr0 00000018 R_ARM_PREL31 \.text - -Contents of section .text: -#... -Contents of section .ARM.exidx: - 8020 (e0ffff7f b0b0a880 dcffff7f e8ffff7f|7fffffe0 80a8b0b0 7fffffdc 7fffffe8) .* - 8030 (d8ffff7f b0b0a880 d8ffff7f 01000000|7fffffd8 80a8b0b0 7fffffd8 00000001) .* -Contents of section .far: -#... +Contents of section \.ARM\.exidx: + 8020 (e0ffff7f b0b0a880 dcffff7f e8ffff7f|7fffffe0 80a8b0b0 7fffffdc 7fffffe8) \.+ + 8030 (d8ffff7f b0b0a880 d8ffff7f 01000000|7fffffd8 80a8b0b0 7fffffd8 00000001) \.+ diff --git a/ld/testsuite/ld-elf/sec64k.exp b/ld/testsuite/ld-elf/sec64k.exp index 8dcb021..deb46d3 100644 --- a/ld/testsuite/ld-elf/sec64k.exp +++ b/ld/testsuite/ld-elf/sec64k.exp @@ -168,9 +168,9 @@ if [catch { set ofd [open "tmpdir/$test2.d" w] } x] { return } -# too big for avr, d10v and msp -# lack of fancy orphan section handling causes overlap on fr30 and iq2000 -# bfin and lm32 complain about relocations in read-only sections +# Too big for avr, d10v and msp. +# Lack of fancy orphan section handling causes overlap on fr30 and iq2000. +# bfin and lm32 complain about relocations in read-only sections. if { ![istarget "d10v-*-*"] && ![istarget "avr-*-*"] && ![istarget "msp*-*-*"] @@ -179,7 +179,13 @@ if { ![istarget "d10v-*-*"] && ![istarget "bfin-*-linux*"] && ![istarget "lm32-*-linux*"] && ![istarget "pru-*-*"] } { + + # Create a 64ksec.d test control file... + + # List the input files. foreach sfile $sfiles { puts $ofd "#source: $sfile" } + + # Add any needed linker command line options. if { [istarget spu*-*-*] } { puts $ofd "#ld: --local-store 0:0" } elseif { [istarget "i?86-*-linux*"] || [istarget "x86_64-*-linux*"] } { @@ -187,10 +193,20 @@ if { ![istarget "d10v-*-*"] } else { puts $ofd "#ld:" } - #force z80 target to compile for eZ80 in ADL mode + + # Enable the accumulation of internal linker statistics in a separate file. + # Enabled this way as you cannot have multiple #ld: options in a .d file. + # The + character causes the file to opened in append mode, so that multiple + # runs of this test will accumulate data over time. Thus allowing regular + # testers to see changes in the performance of the linker. + puts $ofd "#ld_after_inputfiles: --stats=+tmpdir/$test2.stats" + + # Force z80 target to compile for eZ80 in ADL mode. if { [istarget "z80-*-*"] } then { puts $ofd "#as: -ez80-adl" } + + # Add a test of the linked binary. puts $ofd "#readelf: -W -wN -Ss" puts $ofd "There are 660.. section headers.*:" puts $ofd "#..." @@ -199,6 +215,7 @@ if { ![istarget "d10v-*-*"] puts $ofd " \\\[65279\\\] \\.foo\\.\[0-9\]+ .*" puts $ofd " \\\[65280\\\] \\.foo\\.\[0-9\]+ .*" puts $ofd "#..." + if { [is_elf_unused_section_symbols ] } { puts $ofd " 660..: \[0-9a-f\]+\[ \]+0\[ \]+SECTION\[ \]+LOCAL\[ \]+DEFAULT\[ \]+660...*" puts $ofd "#..." @@ -209,6 +226,7 @@ if { ![istarget "d10v-*-*"] puts $ofd " 66...: \[0-9a-f\]+\[ \]+0\[ \]+NOTYPE\[ \]+LOCAL\[ \]+DEFAULT\[ \]+660.. bar_66000$" } puts $ofd "#..." + # Global symbols are not in "alphanumeric" order, so we just check # that the first and the last are present in any order (assuming no # duplicates). @@ -217,9 +235,14 @@ if { ![istarget "d10v-*-*"] puts $ofd ".* (\[0-9\] foo_1|66... foo_66000)$" puts $ofd "#pass" close $ofd + + # Now run the constructed test file. run_dump_test "tmpdir/$test2" + + # Leave the test file around in case the user wants to examine it. } +# Tidy up. for { set i 1 } { $i < $max_sec / $secs_per_file } { incr i } { catch "exec rm -f tmpdir/dump$i.o" status } diff --git a/ld/testsuite/ld-elf/tbss4.d b/ld/testsuite/ld-elf/tbss4.d new file mode 100644 index 0000000..336ed8f --- /dev/null +++ b/ld/testsuite/ld-elf/tbss4.d @@ -0,0 +1,13 @@ +#ld: -e _start -Ttext=0x1000 -z max-page-size=0x1000 -z common-page-size=0x1000 -z noseparate-code +#readelf: -lSW +#target: *-linux* *-gnu* +#notarget: hppa64-*-* ia64-*-* + +#... +.* \.tbss +NOBITS +0+1014 +0+1014 +0+4 +0+ +WAT +0 +0 +4 + +#... + +TLS +0x0*1014 +0x0+1014 +0x0+1014 +0x0+ +0x0+4 R +0x4 +#... +.* \.tbss +#pass diff --git a/ld/testsuite/ld-elf/tbss4.s b/ld/testsuite/ld-elf/tbss4.s new file mode 100644 index 0000000..f49491e --- /dev/null +++ b/ld/testsuite/ld-elf/tbss4.s @@ -0,0 +1,25 @@ +# Writeable gcc_except_table is required in order to put this section after +# the DATA_SEGMENT_ALIGN directive in the default linker script (and hence +# in the same PT_LOAD as the PT_TLS segment, and hence so that the +# gcc_except_table can affect the .tbss section location). + .section .gcc_except_table,"aw",%progbits +# Alignment is needed -- otherwise gcc_except_table start position seems to +# be adjusted so that the tbss section is fully aligned. + .balign 4 + .ascii "Odd number of chars" + + .section .tbss,"awT",%nobits + .balign 4 + .type xyz, %object + .size xyz, 4 +xyz: + .zero 4 + + .data +dataval: + .balign 4 + .ascii "x" + + .text + .global _start +_start: diff --git a/ld/testsuite/ld-elfvers/vers7.c b/ld/testsuite/ld-elfvers/vers7.c index 54316c9..a4fb254 100644 --- a/ld/testsuite/ld-elfvers/vers7.c +++ b/ld/testsuite/ld-elfvers/vers7.c @@ -2,8 +2,8 @@ * Test program that goes with test7.so */ -extern int hide_a(); -extern int show_b(); +extern int hide_a(int e); +extern int show_b(int e); int main() diff --git a/ld/testsuite/ld-loongarch-elf/32_pcrel.s b/ld/testsuite/ld-loongarch-elf/32_pcrel.s new file mode 100644 index 0000000..3ef16de --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/32_pcrel.s @@ -0,0 +1,6 @@ + .section sx,"a" +x: + nop + + .section sy,"a" + .4byte x-. diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp index 0295be8..2f09a69 100644 --- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp +++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp @@ -200,6 +200,8 @@ if [istarget "loongarch64-*-*"] { run_dump_test "bad_pcrel20_s2_global" run_dump_test "bad_pcrel20_s2_weak" run_dump_test "weak-undef-hidden-shared" + run_dump_test "overflow_32_pcrel" + run_dump_test "underflow_32_pcrel" } if [check_pie_support] { diff --git a/ld/testsuite/ld-loongarch-elf/overflow_32_pcrel.d b/ld/testsuite/ld-loongarch-elf/overflow_32_pcrel.d new file mode 100644 index 0000000..154dac9 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/overflow_32_pcrel.d @@ -0,0 +1,4 @@ +#source: 32_pcrel.s +#as: -mthin-add-sub +#ld: -shared --section-start=sx=0x80001000 --section-start=sy=0x1000 +#error: .*relocation truncated to fit: R_LARCH_32_PCREL against `x' diff --git a/ld/testsuite/ld-loongarch-elf/underflow_32_pcrel.d b/ld/testsuite/ld-loongarch-elf/underflow_32_pcrel.d new file mode 100644 index 0000000..a5396bc --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/underflow_32_pcrel.d @@ -0,0 +1,4 @@ +#source: 32_pcrel.s +#as: -mthin-add-sub +#ld: -shared --section-start=sx=0x1000 --section-start=sy=0x80001001 +#error: .*relocation truncated to fit: R_LARCH_32_PCREL against `x' diff --git a/ld/testsuite/ld-pe/secidx.d b/ld/testsuite/ld-pe/secidx.d index 184cc9f..d0e52c9 100644 --- a/ld/testsuite/ld-pe/secidx.d +++ b/ld/testsuite/ld-pe/secidx.d @@ -1,11 +1,11 @@ tmpdir/secidx\.x: +file format pei-.* -Contents of section .text: +Contents of section \.text: .*1000 3e3e3e3e 3c3c3c3c 3e3e3e3e 3e3c3c3c >>>><<<<>>>>><<< .*1010 3e3e3e3e 3e3e3c3c 3e3e3e3e 3e3e3e3c >>>>>><<>>>>>>>< .*1020 3c3c3c3c 3e3e3e3e 3e909090 <<<<>>>>>... -Contents of section .data: +Contents of section \.data: .*2000 3e3e3e3e 3c3c3c3c 3e3e3e3e 3e3c3c3c >>>><<<<>>>>><<< .*2010 3e3e3e3e 3e3e3c3c 3e3e3e3e 3e3e3e3c >>>>>><<>>>>>>>< .*2020 3e3e3e3e 01001101 00110100 11010011 >>>>............ @@ -15,13 +15,13 @@ Contents of section .data: .*2060 3c3c3c3c 3c3c3c3c 3e3e3e3e 01001102 <<<<<<<<>>>>.... .*2070 00110300 113c3c3c 3c3c3c3c 3c000000 .....<<<<<<<<... .*2080 3c3c3c3e 3e3e3e3e 3e000000 <<<>>>>>>... -Contents of section .rdata: +Contents of section \.rdata: .*3000 3e3e3e3e 3c3c3c3c 3e3e3e3e 3e3c3c3c >>>><<<<>>>>><<< .*3010 3e3e3e3e 3e3e3c3c 3e3e3e3e 3e3e3e3c >>>>>><<>>>>>>>< .*3020 3e3e3e3e 00000000 00000000 00000000 >>>>............ .*3030 3c3c3c3e 3e3e3e3e 3e000000 ffffffff <<<>>>>>>....... .*3040 00000000 ffffffff 00000000 ............ -Contents of section .idata: +Contents of section \.idata: .*4000 00000000 00000000 00000000 00000000 ................ .*4010 00000000 .... #... diff --git a/ld/testsuite/ld-plugin/lto-20.ver b/ld/testsuite/ld-plugin/lto-20.ver new file mode 100644 index 0000000..ac906ac --- /dev/null +++ b/ld/testsuite/ld-plugin/lto-20.ver @@ -0,0 +1 @@ +FOO { global: foo; }; diff --git a/ld/testsuite/ld-plugin/lto-20a.c b/ld/testsuite/ld-plugin/lto-20a.c new file mode 100644 index 0000000..3d6dac9 --- /dev/null +++ b/ld/testsuite/ld-plugin/lto-20a.c @@ -0,0 +1,2 @@ +extern int foo (); +int main () { return foo (); } diff --git a/ld/testsuite/ld-plugin/lto-20b.c b/ld/testsuite/ld-plugin/lto-20b.c new file mode 100644 index 0000000..ba123cb --- /dev/null +++ b/ld/testsuite/ld-plugin/lto-20b.c @@ -0,0 +1,11 @@ +extern int printf (const char *, ...); +int foo () +{ +#ifdef SHARED + printf ("PASS\n"); + return 0; +#else + printf ("FAIL\n"); + return 1; +#endif +} diff --git a/ld/testsuite/ld-plugin/lto-binutils.exp b/ld/testsuite/ld-plugin/lto-binutils.exp new file mode 100644 index 0000000..5b4e0a1 --- /dev/null +++ b/ld/testsuite/ld-plugin/lto-binutils.exp @@ -0,0 +1,358 @@ +# Expect script for binutils tests with LTO +# Copyright (C) 2025 Free Software Foundation, Inc. +# +# This file is part of the GNU Binutils. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. +# + +# Make sure that binutils can correctly handle LTO IR in ELF. + +if { !([istarget *-*-linux*] + || [istarget arm*-*-uclinuxfdpiceabi] + || [istarget *-*-nacl*] + || [istarget *-*-gnu*]) || [istarget *ecoff] } then { + return +} + +# Check to see if the C and C++ compilers work +if { ![check_compiler_available] || [which $CXX_FOR_TARGET] == 0 } { + return +} + +# These tests require plugin and LTO. +if { ![check_plugin_api_available] + || ![check_lto_available] } { + return +} + +set lto_fat "" +set lto_no_fat "" +if { [check_lto_fat_available] } { + set lto_fat "-ffat-lto-objects" + set lto_no_fat "-fno-fat-lto-objects" + set no_lto "-fno-lto" +} + +# List contains test-items: +# 0:program name +# 1:program options +# 2:input file +# 3:output file +# 4:action list (optional) +# +proc run_lto_binutils_test { lto_tests } { + global srcdir + global subdir + global nm + global objcopy + global objdump + global READELF + global strip + global plug_opt + + foreach testitem $lto_tests { + set prog_name [lindex $testitem 0] + set prog_options [lindex $testitem 1] + set input tmpdir/[lindex $testitem 2] + set output tmpdir/[lindex $testitem 3] + set actions [lindex $testitem 4] + set objfiles {} + set is_unresolved 0 + set failed 0 + +# eval set prog \$$prog_name + switch -- $prog_name { + objcopy + { + set prog $objcopy + set prog_output "$output" + } + strip + { + set prog $strip + set prog_output "-o $output" + } + default + { + perror "Unrecognized action $action" + set is_unresolved 1 + break + } + } + + # Don't leave previous output around + if { $output ne "tmpdir/" } { + remote_file host delete $output + } + + append prog_options " $plug_opt" + + set cmd_options "$prog_options $prog_output $input" + set test_name "$prog_name $cmd_options" + + set cmd "$prog $cmd_options" + send_log "$cmd\n" + set got [remote_exec host "$cmd"] + if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then { + send_log "$got\n" + fail "$test_name" + continue + } + + if { $failed == 0 } { + foreach actionlist $actions { + set action [lindex $actionlist 0] + set progopts [lindex $actionlist 1] + + # There are actions where we run regexp_diff on the + # output, and there are other actions (presumably). + # Handling of the former look the same. + set dump_prog "" + switch -- $action { + objdump + { set dump_prog $objdump } + nm + { set dump_prog $nm } + readelf + { set dump_prog $READELF } + default + { + perror "Unrecognized action $action" + set is_unresolved 1 + break + } + } + + if { $dump_prog != "" } { + set dumpfile [lindex $actionlist 2] + set binary $dump_prog + + # Ensure consistent sorting of symbols + if {[info exists env(LC_ALL)]} { + set old_lc_all $env(LC_ALL) + } + set env(LC_ALL) "C" + set cmd "$binary $progopts $output > tmpdir/dump.out" + send_log "$cmd\n" + catch "exec $cmd" comp_output + if {[info exists old_lc_all]} { + set env(LC_ALL) $old_lc_all + } else { + unset env(LC_ALL) + } + set comp_output [prune_warnings $comp_output] + + if ![string match "" $comp_output] then { + send_log "$comp_output\n" + set failed 1 + break + } + + if { [regexp_diff "tmpdir/dump.out" "$srcdir/$subdir/$dumpfile"] } then { + verbose -log "output is [file_contents "tmpdir/dump.out"]" 2 + set failed 1 + break + } + } + } + } + + if { $failed } { + fail $test_name + } elseif { $is_unresolved } { + unresolved $test_name + } else { + pass $test_name + } + } +} + +run_cc_link_tests [list \ + [list \ + "Build strip-1a.o" \ + "" \ + "-O2 -flto $lto_no_fat" \ + { strip-1a.c } \ + ] \ + [list \ + "Build libstrip-1a.a" \ + "$plug_opt" \ + "-O2 -flto $lto_no_fat" \ + { strip-1a.c } \ + {} \ + "libstrip-1a.a" \ + ] \ + [list \ + "Build strip-1a-fat.o" \ + "" \ + "-O2 -flto $lto_fat" \ + { strip-1a-fat.c } \ + ] \ + [list \ + "Build libstrip-1a-fat.a" \ + "$plug_opt" \ + "-O2 -flto $lto_fat" \ + { strip-1a-fat.c } \ + {} \ + "libstrip-1a-fat.a" \ + ] \ +] + +run_lto_binutils_test [list \ + [list \ + "strip" \ + "--strip-unneeded" \ + "libstrip-1a.a" \ + "libstrip-1a-s.a" \ + ] \ + [list \ + "strip" \ + "--strip-unneeded" \ + "strip-1a.o" \ + "strip-1a-s.o" \ + ] \ + [list \ + "strip" \ + "--strip-unneeded -R .gnu.*lto_* -N __gnu_lto_v1" \ + "libstrip-1a-fat.a" \ + "libstrip-1a-fat-s.a" \ + {{readelf -SW strip-1a-fat.rd}} \ + ] \ + [list \ + "strip" \ + "--strip-unneeded -R .gnu.*lto_* -N __gnu_lto_v1" \ + "strip-1a-fat.o" \ + "strip-1a-fat-s.o" \ + {{readelf -SW strip-1a-fat.rd}} \ + ] \ + [list \ + "strip" \ + "--strip-unneeded -R .gnu.debuglto_*" \ + "libstrip-1a-fat.a" \ + "libstrip-1b-fat-s.a" \ + {{readelf -SW strip-1b-fat.rd}} \ + ] \ + [list \ + "strip" \ + "--strip-unneeded -R .gnu.debuglto_*" \ + "strip-1a-fat.o" \ + "strip-1b-fat-s.o" \ + {{readelf -SW strip-1b-fat.rd}} \ + ] \ +] + +if { [check_lto_fat_available] } { + run_lto_binutils_test [list \ + [list \ + "strip" \ + "-R .gnu.*lto_* -N __gnu_lto_v1" \ + "strip-1a.o" \ + "strip-1a-s-all.o" \ + {{nm -n strip-1a-s-all.nd}} \ + ] \ + [list \ + "strip" \ + "-R .gnu.*lto_* -N __gnu_lto_v1" \ + "libstrip-1a.a" \ + "libstrip-1a-s-all.a" \ + {{nm -n strip-1a-s-all.nd}} \ + ] \ + ] +} + +run_cc_link_tests [list \ + [list \ + "Build strip-1a (strip-1a.o)" \ + "" \ + "-O2 -flto $lto_no_fat" \ + { strip-1b.c } \ + {} \ + "libstrip-1a" \ + "C" \ + "tmpdir/strip-1a.o" \ + ] \ + [list \ + "Build strip-1b (strip-1a-s.o)" \ + "" \ + "-O2 -flto $lto_no_fat" \ + { strip-1b.c } \ + {} \ + "libstrip-1b" \ + "C" \ + "tmpdir/strip-1a-s.o" \ + ] \ + [list \ + "Build strip-1c (libstrip-1a.a)" \ + "" \ + "-O2 -flto $lto_no_fat" \ + { strip-1b.c } \ + {} \ + "libstrip-1c" \ + "C" \ + "tmpdir/libstrip-1a.a" \ + ] \ + [list \ + "Build strip-1d (libstrip-1a-s.a)" \ + "" \ + "-O2 -flto $lto_no_fat" \ + { strip-1b.c } \ + {} \ + "libstrip-1d" \ + "C" \ + "tmpdir/libstrip-1a-s.a" \ + ] \ + [list \ + "Build strip-1e (strip-1a-fat-s.o)" \ + "" \ + "-O2 -flto $lto_fat" \ + { strip-1b-fat.c } \ + {} \ + "libstrip-1e" \ + "C" \ + "tmpdir/strip-1a-fat-s.o" \ + ] \ + [list \ + "Build strip-1f (libstrip-1a-fat-s.a)" \ + "" \ + "-O2 -flto $lto_fat" \ + { strip-1b-fat.c } \ + {} \ + "libstrip-1f" \ + "C" \ + "tmpdir/libstrip-1a-fat-s.a" \ + ] \ + [list \ + "Build strip-1g (strip-1b-fat-s.o)" \ + "" \ + "-O2 -flto $lto_fat" \ + { strip-1b-fat.c } \ + {} \ + "libstrip-1g" \ + "C" \ + "tmpdir/strip-1b-fat-s.o" \ + ] \ + [list \ + "Build strip-1h (libstrip-1b-fat-s.a)" \ + "" \ + "-O2 -flto $lto_fat" \ + { strip-1b-fat.c } \ + {} \ + "libstrip-1h" \ + "C" \ + "tmpdir/libstrip-1b-fat-s.a" \ + ] \ +] diff --git a/ld/testsuite/ld-plugin/lto.exp b/ld/testsuite/ld-plugin/lto.exp index 556bbe9..f0d0954 100644 --- a/ld/testsuite/ld-plugin/lto.exp +++ b/ld/testsuite/ld-plugin/lto.exp @@ -477,6 +477,12 @@ set lto_link_elf_tests [list \ [list {liblto-19.so} \ {-shared tmpdir/lto-19b.o tmpdir/liblto-19.a} {-O2 -fPIC} \ {dummy.c} {} {liblto-19.so}] \ + [list {liblto-20_static.a} \ + {} {-fPIC} \ + {lto-20b.c} {} {liblto-20_static.a}] \ + [list {liblto-20.so} \ + {-shared -Wl,--version-script=lto-20.ver} {-DSHARED -fPIC} \ + {lto-20b.c} {} {liblto-20.so}] \ [list {pr26806.so} \ {-shared} {-fpic -O2 -flto} \ {pr26806.c} {{nm {-D} pr26806.d}} {pr26806.so}] \ @@ -880,6 +886,10 @@ set lto_run_elf_shared_tests [list \ {-Wl,--as-needed,-R,tmpdir} {} \ {lto-19c.c} {lto-19.exe} {pass.out} {-flto -O2} {c} {} \ {tmpdir/liblto-19.so tmpdir/liblto-19.a}] \ + [list {lto-20} \ + {-Wl,--as-needed,-R,tmpdir} {} \ + {lto-20a.c} {lto-20.exe} {pass.out} {-flto} {c} {} \ + {tmpdir/liblto-20.so tmpdir/liblto-20_static.a -Wl,--no-as-needed}] \ [list {pr31482a} \ {-Wl,--no-as-needed,-R,tmpdir} {} \ {pr31482a.c} {pr31482a.exe} {pass.out} {-flto} {c} {} \ @@ -1148,9 +1158,8 @@ remote_exec host "mv" "tmpdir/dump tmpdir/lto-5.o" run_dump_test "lto-10r" remote_exec host "mv" "tmpdir/dump tmpdir/lto-10.o" set testname "nm mixed object" -set lto_plugin [string trim [run_host_cmd "$CC_FOR_TARGET" "-print-prog-name=liblto_plugin.so"]] -if { [ regexp "liblto_plugin.so" $lto_plugin ] } { - set exec_output [run_host_cmd "$NM" "--plugin $lto_plugin tmpdir/lto-10.o"] +if { $plug_opt != "" } { + set exec_output [run_host_cmd "$NM" "$plug_opt tmpdir/lto-10.o"] if { [ regexp "(D|T) main" $exec_output ] } { pass $testname } else { @@ -1202,6 +1211,38 @@ if { [is_elf_format] } { if { [is_elf_format] && [check_lto_shared_available] } { run_ld_link_exec_tests $lto_run_elf_shared_tests + if { [check_lto_fat_available] } { + run_cc_link_tests [list \ + [list \ + "Build libpr32846a.a" \ + "$plug_opt" "-fPIC -O2 -flto $lto_no_fat" \ + {pr32846a.c pr32846b.c} {} "libpr32846a.a" \ + ] \ + [list \ + "Build libpr32846b.a" \ + "$plug_opt" "-fPIC -O2 -flto $lto_no_fat" \ + {pr32846a.c pr32846b.c pr32846c.c} {} "libpr32846b.a" \ + ] \ + [list \ + "Build pr32846d.o" \ + "$plug_opt" "-fPIC -O2 -flto $lto_no_fat" \ + {pr32846d.c} {} \ + ] \ + [list \ + "Build pr32846e.o" \ + "$plug_opt" "-fPIC -O2 -flto $lto_no_fat" \ + {pr32846e.c} {} \ + ] \ + [list \ + "Build pr32846" \ + "-shared -fPIC -O2 -flto $lto_no_fat -Wl,--no-undefined \ + tmpdir/pr32846d.o tmpdir/libpr32846a.a \ + tmpdir/libpr32846b.a tmpdir/pr32846e.o" \ + "-O2 -fPIC -flto $lto_no_fat" \ + {dummy.c} {} "pr32846" \ + ] \ + ] \ + } } proc pr20103 {cflags libs} { diff --git a/ld/testsuite/ld-plugin/pr25618a.h b/ld/testsuite/ld-plugin/pr25618a.h index 9bf857c..04be194 100644 --- a/ld/testsuite/ld-plugin/pr25618a.h +++ b/ld/testsuite/ld-plugin/pr25618a.h @@ -1,2 +1 @@ -#pragma once __attribute__((visibility("default"))) int bar(); diff --git a/ld/testsuite/ld-plugin/pr25618b.h b/ld/testsuite/ld-plugin/pr25618b.h index cd80074..65e72a0 100644 --- a/ld/testsuite/ld-plugin/pr25618b.h +++ b/ld/testsuite/ld-plugin/pr25618b.h @@ -1,2 +1 @@ -#pragma once __attribute__((visibility("default"))) int foo(); diff --git a/ld/testsuite/ld-plugin/pr32846a.c b/ld/testsuite/ld-plugin/pr32846a.c new file mode 100644 index 0000000..8c16171 --- /dev/null +++ b/ld/testsuite/ld-plugin/pr32846a.c @@ -0,0 +1,6 @@ +extern void mkdir_p (void); +void +mkdir_parents (void) +{ + mkdir_p (); +} diff --git a/ld/testsuite/ld-plugin/pr32846b.c b/ld/testsuite/ld-plugin/pr32846b.c new file mode 100644 index 0000000..9776a37 --- /dev/null +++ b/ld/testsuite/ld-plugin/pr32846b.c @@ -0,0 +1,4 @@ +void +hash_new (void) +{ +} diff --git a/ld/testsuite/ld-plugin/pr32846c.c b/ld/testsuite/ld-plugin/pr32846c.c new file mode 100644 index 0000000..f87cffb --- /dev/null +++ b/ld/testsuite/ld-plugin/pr32846c.c @@ -0,0 +1,6 @@ +extern void hash_new (void); +void +kmod_new (void) +{ + hash_new(); +} diff --git a/ld/testsuite/ld-plugin/pr32846d.c b/ld/testsuite/ld-plugin/pr32846d.c new file mode 100644 index 0000000..c6f4102 --- /dev/null +++ b/ld/testsuite/ld-plugin/pr32846d.c @@ -0,0 +1,12 @@ +extern void kmod_new (void); +extern void mkdir_parents (void); +void +do_lsmod (void) +{ + kmod_new (); +} +void +do_static_nodes (void) +{ + mkdir_parents(); +} diff --git a/ld/testsuite/ld-plugin/pr32846e.c b/ld/testsuite/ld-plugin/pr32846e.c new file mode 100644 index 0000000..c4e5e56 --- /dev/null +++ b/ld/testsuite/ld-plugin/pr32846e.c @@ -0,0 +1,4 @@ +void +mkdir_p (void) +{ +} diff --git a/ld/testsuite/ld-plugin/strip-1a-fat.c b/ld/testsuite/ld-plugin/strip-1a-fat.c new file mode 100644 index 0000000..03b2a5c --- /dev/null +++ b/ld/testsuite/ld-plugin/strip-1a-fat.c @@ -0,0 +1 @@ +#include "strip-1a.c" diff --git a/ld/testsuite/ld-plugin/strip-1a-fat.rd b/ld/testsuite/ld-plugin/strip-1a-fat.rd new file mode 100644 index 0000000..aefe1c5 --- /dev/null +++ b/ld/testsuite/ld-plugin/strip-1a-fat.rd @@ -0,0 +1,6 @@ +#failif +#... +Section Headers: +#... + \[[ 0-9]+\] \.gnu.lto_.* +#... diff --git a/ld/testsuite/ld-plugin/strip-1a-s-all.nd b/ld/testsuite/ld-plugin/strip-1a-s-all.nd new file mode 100644 index 0000000..612ba6a --- /dev/null +++ b/ld/testsuite/ld-plugin/strip-1a-s-all.nd @@ -0,0 +1,3 @@ +#... +[0-9a-f]* C _?__gnu_lto_slim +#pass diff --git a/ld/testsuite/ld-plugin/strip-1a.c b/ld/testsuite/ld-plugin/strip-1a.c new file mode 100644 index 0000000..d84af20 --- /dev/null +++ b/ld/testsuite/ld-plugin/strip-1a.c @@ -0,0 +1,4 @@ +extern void foo2(void); +extern void foo3(void); +void foo1(void) { foo3(); } +int main(void) { foo2(); } diff --git a/ld/testsuite/ld-plugin/strip-1b-fat.c b/ld/testsuite/ld-plugin/strip-1b-fat.c new file mode 100644 index 0000000..1a2e4d2 --- /dev/null +++ b/ld/testsuite/ld-plugin/strip-1b-fat.c @@ -0,0 +1 @@ +#include "strip-1b.c" diff --git a/ld/testsuite/ld-plugin/strip-1b-fat.rd b/ld/testsuite/ld-plugin/strip-1b-fat.rd new file mode 100644 index 0000000..e3a266f --- /dev/null +++ b/ld/testsuite/ld-plugin/strip-1b-fat.rd @@ -0,0 +1,5 @@ +#... +Section Headers: +#... + \[[ 0-9]+\] \.gnu.lto_.* +#pass diff --git a/ld/testsuite/ld-plugin/strip-1b.c b/ld/testsuite/ld-plugin/strip-1b.c new file mode 100644 index 0000000..967872a --- /dev/null +++ b/ld/testsuite/ld-plugin/strip-1b.c @@ -0,0 +1,3 @@ +extern void foo1(void); +void foo2(void) { foo1(); } +void foo3(void) {} diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp index 9cb847d..e103df6 100644 --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp @@ -227,6 +227,14 @@ if [istarget "riscv*-*-*"] { run_dump_test "data-reloc-rv64-addr32-pic" run_dump_test "data-reloc-rv64-undef32-pic" + run_dump_test "property-zicfilp-unlabeled" + run_dump_test "property-zicfiss" + run_dump_test "property-combine-and-1" + run_dump_test "property-combine-and-2" + run_dump_test "property-combine-and-3" + + run_dump_test "zicfilp-unlabeled-plt" + # IFUNC testcases. # Check IFUNC by single type relocs. run_dump_test_ifunc "ifunc-reloc-call-01" rv32 exe diff --git a/ld/testsuite/ld-riscv-elf/property-combine-and-1.d b/ld/testsuite/ld-riscv-elf/property-combine-and-1.d new file mode 100644 index 0000000..571620f --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/property-combine-and-1.d @@ -0,0 +1,6 @@ +#name: RISC-V GNU Property (multiple inputs, combine section) - 1 +#source: property1.s +#source: property2.s +#as: -march=rv64g +#ld: -shared -melf64lriscv +#readelf: -n diff --git a/ld/testsuite/ld-riscv-elf/property-combine-and-2.d b/ld/testsuite/ld-riscv-elf/property-combine-and-2.d new file mode 100644 index 0000000..23482af --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/property-combine-and-2.d @@ -0,0 +1,11 @@ +#name: RISC-V GNU Property (multiple inputs, combine section) - 2 +#source: property1.s +#source: property3.s +#as: -march=rv64g +#ld: -shared -melf64lriscv +#readelf: -n + +Displaying notes found in: .note.gnu.property +[ ]+Owner[ ]+Data size[ ]+Description +[ ]+GNU[ ]+0x00000010[ ]+NT_GNU_PROPERTY_TYPE_0 +[ ]+Properties: RISC-V AND feature: CFI_LP_UNLABELED diff --git a/ld/testsuite/ld-riscv-elf/property-combine-and-3.d b/ld/testsuite/ld-riscv-elf/property-combine-and-3.d new file mode 100644 index 0000000..b57a0f7 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/property-combine-and-3.d @@ -0,0 +1,11 @@ +#name: RISC-V GNU Property (multiple inputs, combine section) - 3 +#source: property1.s +#source: property4.s +#as: -march=rv64g +#ld: -shared -melf64lriscv +#readelf: -n + +Displaying notes found in: .note.gnu.property +[ ]+Owner[ ]+Data size[ ]+Description +[ ]+GNU[ ]+0x00000010[ ]+NT_GNU_PROPERTY_TYPE_0 +[ ]+Properties: RISC-V AND feature: CFI_SS diff --git a/ld/testsuite/ld-riscv-elf/property-zicfilp-unlabeled.d b/ld/testsuite/ld-riscv-elf/property-zicfilp-unlabeled.d new file mode 100644 index 0000000..48d60d6 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/property-zicfilp-unlabeled.d @@ -0,0 +1,10 @@ +#name: GNU Property (single input, CFI_LP_UNLABELED) +#source: property-zicfilp-unlabeled.s +#as: -march=rv64g +#ld: -shared -melf64lriscv +#readelf: -n + +Displaying notes found in: .note.gnu.property +[ ]+Owner[ ]+Data size[ ]+Description +[ ]+GNU[ ]+0x00000010[ ]+NT_GNU_PROPERTY_TYPE_0 +[ ]+Properties: RISC-V AND feature: CFI_LP_UNLABELED diff --git a/ld/testsuite/ld-riscv-elf/property-zicfilp-unlabeled.s b/ld/testsuite/ld-riscv-elf/property-zicfilp-unlabeled.s new file mode 100644 index 0000000..b0192c0 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/property-zicfilp-unlabeled.s @@ -0,0 +1,21 @@ + .text + .globl _start + .type _start,@function +_start: + ret + + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align 3 +2: .long 0xc0000000 /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x1 /* GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED. */ +4: + .p2align 3 +5: diff --git a/ld/testsuite/ld-riscv-elf/property-zicfiss.d b/ld/testsuite/ld-riscv-elf/property-zicfiss.d new file mode 100644 index 0000000..0dec1a1 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/property-zicfiss.d @@ -0,0 +1,10 @@ +#name: GNU Property (single input, CFI_SS) +#source: property-zicfiss.s +#as: -march=rv64g +#ld: -shared -melf64lriscv +#readelf: -n + +Displaying notes found in: .note.gnu.property +[ ]+Owner[ ]+Data size[ ]+Description +[ ]+GNU[ ]+0x00000010[ ]+NT_GNU_PROPERTY_TYPE_0 +[ ]+Properties: RISC-V AND feature: CFI_SS diff --git a/ld/testsuite/ld-riscv-elf/property-zicfiss.s b/ld/testsuite/ld-riscv-elf/property-zicfiss.s new file mode 100644 index 0000000..21342ef --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/property-zicfiss.s @@ -0,0 +1,21 @@ + .text + .globl _start + .type _start,@function +_start: + ret + + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align 3 +2: .long 0xc0000000 /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x2 /* GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS. */ +4: + .p2align 3 +5: diff --git a/ld/testsuite/ld-riscv-elf/property1.s b/ld/testsuite/ld-riscv-elf/property1.s new file mode 100644 index 0000000..622bbcb --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/property1.s @@ -0,0 +1,21 @@ + .text + .globl _start + .type _start,@function +_start: + ret + + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align 3 +2: .long 0xc0000000 /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x3 /* CFI_LP_UNLABELED and CFI_SS. */ +4: + .p2align 3 +5: diff --git a/ld/testsuite/ld-riscv-elf/property2.s b/ld/testsuite/ld-riscv-elf/property2.s new file mode 100644 index 0000000..4d1610c --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/property2.s @@ -0,0 +1,5 @@ + .text + .globl foo + .type foo,@function +foo: + ret diff --git a/ld/testsuite/ld-riscv-elf/property3.s b/ld/testsuite/ld-riscv-elf/property3.s new file mode 100644 index 0000000..61518fb --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/property3.s @@ -0,0 +1,21 @@ + .text + .globl _start + .type _start,@function +bar: + ret + + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align 3 +2: .long 0xc0000000 /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x1 /* CFI_LP_UNLABELED. */ +4: + .p2align 3 +5: diff --git a/ld/testsuite/ld-riscv-elf/property4.s b/ld/testsuite/ld-riscv-elf/property4.s new file mode 100644 index 0000000..54098a5 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/property4.s @@ -0,0 +1,21 @@ + .text + .globl _start + .type _start,@function +zoo: + ret + + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align 3 +2: .long 0xc0000000 /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x2 /* CFI_LP_SS. */ +4: + .p2align 3 +5: diff --git a/ld/testsuite/ld-riscv-elf/zicfilp-unlabeled-plt.d b/ld/testsuite/ld-riscv-elf/zicfilp-unlabeled-plt.d new file mode 100644 index 0000000..bb888d1 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/zicfilp-unlabeled-plt.d @@ -0,0 +1,35 @@ +#name: Unlabled landing pad PLT +#source: zicfilp-unlabeled-plt.s +#ld: -shared -melf64lriscv +#objdump: -dr -j .plt +#as: -march=rv64gc_zicfilp + +[^:]*: *file format elf64-.*riscv + +Disassembly of section \.plt: + +[0-9a-f]+ <\.plt>: +.*:[ ]+[0-9a-f]+[ ]+lpad[ ]+0x0 +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+t2,0x[0-9a-f]+ +.*:[ ]+[0-9a-f]+[ ]+sub[ ]+t1,t1,t3 +.*:[ ]+[0-9a-f]+[ ]+ld[ ]+t3,[0-9]+\(t2\) # [0-9a-f]+ <\.got\.plt> +.*:[ ]+[0-9a-f]+[ ]+addi[ ]+t1,t1,-64 +.*:[ ]+[0-9a-f]+[ ]+addi[ ]+t0,t2,[0-9]+ +.*:[ ]+[0-9a-f]+[ ]+srli[ ]+t1,t1,0x1 +.*:[ ]+[0-9a-f]+[ ]+ld[ ]+t0,8\(t0\) +.*:[ ]+[0-9a-f]+[ ]+jr[ ]+t3 +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop +.*:[ ]+[0-9a-f]+[ ]+nop + +[0-9a-f]+ <foo@plt>: +.*:[ ]+[0-9a-f]+[ ]+lpad[ ]+0x0 +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+t3,0x[0-9a-f]+ +.*:[ ]+[0-9a-f]+[ ]+ld[ ]+t3,[0-9]+\(t3\) # [0-9a-f]+ <foo> +.*:[ ]+[0-9a-f]+[ ]+jalr[ ]+t1,t3 + +[0-9a-f]+ <bar@plt>: +.*:[ ]+[0-9a-f]+[ ]+lpad[ ]+0x0 +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+t3,0x1 +.*:[ ]+[0-9a-f]+[ ]+ld[ ]+t3,[0-9]+\(t3\) # [0-9a-f]+ <bar> +.*:[ ]+[0-9a-f]+[ ]+jalr[ ]+t1,t3 diff --git a/ld/testsuite/ld-riscv-elf/zicfilp-unlabeled-plt.s b/ld/testsuite/ld-riscv-elf/zicfilp-unlabeled-plt.s new file mode 100644 index 0000000..628fca8 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/zicfilp-unlabeled-plt.s @@ -0,0 +1,21 @@ + .text + .globl _start + .type _start,@function +_start: + call foo + call bar + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align 3 +2: .long 0xc0000000 /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x1 /* CFI_LP. */ +4: + .p2align 3 +5: diff --git a/ld/testsuite/ld-s390/pr32969_64-1.dd b/ld/testsuite/ld-s390/pr32969_64-1.dd new file mode 100644 index 0000000..fce262f --- /dev/null +++ b/ld/testsuite/ld-s390/pr32969_64-1.dd @@ -0,0 +1,15 @@ +tmpdir/pr32969_64-1: file format elf64-s390 + +Disassembly of section .text: + +.* <_start>: +.*: c0 10 00 00 00 0e [ ]*larl %r1,10000cc <foo> +.*: c4 18 00 00 08 1d [ ]*lgrl %r1,10010f0 <_GLOBAL_OFFSET_TABLE_\+0x20> + +.* <b>: +.*: c4 18 00 00 08 1a [ ]*lgrl %r1,10010f0 <_GLOBAL_OFFSET_TABLE_\+0x20> +#?.* 07 07 [ ]*nopr %r7 + +.* <c>: +.* c4 18 00 00 08 16 [ ]*lgrl %r1,10010f0 <_GLOBAL_OFFSET_TABLE_\+0x20> +#?.* 07 07 [ ]*nopr %r7 diff --git a/ld/testsuite/ld-s390/pr32969_64-2.dd b/ld/testsuite/ld-s390/pr32969_64-2.dd new file mode 100644 index 0000000..88c770e --- /dev/null +++ b/ld/testsuite/ld-s390/pr32969_64-2.dd @@ -0,0 +1,15 @@ +tmpdir/pr32969_64-2: file format elf64-s390 + +Disassembly of section .text: + +.* <_start>: +.*: c0 10 00 00 00 0e [ ]*larl %r1,10000cc <foo> +.*: c0 10 00 00 00 0c [ ]*larl %r1,10000ce <bar> + +.* <c>: +.*: c0 10 00 00 00 09 [ ]*larl %r1,10000ce <bar> +#?.* 07 07 [ ]*nopr %r7 + +.* <b>: +.* c0 10 00 00 00 05 [ ]*larl %r1,10000ce <bar> +#?.* 07 07 [ ]*nopr %r7 diff --git a/ld/testsuite/ld-s390/pr32969a.s b/ld/testsuite/ld-s390/pr32969a.s new file mode 100644 index 0000000..baee6ca --- /dev/null +++ b/ld/testsuite/ld-s390/pr32969a.s @@ -0,0 +1,14 @@ + .text + .globl _start + .type _start,@function +_start: + lgrl %r1,foo@GOTENT + lgrl %r1,bar@GOTENT + + .section .rodata,"a",@progbits + .align 1 + .globl foo + .type foo,@object +foo: + .byte 0xa + .size foo, .-foo diff --git a/ld/testsuite/ld-s390/pr32969b.s b/ld/testsuite/ld-s390/pr32969b.s new file mode 100644 index 0000000..54ee369 --- /dev/null +++ b/ld/testsuite/ld-s390/pr32969b.s @@ -0,0 +1,10 @@ +b: + lgrl %r1,bar@GOTENT + + .section .rodata,"aG",@progbits,bar_group,comdat + .align 1 + .globl bar + .type bar,@object +bar: + .byte 0xb + .size bar, .-bar diff --git a/ld/testsuite/ld-s390/pr32969c.s b/ld/testsuite/ld-s390/pr32969c.s new file mode 100644 index 0000000..02cf584 --- /dev/null +++ b/ld/testsuite/ld-s390/pr32969c.s @@ -0,0 +1,10 @@ +c: + lgrl %r1,bar@GOTENT + + .section .rodata,"aG",@progbits,bar_group,comdat + .align 2 + .globl bar + .type bar,@object +bar: + .byte 0xc + .size bar, .-bar diff --git a/ld/testsuite/ld-s390/s390.exp b/ld/testsuite/ld-s390/s390.exp index d91eeac..aaba88d 100644 --- a/ld/testsuite/ld-s390/s390.exp +++ b/ld/testsuite/ld-s390/s390.exp @@ -125,6 +125,14 @@ set s390xtests { "-m elf64_s390 tmpdir/libpltlib_64.so" "" "-m64" {plt_64-1.s} {{objdump "-dzrj.plt" plt_64-1.pd} {readelf "-wf" plt_64-1_eh.wf}} "plt_64-1_eh"} + {"PR32969-1: do not rewrite load of misaligned COMDAT symbol address" + "-m elf64_s390" "" "-m64" {pr32969a.s pr32969b.s pr32969c.s} + {{objdump "-dzrj.text" pr32969_64-1.dd}} + "pr32969_64-1"} + {"PR32969-2: rewrite load of aligned COMDAT symbol address" + "-m elf64_s390" "" "-m64" {pr32969a.s pr32969c.s pr32969b.s} + {{objdump "-dzrj.text" pr32969_64-2.dd}} + "pr32969_64-2"} } if [istarget "s390-*-*"] { diff --git a/ld/testsuite/ld-scripts/map-address.exp b/ld/testsuite/ld-scripts/map-address.exp index 2291302..776fed4 100644 --- a/ld/testsuite/ld-scripts/map-address.exp +++ b/ld/testsuite/ld-scripts/map-address.exp @@ -130,19 +130,38 @@ if { [is_elf_format] } { $IMAGE_BASE tmpdir/map-address.o \ -Map=tmpdir/map-locals.map --print-map-locals"]} { fail $testname - return - } - if [is_remote host] then { - remote_upload host "tmpdir/map-locals.map" - } + } else { - # Some ELF targets do not preserve their local symbols. - setup_xfail "d30v-*-*" "dlx-*-*" "pj-*-*" "s12z-*-*" "xgate-*-*" + if [is_remote host] then { + remote_upload host "tmpdir/map-locals.map" + } + + # Some ELF targets do not preserve their local symbols. + setup_xfail "d30v-*-*" "dlx-*-*" "pj-*-*" "s12z-*-*" "xgate-*-*" + if {[regexp_diff \ + "tmpdir/map-locals.map" \ + "$srcdir/$subdir/map-locals.d"]} { + fail $testname + } else { + pass $testname + } + } +} + +set testname "map with resource usage" + +if {![ld_link $ld tmpdir/map-address \ + "$LDFLAGS -T $srcdir/$subdir/map-address.t \ + $IMAGE_BASE tmpdir/map-address.o \ + -Map=tmpdir/map-locals.map \ + --stats=tmpdir/map-stats.map"]} { + fail $testname +} else { if {[regexp_diff \ - "tmpdir/map-locals.map" \ - "$srcdir/$subdir/map-locals.d"]} { + "tmpdir/map-stats.map" \ + "$srcdir/$subdir/map-stats.d"]} { fail $testname } else { pass $testname diff --git a/ld/testsuite/ld-scripts/map-stats.d b/ld/testsuite/ld-scripts/map-stats.d new file mode 100644 index 0000000..ba9adf8 --- /dev/null +++ b/ld/testsuite/ld-scripts/map-stats.d @@ -0,0 +1,5 @@ +#... +Stats: phase.* +Stats: name.* +Stats: ALL.* +#pass diff --git a/ld/testsuite/ld-tic6x/discard-unwind.ld b/ld/testsuite/ld-tic6x/discard-unwind.ld index 00582c1..172e2a8 100644 --- a/ld/testsuite/ld-tic6x/discard-unwind.ld +++ b/ld/testsuite/ld-tic6x/discard-unwind.ld @@ -11,5 +11,5 @@ SECTIONS *(.c6xabi.extab*) } =0 /DISCARD/ : { *(.c6xabi.exidx*) } - .c6xabi.attribues 0 : { *(.c6xabi.atttributes) } + .c6xabi.attributes 0 : { *(.c6xabi.attributes) } } diff --git a/ld/testsuite/ld-tic6x/unwind.ld b/ld/testsuite/ld-tic6x/unwind.ld index a4f8722..01ba9b6 100644 --- a/ld/testsuite/ld-tic6x/unwind.ld +++ b/ld/testsuite/ld-tic6x/unwind.ld @@ -16,5 +16,5 @@ SECTIONS .got : { *(.got) *(.got.plt)} . = 0x12340000; .far : { *(.far) } - .c6xabi.attribues 0 : { *(.c6xabi.atttributes) } + .c6xabi.attributes 0 : { *(.c6xabi.attributes) } } diff --git a/ld/testsuite/ld-x86-64/dwarf4.s b/ld/testsuite/ld-x86-64/dwarf4.s new file mode 100644 index 0000000..7f1a90d --- /dev/null +++ b/ld/testsuite/ld-x86-64/dwarf4.s @@ -0,0 +1,346 @@ +/* Assembly outputs of + +extern void bar(); + +void foo(int p) { + int local = p; + bar(); + local = 123; + bar(); + local = 456; +} + +compiled by GCC 14.2.1 with -O2 -g -dA -gdwarf-4. */ + + .file "dwarf4.c" + .text +.Ltext0: + .file 1 "dwarf4.c" + .p2align 4 + .globl foo + .type foo, @function +foo: +.LVL0: + # DEBUG p => di +.LFB0: + # dwarf4.c:3:17 + .loc 1 3 17 view -0 + .cfi_startproc +# BLOCK 2, count:1073741824 (estimated locally) seq:0 +# PRED: ENTRY [always] count:1073741824 (estimated locally, freq 1.0000) (FALLTHRU) + # dwarf4.c:4:3 + .loc 1 4 3 view .LVU1 + # DEBUG local => di + # dwarf4.c:5:3 + .loc 1 5 3 view .LVU2 + # dwarf4.c:3:17 + .loc 1 3 17 is_stmt 0 view .LVU3 + subq $8, %rsp + .cfi_def_cfa_offset 16 + # dwarf4.c:5:3 + .loc 1 5 3 view .LVU4 + xorl %eax, %eax + call bar +.LVL1: + # DEBUG local => entry_value#0 + # DEBUG p => entry_value#0 + # dwarf4.c:6:3 + .loc 1 6 3 is_stmt 1 view .LVU5 + # DEBUG local => 0x7b + # dwarf4.c:7:3 + .loc 1 7 3 view .LVU6 + xorl %eax, %eax + # dwarf4.c:9:1 + .loc 1 9 1 is_stmt 0 view .LVU7 + addq $8, %rsp + .cfi_def_cfa_offset 8 +# SUCC: EXIT [always] count:1073741824 (estimated locally, freq 1.0000) (ABNORMAL,SIBCALL) + # dwarf4.c:7:3 + .loc 1 7 3 view .LVU8 + jmp bar +.LVL2: + .cfi_endproc +.LFE0: + .size foo, .-foo +.Letext0: + .section .debug_info,"",@progbits +.Ldebug_info0: + .long 0x9e # Length of Compilation Unit Info + .value 0x4 # DWARF version number + .long .Ldebug_abbrev0 # Offset Into Abbrev. Section + .byte 0x8 # Pointer Size (in bytes) + .uleb128 0x1 # (DIE (0xb) DW_TAG_compile_unit) + .long .LASF0 # DW_AT_producer: "GNU C17 14.2.1 20240906 [releases/gcc-14 r14-10649-gaedf6f810ee] -mtune=generic -march=x86-64 -g -gdwarf-4 -O2" + .byte 0xc # DW_AT_language + .long .LASF1 # DW_AT_name: "dwarf4.c" + .long .LASF2 # DW_AT_comp_dir: "." + .quad .Ltext0 # DW_AT_low_pc + .quad .Letext0-.Ltext0 # DW_AT_high_pc + .long .Ldebug_line0 # DW_AT_stmt_list + .uleb128 0x2 # (DIE (0x2d) DW_TAG_subprogram) + # DW_AT_external + .ascii "bar\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (dwarf4.c) + .byte 0x1 # DW_AT_decl_line + .byte 0xd # DW_AT_decl_column + # DW_AT_declaration + .long 0x3b # DW_AT_sibling + .uleb128 0x3 # (DIE (0x39) DW_TAG_unspecified_parameters) + .byte 0 # end of children of DIE 0x2d + .uleb128 0x4 # (DIE (0x3b) DW_TAG_subprogram) + # DW_AT_external + .ascii "foo\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (dwarf4.c) + .byte 0x3 # DW_AT_decl_line + .byte 0x6 # DW_AT_decl_column + # DW_AT_prototyped + .quad .LFB0 # DW_AT_low_pc + .quad .LFE0-.LFB0 # DW_AT_high_pc + .uleb128 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + # DW_AT_GNU_all_call_sites + .long 0x9a # DW_AT_sibling + .uleb128 0x5 # (DIE (0x59) DW_TAG_formal_parameter) + .ascii "p\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (dwarf4.c) + .byte 0x3 # DW_AT_decl_line + .byte 0xe # DW_AT_decl_column + .long 0x9a # DW_AT_type + .long .LLST0 # DW_AT_location + .long .LVUS0 # DW_AT_GNU_locviews + .uleb128 0x6 # (DIE (0x6b) DW_TAG_variable) + .long .LASF3 # DW_AT_name: "local" + .byte 0x1 # DW_AT_decl_file (dwarf4.c) + .byte 0x4 # DW_AT_decl_line + .byte 0x7 # DW_AT_decl_column + .long 0x9a # DW_AT_type + .long .LLST1 # DW_AT_location + .long .LVUS1 # DW_AT_GNU_locviews + .uleb128 0x7 # (DIE (0x7f) DW_TAG_GNU_call_site) + .quad .LVL1 # DW_AT_low_pc + .long 0x2d # DW_AT_abstract_origin + .uleb128 0x8 # (DIE (0x8c) DW_TAG_GNU_call_site) + .quad .LVL2 # DW_AT_low_pc + # DW_AT_GNU_tail_call + .long 0x2d # DW_AT_abstract_origin + .byte 0 # end of children of DIE 0x3b + .uleb128 0x9 # (DIE (0x9a) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .ascii "int\0" # DW_AT_name + .byte 0 # end of children of DIE 0xb + .section .debug_abbrev,"",@progbits +.Ldebug_abbrev0: + .uleb128 0x1 # (abbrev code) + .uleb128 0x11 # (TAG: DW_TAG_compile_unit) + .byte 0x1 # DW_children_yes + .uleb128 0x25 # (DW_AT_producer) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x13 # (DW_AT_language) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x1b # (DW_AT_comp_dir) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x7 # (DW_FORM_data8) + .uleb128 0x10 # (DW_AT_stmt_list) + .uleb128 0x17 # (DW_FORM_sec_offset) + .byte 0 + .byte 0 + .uleb128 0x2 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x1 # DW_children_yes + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3c # (DW_AT_declaration) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x1 # (DW_AT_sibling) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0x3 # (abbrev code) + .uleb128 0x18 # (TAG: DW_TAG_unspecified_parameters) + .byte 0 # DW_children_no + .byte 0 + .byte 0 + .uleb128 0x4 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x1 # DW_children_yes + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x27 # (DW_AT_prototyped) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x7 # (DW_FORM_data8) + .uleb128 0x40 # (DW_AT_frame_base) + .uleb128 0x18 # (DW_FORM_exprloc) + .uleb128 0x2117 # (DW_AT_GNU_all_call_sites) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x1 # (DW_AT_sibling) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0x5 # (abbrev code) + .uleb128 0x5 # (TAG: DW_TAG_formal_parameter) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x17 # (DW_FORM_sec_offset) + .uleb128 0x2137 # (DW_AT_GNU_locviews) + .uleb128 0x17 # (DW_FORM_sec_offset) + .byte 0 + .byte 0 + .uleb128 0x6 # (abbrev code) + .uleb128 0x34 # (TAG: DW_TAG_variable) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x17 # (DW_FORM_sec_offset) + .uleb128 0x2137 # (DW_AT_GNU_locviews) + .uleb128 0x17 # (DW_FORM_sec_offset) + .byte 0 + .byte 0 + .uleb128 0x7 # (abbrev code) + .uleb128 0x4109 # (TAG: DW_TAG_GNU_call_site) + .byte 0 # DW_children_no + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x31 # (DW_AT_abstract_origin) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0x8 # (abbrev code) + .uleb128 0x4109 # (TAG: DW_TAG_GNU_call_site) + .byte 0 # DW_children_no + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x2115 # (DW_AT_GNU_tail_call) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x31 # (DW_AT_abstract_origin) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0x9 # (abbrev code) + .uleb128 0x24 # (TAG: DW_TAG_base_type) + .byte 0 # DW_children_no + .uleb128 0xb # (DW_AT_byte_size) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3e # (DW_AT_encoding) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .byte 0 + .byte 0 + .byte 0 + .section .debug_loc,"",@progbits +.Ldebug_loc0: +.LVUS0: + .uleb128 0 # View list begin (*.LVUS0) + .uleb128 .LVU5 # View list end (*.LVUS0) + .uleb128 .LVU5 # View list begin (*.LVUS0) + .uleb128 0 # View list end (*.LVUS0) +.LLST0: + .quad .LVL0-.Ltext0 # Location list begin address (*.LLST0) + .quad .LVL1-1-.Ltext0 # Location list end address (*.LLST0) + .value 0x1 # Location expression size + .byte 0x55 # DW_OP_reg5 + .quad .LVL1-1-.Ltext0 # Location list begin address (*.LLST0) + .quad .LFE0-.Ltext0 # Location list end address (*.LLST0) + .value 0x4 # Location expression size + .byte 0xf3 # DW_OP_GNU_entry_value + .uleb128 0x1 + .byte 0x55 # DW_OP_reg5 + .byte 0x9f # DW_OP_stack_value + .quad 0 # Location list terminator begin (*.LLST0) + .quad 0 # Location list terminator end (*.LLST0) +.LVUS1: + .uleb128 .LVU2 # View list begin (*.LVUS1) + .uleb128 .LVU5 # View list end (*.LVUS1) + .uleb128 .LVU5 # View list begin (*.LVUS1) + .uleb128 .LVU6 # View list end (*.LVUS1) + .uleb128 .LVU6 # View list begin (*.LVUS1) + .uleb128 0 # View list end (*.LVUS1) +.LLST1: + .quad .LVL0-.Ltext0 # Location list begin address (*.LLST1) + .quad .LVL1-1-.Ltext0 # Location list end address (*.LLST1) + .value 0x1 # Location expression size + .byte 0x55 # DW_OP_reg5 + .quad .LVL1-1-.Ltext0 # Location list begin address (*.LLST1) + .quad .LVL1-.Ltext0 # Location list end address (*.LLST1) + .value 0x4 # Location expression size + .byte 0xf3 # DW_OP_GNU_entry_value + .uleb128 0x1 + .byte 0x55 # DW_OP_reg5 + .byte 0x9f # DW_OP_stack_value + .quad .LVL1-.Ltext0 # Location list begin address (*.LLST1) + .quad .LFE0-.Ltext0 # Location list end address (*.LLST1) + .value 0x3 # Location expression size + .byte 0x8 # DW_OP_const1u + .byte 0x7b + .byte 0x9f # DW_OP_stack_value + .quad 0 # Location list terminator begin (*.LLST1) + .quad 0 # Location list terminator end (*.LLST1) + .section .debug_aranges,"",@progbits + .long 0x2c # Length of Address Ranges Info + .value 0x2 # DWARF aranges version + .long .Ldebug_info0 # Offset of Compilation Unit Info + .byte 0x8 # Size of Address + .byte 0 # Size of Segment Descriptor + .value 0 # Pad to 16 byte boundary + .value 0 + .quad .Ltext0 # Address + .quad .Letext0-.Ltext0 # Length + .quad 0 + .quad 0 + .section .debug_line,"",@progbits +.Ldebug_line0: + .section .debug_str,"MS",@progbits,1 +.LASF0: + .string "GNU C17 14.2.1 20240906 [releases/gcc-14 r14-10649-gaedf6f810ee] -mtune=generic -march=x86-64 -g -gdwarf-4 -O2" +.LASF1: + .string "dwarf4.c" +.LASF3: + .string "local" +.LASF2: + .string "." + .ident "GCC: (GNU) 14.2.1 20240906 [releases/gcc-14 r14-10649-gaedf6f810ee]" + .section .note.GNU-stack,"",@progbits diff --git a/ld/testsuite/ld-x86-64/dwarf5a.s b/ld/testsuite/ld-x86-64/dwarf5a.s new file mode 100644 index 0000000..eefaaf4 --- /dev/null +++ b/ld/testsuite/ld-x86-64/dwarf5a.s @@ -0,0 +1,400 @@ +/* Assembly outputs of + +extern void foo(int); + +int global; + +int main() { + int local = global; + foo(1); + local = 123; + foo(2); + local = 456; + return 0; +} + +compiled by GCC 14.2.1 with -O2 -g -dA -gdwarf-5. */ + + .file "dwarf5a.c" + .text +.Ltext0: + .file 0 "." "dwarf5a.c" + .section .text.startup,"ax",@progbits + .p2align 4 + .globl main + .type main, @function +main: +.LFB0: + .file 1 "dwarf5a.c" + # dwarf5a.c:5:12 + .loc 1 5 12 view -0 + .cfi_startproc +# BLOCK 2, count:1073741824 (estimated locally) seq:0 +# PRED: ENTRY [always] count:1073741824 (estimated locally, freq 1.0000) (FALLTHRU) + # dwarf5a.c:6:3 + .loc 1 6 3 view .LVU1 +.LVL0: + # DEBUG local => [`global'] + # dwarf5a.c:7:3 + .loc 1 7 3 view .LVU2 + # dwarf5a.c:5:12 + .loc 1 5 12 is_stmt 0 view .LVU3 + subq $8, %rsp + .cfi_def_cfa_offset 16 + # dwarf5a.c:7:3 + .loc 1 7 3 view .LVU4 + movl $1, %edi + call foo +.LVL1: + # DEBUG local RESET + # dwarf5a.c:8:3 + .loc 1 8 3 is_stmt 1 view .LVU5 + # DEBUG local => 0x7b + # dwarf5a.c:9:3 + .loc 1 9 3 view .LVU6 + movl $2, %edi + call foo +.LVL2: + # dwarf5a.c:10:3 + .loc 1 10 3 view .LVU7 + # DEBUG local => 0x1c8 + # dwarf5a.c:11:3 + .loc 1 11 3 view .LVU8 + # dwarf5a.c:12:1 + .loc 1 12 1 is_stmt 0 view .LVU9 + xorl %eax, %eax + addq $8, %rsp + .cfi_def_cfa_offset 8 +# SUCC: EXIT [always] count:1073741824 (estimated locally, freq 1.0000) + ret + .cfi_endproc +.LFE0: + .size main, .-main + .globl global + .bss + .align 4 + .type global, @object + .size global, 4 +global: + .zero 4 + .text +.Letext0: + .section .debug_info,"",@progbits +.Ldebug_info0: + .long 0xb3 # Length of Compilation Unit Info + .value 0x5 # DWARF version number + .byte 0x1 # DW_UT_compile + .byte 0x8 # Pointer Size (in bytes) + .long .Ldebug_abbrev0 # Offset Into Abbrev. Section + .uleb128 0x2 # (DIE (0xc) DW_TAG_compile_unit) + .long .LASF4 # DW_AT_producer: "GNU C17 14.2.1 20240906 [releases/gcc-14 r14-10649-gaedf6f810ee] -mtune=generic -march=x86-64 -g -gdwarf-5 -O2" + .byte 0x1d # DW_AT_language + .long .LASF0 # DW_AT_name: "dwarf5a.c" + .long .LASF1 # DW_AT_comp_dir: "." + .long .LLRL1 # DW_AT_ranges + .quad 0 # DW_AT_low_pc + .long .Ldebug_line0 # DW_AT_stmt_list + .uleb128 0x3 # (DIE (0x2a) DW_TAG_variable) + .long .LASF2 # DW_AT_name: "global" + .byte 0x1 # DW_AT_decl_file (dwarf5a.c) + .byte 0x3 # DW_AT_decl_line + .byte 0x5 # DW_AT_decl_column + .long 0x40 # DW_AT_type + # DW_AT_external + .uleb128 0x9 # DW_AT_location + .byte 0x3 # DW_OP_addr + .quad global + .uleb128 0x4 # (DIE (0x40) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .ascii "int\0" # DW_AT_name + .uleb128 0x5 # (DIE (0x47) DW_TAG_subprogram) + # DW_AT_external + .ascii "foo\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (dwarf5a.c) + .byte 0x1 # DW_AT_decl_line + .byte 0xd # DW_AT_decl_column + # DW_AT_prototyped + # DW_AT_declaration + .long 0x59 # DW_AT_sibling + .uleb128 0x6 # (DIE (0x53) DW_TAG_formal_parameter) + .long 0x40 # DW_AT_type + .byte 0 # end of children of DIE 0x47 + .uleb128 0x7 # (DIE (0x59) DW_TAG_subprogram) + # DW_AT_external + .long .LASF5 # DW_AT_name: "main" + .byte 0x1 # DW_AT_decl_file (dwarf5a.c) + .byte 0x5 # DW_AT_decl_line + .byte 0x5 # DW_AT_decl_column + .long 0x40 # DW_AT_type + .quad .LFB0 # DW_AT_low_pc + .quad .LFE0-.LFB0 # DW_AT_high_pc + .uleb128 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + # DW_AT_call_all_calls + .uleb128 0x8 # (DIE (0x77) DW_TAG_variable) + .long .LASF3 # DW_AT_name: "local" + .byte 0x1 # DW_AT_decl_file (dwarf5a.c) + .byte 0x6 # DW_AT_decl_line + .byte 0x7 # DW_AT_decl_column + .long 0x40 # DW_AT_type + .long .LLST0 # DW_AT_location + .long .LVUS0 # DW_AT_GNU_locviews + .uleb128 0x9 # (DIE (0x8b) DW_TAG_call_site) + .quad .LVL1 # DW_AT_call_return_pc + .long 0x47 # DW_AT_call_origin + .long 0xa2 # DW_AT_sibling + .uleb128 0x1 # (DIE (0x9c) DW_TAG_call_site_parameter) + .uleb128 0x1 # DW_AT_location + .byte 0x55 # DW_OP_reg5 + .uleb128 0x1 # DW_AT_call_value + .byte 0x31 # DW_OP_lit1 + .byte 0 # end of children of DIE 0x8b + .uleb128 0xa # (DIE (0xa2) DW_TAG_call_site) + .quad .LVL2 # DW_AT_call_return_pc + .long 0x47 # DW_AT_call_origin + .uleb128 0x1 # (DIE (0xaf) DW_TAG_call_site_parameter) + .uleb128 0x1 # DW_AT_location + .byte 0x55 # DW_OP_reg5 + .uleb128 0x1 # DW_AT_call_value + .byte 0x32 # DW_OP_lit2 + .byte 0 # end of children of DIE 0xa2 + .byte 0 # end of children of DIE 0x59 + .byte 0 # end of children of DIE 0xc + .section .debug_abbrev,"",@progbits +.Ldebug_abbrev0: + .uleb128 0x1 # (abbrev code) + .uleb128 0x49 # (TAG: DW_TAG_call_site_parameter) + .byte 0 # DW_children_no + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x18 # (DW_FORM_exprloc) + .uleb128 0x7e # (DW_AT_call_value) + .uleb128 0x18 # (DW_FORM_exprloc) + .byte 0 + .byte 0 + .uleb128 0x2 # (abbrev code) + .uleb128 0x11 # (TAG: DW_TAG_compile_unit) + .byte 0x1 # DW_children_yes + .uleb128 0x25 # (DW_AT_producer) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x13 # (DW_AT_language) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x1f # (DW_FORM_line_strp) + .uleb128 0x1b # (DW_AT_comp_dir) + .uleb128 0x1f # (DW_FORM_line_strp) + .uleb128 0x55 # (DW_AT_ranges) + .uleb128 0x17 # (DW_FORM_sec_offset) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x10 # (DW_AT_stmt_list) + .uleb128 0x17 # (DW_FORM_sec_offset) + .byte 0 + .byte 0 + .uleb128 0x3 # (abbrev code) + .uleb128 0x34 # (TAG: DW_TAG_variable) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x18 # (DW_FORM_exprloc) + .byte 0 + .byte 0 + .uleb128 0x4 # (abbrev code) + .uleb128 0x24 # (TAG: DW_TAG_base_type) + .byte 0 # DW_children_no + .uleb128 0xb # (DW_AT_byte_size) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3e # (DW_AT_encoding) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .byte 0 + .byte 0 + .uleb128 0x5 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x1 # DW_children_yes + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x27 # (DW_AT_prototyped) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3c # (DW_AT_declaration) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x1 # (DW_AT_sibling) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0x6 # (abbrev code) + .uleb128 0x5 # (TAG: DW_TAG_formal_parameter) + .byte 0 # DW_children_no + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0x7 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x1 # DW_children_yes + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x7 # (DW_FORM_data8) + .uleb128 0x40 # (DW_AT_frame_base) + .uleb128 0x18 # (DW_FORM_exprloc) + .uleb128 0x7a # (DW_AT_call_all_calls) + .uleb128 0x19 # (DW_FORM_flag_present) + .byte 0 + .byte 0 + .uleb128 0x8 # (abbrev code) + .uleb128 0x34 # (TAG: DW_TAG_variable) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x17 # (DW_FORM_sec_offset) + .uleb128 0x2137 # (DW_AT_GNU_locviews) + .uleb128 0x17 # (DW_FORM_sec_offset) + .byte 0 + .byte 0 + .uleb128 0x9 # (abbrev code) + .uleb128 0x48 # (TAG: DW_TAG_call_site) + .byte 0x1 # DW_children_yes + .uleb128 0x7d # (DW_AT_call_return_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x7f # (DW_AT_call_origin) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x1 # (DW_AT_sibling) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0xa # (abbrev code) + .uleb128 0x48 # (TAG: DW_TAG_call_site) + .byte 0x1 # DW_children_yes + .uleb128 0x7d # (DW_AT_call_return_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x7f # (DW_AT_call_origin) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .byte 0 + .section .debug_loclists,"",@progbits + .long .Ldebug_loc3-.Ldebug_loc2 # Length of Location Lists +.Ldebug_loc2: + .value 0x5 # DWARF version number + .byte 0x8 # Address Size + .byte 0 # Segment Size + .long 0 # Offset Entry Count +.Ldebug_loc0: +.LVUS0: + .uleb128 .LVU2 # View list begin (*.LVUS0) + .uleb128 .LVU5 # View list end (*.LVUS0) + .uleb128 .LVU6 # View list begin (*.LVUS0) + .uleb128 .LVU8 # View list end (*.LVUS0) + .uleb128 .LVU8 # View list begin (*.LVUS0) + .uleb128 0 # View list end (*.LVUS0) +.LLST0: + .byte 0x6 # DW_LLE_base_address (*.LLST0) + .quad .LVL0 # Base address (*.LLST0) + .byte 0x4 # DW_LLE_offset_pair (*.LLST0) + .uleb128 .LVL0-.LVL0 # Location list begin address (*.LLST0) + .uleb128 .LVL1-1-.LVL0 # Location list end address (*.LLST0) + .uleb128 0x9 # Location expression size + .byte 0x3 # DW_OP_addr + .quad global + .byte 0x4 # DW_LLE_offset_pair (*.LLST0) + .uleb128 .LVL1-.LVL0 # Location list begin address (*.LLST0) + .uleb128 .LVL2-.LVL0 # Location list end address (*.LLST0) + .uleb128 0x3 # Location expression size + .byte 0x8 # DW_OP_const1u + .byte 0x7b + .byte 0x9f # DW_OP_stack_value + .byte 0x4 # DW_LLE_offset_pair (*.LLST0) + .uleb128 .LVL2-.LVL0 # Location list begin address (*.LLST0) + .uleb128 .LFE0-.LVL0 # Location list end address (*.LLST0) + .uleb128 0x4 # Location expression size + .byte 0xa # DW_OP_const2u + .value 0x1c8 + .byte 0x9f # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list (*.LLST0) +.Ldebug_loc3: + .section .debug_aranges,"",@progbits + .long 0x2c # Length of Address Ranges Info + .value 0x2 # DWARF aranges version + .long .Ldebug_info0 # Offset of Compilation Unit Info + .byte 0x8 # Size of Address + .byte 0 # Size of Segment Descriptor + .value 0 # Pad to 16 byte boundary + .value 0 + .quad .LFB0 # Address + .quad .LFE0-.LFB0 # Length + .quad 0 + .quad 0 + .section .debug_rnglists,"",@progbits +.Ldebug_ranges0: + .long .Ldebug_ranges3-.Ldebug_ranges2 # Length of Range Lists +.Ldebug_ranges2: + .value 0x5 # DWARF version number + .byte 0x8 # Address Size + .byte 0 # Segment Size + .long 0 # Offset Entry Count +.LLRL1: + .byte 0x7 # DW_RLE_start_length (*.LLRL1) + .quad .LFB0 # Range begin address (*.LLRL1) + .uleb128 .LFE0-.LFB0 # Range length (*.LLRL1) + .byte 0 # DW_RLE_end_of_list (*.LLRL1) +.Ldebug_ranges3: + .section .debug_line,"",@progbits +.Ldebug_line0: + .section .debug_str,"MS",@progbits,1 +.LASF3: + .string "local" +.LASF4: + .string "GNU C17 14.2.1 20240906 [releases/gcc-14 r14-10649-gaedf6f810ee] -mtune=generic -march=x86-64 -g -gdwarf-5 -O2" +.LASF2: + .string "global" +.LASF5: + .string "main" + .section .debug_line_str,"MS",@progbits,1 +.LASF0: + .string "dwarf5a.c" +.LASF1: + .string "." + .ident "GCC: (GNU) 14.2.1 20240906 [releases/gcc-14 r14-10649-gaedf6f810ee]" + .section .note.GNU-stack,"",@progbits diff --git a/ld/testsuite/ld-x86-64/dwarf5b.s b/ld/testsuite/ld-x86-64/dwarf5b.s new file mode 100644 index 0000000..4d34469 --- /dev/null +++ b/ld/testsuite/ld-x86-64/dwarf5b.s @@ -0,0 +1,345 @@ +/* Assembly outputs of + +extern void foo(int); + +extern int global; + +void +bar (void) +{ + int local = global; + foo(local); + local = 123; + foo(local); + local = 456; +} + +compiled by GCC 14.2.1 with -O2 -g -dA -gdwarf-5. */ + + .file "dwarf5b.c" + .text +.Ltext0: + .file 0 "." "dwarf5b.c" + .p2align 4 + .globl bar + .type bar, @function +bar: +.LFB0: + .file 1 "dwarf5b.c" + # dwarf5b.c:7:1 + .loc 1 7 1 view -0 + .cfi_startproc +# BLOCK 2, count:1073741824 (estimated locally) seq:0 +# PRED: ENTRY [always] count:1073741824 (estimated locally, freq 1.0000) (FALLTHRU) + # dwarf5b.c:8:3 + .loc 1 8 3 view .LVU1 +.LVL0: + # DEBUG local => [`global'] + # dwarf5b.c:9:3 + .loc 1 9 3 view .LVU2 + # dwarf5b.c:7:1 + .loc 1 7 1 is_stmt 0 view .LVU3 + subq $8, %rsp + .cfi_def_cfa_offset 16 + # dwarf5b.c:9:3 + .loc 1 9 3 view .LVU4 + movl global(%rip), %edi + call foo +.LVL1: + # DEBUG local RESET + # dwarf5b.c:10:3 + .loc 1 10 3 is_stmt 1 view .LVU5 + # DEBUG local => 0x7b + # dwarf5b.c:11:3 + .loc 1 11 3 view .LVU6 + movl $123, %edi + # dwarf5b.c:13:1 + .loc 1 13 1 is_stmt 0 view .LVU7 + addq $8, %rsp + .cfi_def_cfa_offset 8 +# SUCC: EXIT [always] count:1073741824 (estimated locally, freq 1.0000) (ABNORMAL,SIBCALL) + # dwarf5b.c:11:3 + .loc 1 11 3 view .LVU8 + jmp foo +.LVL2: + .cfi_endproc +.LFE0: + .size bar, .-bar +.Letext0: + .section .debug_info,"",@progbits +.Ldebug_info0: + .long 0xa0 # Length of Compilation Unit Info + .value 0x5 # DWARF version number + .byte 0x1 # DW_UT_compile + .byte 0x8 # Pointer Size (in bytes) + .long .Ldebug_abbrev0 # Offset Into Abbrev. Section + .uleb128 0x1 # (DIE (0xc) DW_TAG_compile_unit) + .long .LASF4 # DW_AT_producer: "GNU C17 14.2.1 20240906 [releases/gcc-14 r14-10649-gaedf6f810ee] -mtune=generic -march=x86-64 -g -gdwarf-5 -O2" + .byte 0x1d # DW_AT_language + .long .LASF0 # DW_AT_name: "dwarf5b.c" + .long .LASF1 # DW_AT_comp_dir: "." + .quad .Ltext0 # DW_AT_low_pc + .quad .Letext0-.Ltext0 # DW_AT_high_pc + .long .Ldebug_line0 # DW_AT_stmt_list + .uleb128 0x2 # (DIE (0x2e) DW_TAG_variable) + .long .LASF2 # DW_AT_name: "global" + .byte 0x1 # DW_AT_decl_file (dwarf5b.c) + .byte 0x3 # DW_AT_decl_line + .byte 0xc # DW_AT_decl_column + .long 0x3a # DW_AT_type + # DW_AT_external + # DW_AT_declaration + .uleb128 0x3 # (DIE (0x3a) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .ascii "int\0" # DW_AT_name + .uleb128 0x4 # (DIE (0x41) DW_TAG_subprogram) + # DW_AT_external + .ascii "foo\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (dwarf5b.c) + .byte 0x1 # DW_AT_decl_line + .byte 0xd # DW_AT_decl_column + # DW_AT_prototyped + # DW_AT_declaration + .long 0x53 # DW_AT_sibling + .uleb128 0x5 # (DIE (0x4d) DW_TAG_formal_parameter) + .long 0x3a # DW_AT_type + .byte 0 # end of children of DIE 0x41 + .uleb128 0x6 # (DIE (0x53) DW_TAG_subprogram) + # DW_AT_external + .ascii "bar\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (dwarf5b.c) + .byte 0x6 # DW_AT_decl_line + .byte 0x1 # DW_AT_decl_column + # DW_AT_prototyped + .quad .LFB0 # DW_AT_low_pc + .quad .LFE0-.LFB0 # DW_AT_high_pc + .uleb128 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + # DW_AT_call_all_calls + .uleb128 0x7 # (DIE (0x6d) DW_TAG_variable) + .long .LASF3 # DW_AT_name: "local" + .byte 0x1 # DW_AT_decl_file (dwarf5b.c) + .byte 0x8 # DW_AT_decl_line + .byte 0x7 # DW_AT_decl_column + .long 0x3a # DW_AT_type + .long .LLST0 # DW_AT_location + .long .LVUS0 # DW_AT_GNU_locviews + .uleb128 0x8 # (DIE (0x81) DW_TAG_call_site) + .quad .LVL1 # DW_AT_call_return_pc + .long 0x41 # DW_AT_call_origin + .uleb128 0x9 # (DIE (0x8e) DW_TAG_call_site) + .quad .LVL2 # DW_AT_call_return_pc + # DW_AT_call_tail_call + .long 0x41 # DW_AT_call_origin + .uleb128 0xa # (DIE (0x9b) DW_TAG_call_site_parameter) + .uleb128 0x1 # DW_AT_location + .byte 0x55 # DW_OP_reg5 + .uleb128 0x2 # DW_AT_call_value + .byte 0x8 # DW_OP_const1u + .byte 0x7b + .byte 0 # end of children of DIE 0x8e + .byte 0 # end of children of DIE 0x53 + .byte 0 # end of children of DIE 0xc + .section .debug_abbrev,"",@progbits +.Ldebug_abbrev0: + .uleb128 0x1 # (abbrev code) + .uleb128 0x11 # (TAG: DW_TAG_compile_unit) + .byte 0x1 # DW_children_yes + .uleb128 0x25 # (DW_AT_producer) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x13 # (DW_AT_language) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x1f # (DW_FORM_line_strp) + .uleb128 0x1b # (DW_AT_comp_dir) + .uleb128 0x1f # (DW_FORM_line_strp) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x7 # (DW_FORM_data8) + .uleb128 0x10 # (DW_AT_stmt_list) + .uleb128 0x17 # (DW_FORM_sec_offset) + .byte 0 + .byte 0 + .uleb128 0x2 # (abbrev code) + .uleb128 0x34 # (TAG: DW_TAG_variable) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3c # (DW_AT_declaration) + .uleb128 0x19 # (DW_FORM_flag_present) + .byte 0 + .byte 0 + .uleb128 0x3 # (abbrev code) + .uleb128 0x24 # (TAG: DW_TAG_base_type) + .byte 0 # DW_children_no + .uleb128 0xb # (DW_AT_byte_size) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3e # (DW_AT_encoding) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .byte 0 + .byte 0 + .uleb128 0x4 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x1 # DW_children_yes + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x27 # (DW_AT_prototyped) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3c # (DW_AT_declaration) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x1 # (DW_AT_sibling) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0x5 # (abbrev code) + .uleb128 0x5 # (TAG: DW_TAG_formal_parameter) + .byte 0 # DW_children_no + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0x6 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x1 # DW_children_yes + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x27 # (DW_AT_prototyped) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x7 # (DW_FORM_data8) + .uleb128 0x40 # (DW_AT_frame_base) + .uleb128 0x18 # (DW_FORM_exprloc) + .uleb128 0x7a # (DW_AT_call_all_calls) + .uleb128 0x19 # (DW_FORM_flag_present) + .byte 0 + .byte 0 + .uleb128 0x7 # (abbrev code) + .uleb128 0x34 # (TAG: DW_TAG_variable) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x17 # (DW_FORM_sec_offset) + .uleb128 0x2137 # (DW_AT_GNU_locviews) + .uleb128 0x17 # (DW_FORM_sec_offset) + .byte 0 + .byte 0 + .uleb128 0x8 # (abbrev code) + .uleb128 0x48 # (TAG: DW_TAG_call_site) + .byte 0 # DW_children_no + .uleb128 0x7d # (DW_AT_call_return_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x7f # (DW_AT_call_origin) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0x9 # (abbrev code) + .uleb128 0x48 # (TAG: DW_TAG_call_site) + .byte 0x1 # DW_children_yes + .uleb128 0x7d # (DW_AT_call_return_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x82 # (DW_AT_call_tail_call) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x7f # (DW_AT_call_origin) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0xa # (abbrev code) + .uleb128 0x49 # (TAG: DW_TAG_call_site_parameter) + .byte 0 # DW_children_no + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x18 # (DW_FORM_exprloc) + .uleb128 0x7e # (DW_AT_call_value) + .uleb128 0x18 # (DW_FORM_exprloc) + .byte 0 + .byte 0 + .byte 0 + .section .debug_loclists,"",@progbits + .long .Ldebug_loc3-.Ldebug_loc2 # Length of Location Lists +.Ldebug_loc2: + .value 0x5 # DWARF version number + .byte 0x8 # Address Size + .byte 0 # Segment Size + .long 0 # Offset Entry Count +.Ldebug_loc0: +.LVUS0: + .uleb128 .LVU6 # View list begin (*.LVUS0) + .uleb128 0 # View list end (*.LVUS0) +.LLST0: + .byte 0x4 # DW_LLE_offset_pair (*.LLST0) + .uleb128 .LVL1-.Ltext0 # Location list begin address (*.LLST0) + .uleb128 .LFE0-.Ltext0 # Location list end address (*.LLST0) + .uleb128 0x3 # Location expression size + .byte 0x8 # DW_OP_const1u + .byte 0x7b + .byte 0x9f # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list (*.LLST0) +.Ldebug_loc3: + .section .debug_aranges,"",@progbits + .long 0x2c # Length of Address Ranges Info + .value 0x2 # DWARF aranges version + .long .Ldebug_info0 # Offset of Compilation Unit Info + .byte 0x8 # Size of Address + .byte 0 # Size of Segment Descriptor + .value 0 # Pad to 16 byte boundary + .value 0 + .quad .Ltext0 # Address + .quad .Letext0-.Ltext0 # Length + .quad 0 + .quad 0 + .section .debug_line,"",@progbits +.Ldebug_line0: + .section .debug_str,"MS",@progbits,1 +.LASF3: + .string "local" +.LASF4: + .string "GNU C17 14.2.1 20240906 [releases/gcc-14 r14-10649-gaedf6f810ee] -mtune=generic -march=x86-64 -g -gdwarf-5 -O2" +.LASF2: + .string "global" + .section .debug_line_str,"MS",@progbits,1 +.LASF1: + .string "." +.LASF0: + .string "dwarf5b.c" + .ident "GCC: (GNU) 14.2.1 20240906 [releases/gcc-14 r14-10649-gaedf6f810ee]" + .section .note.GNU-stack,"",@progbits diff --git a/ld/testsuite/ld-x86-64/pr32809.d b/ld/testsuite/ld-x86-64/pr32809.d new file mode 100644 index 0000000..3affc23 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr32809.d @@ -0,0 +1,71 @@ +#source: dwarf5a.s +#source: dwarf4.s +#source: dwarf5b.s +#as: --64 +#ld: -r -m elf_x86_64 +#readelf: --wide --debug-dump=loc + +Contents of the .*ebug_loc section: + + Offset Begin End Expression + + 00000000 v000000000000000 v000000000000000 location view pair + 00000002 v000000000000000 v000000000000000 location view pair + + 00000004 v000000000000000 v000000000000000 views at 00000000 for: + 0000000000000000 000000000000000a \(DW_OP_reg5 \(rdi\)\) + 00000017 v000000000000000 v000000000000000 views at 00000002 for: + 000000000000000a 0000000000000016 \(DW_OP_GNU_entry_value: \(DW_OP_reg5 \(rdi\)\); DW_OP_stack_value\) + 0000002d <End of list> + + 0000003d v000000000000002 v000000000000000 location view pair + 0000003f v000000000000000 v000000000000001 location view pair + 00000041 v000000000000001 v000000000000000 location view pair + + 00000043 v000000000000002 v000000000000000 views at 0000003d for: + 0000000000000000 000000000000000a \(DW_OP_reg5 \(rdi\)\) + 00000056 v000000000000000 v000000000000001 views at 0000003f for: + 000000000000000a 000000000000000b \(DW_OP_GNU_entry_value: \(DW_OP_reg5 \(rdi\)\); DW_OP_stack_value\) + 0000006c v000000000000001 v000000000000000 views at 00000041 for: + 000000000000000b 0000000000000016 \(DW_OP_const1u: 123; DW_OP_stack_value\) + 00000081 <End of list> + +Contents of the .*ebug_loclists section: + +Table at Offset 0 + Length: 0x34 + DWARF version: 5 + Address size: 8 + Segment size: 0 + Offset entries: 0 + + Offset Begin End Expression + + 0000000c v000000000000002 v000000000000000 location view pair + 0000000e v000000000000001 v000000000000001 location view pair + 00000010 v000000000000001 v000000000000000 location view pair + + 00000012 0000000000000000 \(base address\) + 0000001b v000000000000002 v000000000000000 views at 0000000c for: + 0000000000000000 000000000000000d \(DW_OP_addr: 0\) + 00000028 v000000000000001 v000000000000001 views at 0000000e for: + 000000000000000e 0000000000000018 \(DW_OP_const1u: 123; DW_OP_stack_value\) + 0000002f v000000000000001 v000000000000000 views at 00000010 for: + 0000000000000018 000000000000001f \(DW_OP_const2u: 456; DW_OP_stack_value\) + 00000037 <End of list> +Table at Offset 0x38 + Length: 0x12 + DWARF version: 5 + Address size: 8 + Segment size: 0 + Offset entries: 0 + + Offset Begin End Expression + + 00000044 v000000000000001 v000000000000000 location view pair + + 00000046 v000000000000001 v000000000000000 views at 00000044 for: + 000000000000002f 000000000000003d \(DW_OP_const1u: 123; DW_OP_stack_value\) + 0000004d <End of list> + +#pass diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 52c4d5e..3bb88ff 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -563,6 +563,7 @@ run_dump_test "pr32591-3" run_dump_test "pr32591-3-x32" run_dump_test "pr32591-4" run_dump_test "pr32591-4-x32" +run_dump_test "pr32809" if { ![skip_sframe_tests] } { run_dump_test "sframe-simple-1" diff --git a/ld/testsuite/lib/ld-lib.exp b/ld/testsuite/lib/ld-lib.exp index 9615271..119410b 100644 --- a/ld/testsuite/lib/ld-lib.exp +++ b/ld/testsuite/lib/ld-lib.exp @@ -860,14 +860,15 @@ proc run_ld_link_exec_tests { ldtests args } { } # List contains test-items with 3 items followed by 2 lists, one item and -# one optional item: +# 2 optional items: # 0:name -# 1:ld or ar options +# 1:leading ld or ar options # 2:compile options # 3:filenames of source files # 4:action and options. # 5:name of output file # 6:language (optional) +# 7:trailing ld options (optional), placed after object files # # Actions: # objdump: Apply objdump options on result. Compare with regex (last arg). @@ -899,6 +900,7 @@ proc run_cc_link_tests { ldtests } { set actions [lindex $testitem 4] set binfile tmpdir/[lindex $testitem 5] set lang [lindex $testitem 6] + set trailing_ldflags [lindex $testitem 7] set objfiles {} set is_unresolved 0 set failed 0 @@ -927,6 +929,7 @@ proc run_cc_link_tests { ldtests } { #verbose -log "actions is $actions" #verbose -log "binfile is $binfile" #verbose -log "lang is $lang" + #verbose -log "trailing_ldflags is $trailing_ldflags" foreach actionlist $actions { set action [lindex $actionlist 0] @@ -1006,7 +1009,7 @@ proc run_cc_link_tests { ldtests } { untested $testname continue } - ld_link $cc_cmd $binfile "-L$srcdir/$subdir $ldflags $objfiles" + ld_link $cc_cmd $binfile "-L$srcdir/$subdir $ldflags $objfiles $trailing_ldflags" set ld_output "$exec_output" if { $check_ld(source) == "regexp" } then { |