aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
Diffstat (limited to 'ld')
-rw-r--r--ld/config.in3
-rwxr-xr-xld/configure291
-rw-r--r--ld/configure.ac6
-rw-r--r--ld/emultempl/emulation.em3
-rw-r--r--ld/emultempl/kvxelf.em14
-rw-r--r--ld/emultempl/pe.em50
-rw-r--r--ld/ld.texi4
-rw-r--r--ld/ldemul.c8
-rw-r--r--ld/ldemul.h8
-rw-r--r--ld/ldlang.c34
-rw-r--r--ld/testsuite/ld-elf/tbss4.d13
-rw-r--r--ld/testsuite/ld-elf/tbss4.s25
-rw-r--r--ld/testsuite/ld-plugin/pr25618a.h1
-rw-r--r--ld/testsuite/ld-plugin/pr25618b.h1
-rw-r--r--ld/testsuite/ld-x86-64/dwarf4.s346
-rw-r--r--ld/testsuite/ld-x86-64/dwarf5a.s400
-rw-r--r--ld/testsuite/ld-x86-64/dwarf5b.s345
-rw-r--r--ld/testsuite/ld-x86-64/pr32809.d71
-rw-r--r--ld/testsuite/ld-x86-64/x86-64.exp1
19 files changed, 1334 insertions, 290 deletions
diff --git a/ld/config.in b/ld/config.in
index e10c9e7..3781224 100644
--- a/ld/config.in
+++ b/ld/config.in
@@ -234,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 3f745ac..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.
@@ -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 1ee0c0c..e5f56dd 100644
--- a/ld/configure.ac
+++ b/ld/configure.ac
@@ -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 50bb082..b522687 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -2448,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)
@@ -2526,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/ld.texi b/ld/ld.texi
index e8e09f8..ea4536a 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -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},...
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 97fdb91..e036817 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -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)
{
@@ -4184,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);
}
}
@@ -4892,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;
@@ -4939,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);
@@ -7234,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;
}
@@ -7255,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;
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-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-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"