diff options
76 files changed, 2412 insertions, 1355 deletions
diff --git a/Makefile.def b/Makefile.def index 4896c5c..93485c7 100644 --- a/Makefile.def +++ b/Makefile.def @@ -523,7 +523,7 @@ dependencies = { module=install-bfd; on=install-libsframe; }; dependencies = { module=install-strip-bfd; on=install-strip-libsframe; }; // libopcodes depends on libbfd -dependencies = { module=configure-opcodes; on=configure-bfd; hard=true; }; +dependencies = { module=configure-opcodes; on=all-bfd; hard=true; }; dependencies = { module=install-opcodes; on=install-bfd; }; dependencies = { module=install-strip-opcodes; on=install-strip-bfd; }; @@ -549,8 +549,8 @@ dependencies = { module=install-gprofng; on=install-opcodes; }; dependencies = { module=install-gprofng; on=install-bfd; }; dependencies = { module=configure-ld; on=configure-gettext; }; +dependencies = { module=configure-ld; on=all-bfd; }; dependencies = { module=all-ld; on=all-libiberty; }; -dependencies = { module=all-ld; on=all-bfd; }; dependencies = { module=all-ld; on=all-opcodes; }; dependencies = { module=all-ld; on=all-build-bison; }; dependencies = { module=all-ld; on=all-build-flex; }; diff --git a/Makefile.in b/Makefile.in index f12c251..2a53616 100644 --- a/Makefile.in +++ b/Makefile.in @@ -67369,16 +67369,16 @@ install-strip-ld: maybe-install-strip-bfd install-strip-ld: maybe-install-strip-libctf install-bfd: maybe-install-libsframe install-strip-bfd: maybe-install-strip-libsframe -configure-opcodes: configure-bfd -configure-stage1-opcodes: configure-stage1-bfd -configure-stage2-opcodes: configure-stage2-bfd -configure-stage3-opcodes: configure-stage3-bfd -configure-stage4-opcodes: configure-stage4-bfd -configure-stageprofile-opcodes: configure-stageprofile-bfd -configure-stagetrain-opcodes: configure-stagetrain-bfd -configure-stagefeedback-opcodes: configure-stagefeedback-bfd -configure-stageautoprofile-opcodes: configure-stageautoprofile-bfd -configure-stageautofeedback-opcodes: configure-stageautofeedback-bfd +configure-opcodes: all-bfd +configure-stage1-opcodes: all-stage1-bfd +configure-stage2-opcodes: all-stage2-bfd +configure-stage3-opcodes: all-stage3-bfd +configure-stage4-opcodes: all-stage4-bfd +configure-stageprofile-opcodes: all-stageprofile-bfd +configure-stagetrain-opcodes: all-stagetrain-bfd +configure-stagefeedback-opcodes: all-stagefeedback-bfd +configure-stageautoprofile-opcodes: all-stageautoprofile-bfd +configure-stageautofeedback-opcodes: all-stageautofeedback-bfd install-opcodes: maybe-install-bfd install-strip-opcodes: maybe-install-strip-bfd configure-gas: maybe-configure-gettext @@ -67443,6 +67443,16 @@ configure-stagetrain-ld: maybe-configure-stagetrain-gettext configure-stagefeedback-ld: maybe-configure-stagefeedback-gettext configure-stageautoprofile-ld: maybe-configure-stageautoprofile-gettext configure-stageautofeedback-ld: maybe-configure-stageautofeedback-gettext +configure-ld: maybe-all-bfd +configure-stage1-ld: maybe-all-stage1-bfd +configure-stage2-ld: maybe-all-stage2-bfd +configure-stage3-ld: maybe-all-stage3-bfd +configure-stage4-ld: maybe-all-stage4-bfd +configure-stageprofile-ld: maybe-all-stageprofile-bfd +configure-stagetrain-ld: maybe-all-stagetrain-bfd +configure-stagefeedback-ld: maybe-all-stagefeedback-bfd +configure-stageautoprofile-ld: maybe-all-stageautoprofile-bfd +configure-stageautofeedback-ld: maybe-all-stageautofeedback-bfd all-ld: maybe-all-libiberty all-stage1-ld: maybe-all-stage1-libiberty all-stage2-ld: maybe-all-stage2-libiberty @@ -67453,16 +67463,6 @@ all-stagetrain-ld: maybe-all-stagetrain-libiberty all-stagefeedback-ld: maybe-all-stagefeedback-libiberty all-stageautoprofile-ld: maybe-all-stageautoprofile-libiberty all-stageautofeedback-ld: maybe-all-stageautofeedback-libiberty -all-ld: maybe-all-bfd -all-stage1-ld: maybe-all-stage1-bfd -all-stage2-ld: maybe-all-stage2-bfd -all-stage3-ld: maybe-all-stage3-bfd -all-stage4-ld: maybe-all-stage4-bfd -all-stageprofile-ld: maybe-all-stageprofile-bfd -all-stagetrain-ld: maybe-all-stagetrain-bfd -all-stagefeedback-ld: maybe-all-stagefeedback-bfd -all-stageautoprofile-ld: maybe-all-stageautoprofile-bfd -all-stageautofeedback-ld: maybe-all-stageautofeedback-bfd all-ld: maybe-all-opcodes all-stage1-ld: maybe-all-stage1-opcodes all-stage2-ld: maybe-all-stage2-opcodes diff --git a/bfd/Makefile.in b/bfd/Makefile.in index 1543af7..8a670ad 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -113,7 +113,6 @@ target_triplet = @target@ subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ - $(top_srcdir)/../config/bfd64.m4 \ $(top_srcdir)/../config/depstand.m4 \ $(top_srcdir)/../config/gettext-sister.m4 \ $(top_srcdir)/../config/gettext.m4 \ diff --git a/bfd/aclocal.m4 b/bfd/aclocal.m4 index 8364b5d..4d1b7ba 100644 --- a/bfd/aclocal.m4 +++ b/bfd/aclocal.m4 @@ -1168,7 +1168,6 @@ AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([../config/acx.m4]) -m4_include([../config/bfd64.m4]) m4_include([../config/depstand.m4]) m4_include([../config/gettext-sister.m4]) m4_include([../config/gettext.m4]) diff --git a/bfd/configure b/bfd/configure index ca7f66f..f69df12 100755 --- a/bfd/configure +++ b/bfd/configure @@ -702,8 +702,6 @@ REPORT_BUGS_TEXI REPORT_BUGS_TO PKGVERSION DEBUGDIR -ENABLE_BFD_64_BIT_FALSE -ENABLE_BFD_64_BIT_TRUE PLUGINS_FALSE PLUGINS_TRUE LARGEFILE_CPPFLAGS @@ -11155,7 +11153,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11158 "configure" +#line 11156 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11261,7 +11259,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11264 "configure" +#line 11262 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11930,56 +11928,6 @@ 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 -_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='#' -else - ENABLE_BFD_64_BIT_TRUE='#' - ENABLE_BFD_64_BIT_FALSE= -fi - - if test $enable_64_bit_bfd = yes ; then want64=true else @@ -17677,10 +17625,6 @@ if test -z "${PLUGINS_TRUE}" && test -z "${PLUGINS_FALSE}"; then as_fn_error $? "conditional \"PLUGINS\" 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 "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/bfd/configure.ac b/bfd/configure.ac index 90fad54..e9942d2 100644 --- a/bfd/configure.ac +++ b/bfd/configure.ac @@ -81,7 +81,13 @@ if test x$ac_checking != x ; then AC_DEFINE(ENABLE_CHECKING, 1, [Define if you want run-time sanity checks.]) fi -BFD_64_BIT +AC_ARG_ENABLE(64-bit-bfd, + AS_HELP_STRING([--enable-64-bit-bfd], + [64-bit support (on hosts with narrower word sizes)]), + [AS_CASE([$enableval], + [yes|no], [], + [*], [AC_MSG_ERROR(bad value ${enableval} for 64-bit-bfd option)])], + [enable_64_bit_bfd=no]) if test $enable_64_bit_bfd = yes ; then want64=true else @@ -6292,27 +6292,28 @@ assign_file_positions_for_load_sections (bfd *abfd, } else { - if (p->p_type == PT_LOAD) - { - this_hdr->sh_offset = sec->filepos = off; - if (this_hdr->sh_type != SHT_NOBITS) - off += this_hdr->sh_size; - } - else if (this_hdr->sh_type == SHT_NOBITS - && (this_hdr->sh_flags & SHF_TLS) != 0 - && this_hdr->sh_offset == 0) + if (this_hdr->sh_type == SHT_NOBITS + && (this_hdr->sh_flags & SHF_TLS) != 0 + && this_hdr->sh_offset == 0) { - /* This is a .tbss section that didn't get a PT_LOAD. - (See _bfd_elf_map_sections_to_segments "Create a - final PT_LOAD".) Set sh_offset to the value it - would have if we had created a zero p_filesz and - p_memsz PT_LOAD header for the section. This - also makes the PT_TLS header have the same - p_offset value. */ + /* Set sh_offset for .tbss sections to their nominal + offset after aligning. They are not loaded from + disk so the value doesn't really matter, except + when the .tbss section is the first one in a + PT_TLS segment. In that case it sets the + p_offset for the PT_TLS segment, which according + to the ELF gABI ought to satisfy + p_offset % p_align == p_vaddr % p_align. */ bfd_vma adjust = vma_page_aligned_bias (this_hdr->sh_addr, off, align); this_hdr->sh_offset = sec->filepos = off + adjust; } + else if (p->p_type == PT_LOAD) + { + this_hdr->sh_offset = sec->filepos = off; + if (this_hdr->sh_type != SHT_NOBITS) + off += this_hdr->sh_size; + } if (this_hdr->sh_type != SHT_NOBITS) { diff --git a/bfd/version.h b/bfd/version.h index 61a84a9..2e4741a 100644 --- a/bfd/version.h +++ b/bfd/version.h @@ -16,7 +16,7 @@ In releases, the date is not included in either version strings or sonames. */ -#define BFD_VERSION_DATE 20250426 +#define BFD_VERSION_DATE 20250429 #define BFD_VERSION @bfd_version@ #define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@ #define REPORT_BUGS_TO @report_bugs_to@ diff --git a/binutils/MAINTAINERS b/binutils/MAINTAINERS index 2aaadc8..7b50393 100644 --- a/binutils/MAINTAINERS +++ b/binutils/MAINTAINERS @@ -118,6 +118,7 @@ responsibility among the other maintainers. OR1K Stefan Kristiansson <stefan.kristiansson@saunalahti.fi> OR1K Stafford Horne <shorne@gmail.com> PPC Peter Bergner <bergner@linux.ibm.com> + PPC Surya Kumari Jangala <jskumari@linux.ibm.com> PPC vector ext Aldy Hernandez <aldyh@redhat.com> RISC-V Palmer Dabbelt <palmer@dabbelt.com> RISC-V Andrew Waterman <andrew@sifive.com> diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 08bb623..fb09b86 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -7324,7 +7324,7 @@ display_debug_loc (struct dwarf_section *section, void *file) unsigned int *array = NULL; const char *suffix = strrchr (section->name, '.'); bool is_dwo = false; - int is_loclists = strstr (section->name, "debug_loclists") != NULL; + bool is_loclists = strstr (section->name, "debug_loclists") != NULL; uint64_t next_header_offset = 0; if (suffix && strcmp (suffix, ".dwo") == 0) @@ -7450,6 +7450,16 @@ display_debug_loc (struct dwarf_section *section, void *file) debug_info *debug_info_p = debug_information + i; uint32_t offset_count; + /* .debug_loclists section is loaded into debug_information as + DWARF-5 debug info and .debug_loc section is loaded into + debug_information as pre-DWARF-5 debug info. When dumping + .debug_loc section, we should only process pre-DWARF-5 debug + info in debug_information. When dumping .debug_loclists + section, we should only process DWARF-5 info in + debug_information. */ + if ((debug_info_p->dwarf_version >= 5) != is_loclists) + continue; + if (!locs_sorted) { for (k = 0; k < debug_info_p->num_loc_offsets; k++) @@ -7462,7 +7472,7 @@ display_debug_loc (struct dwarf_section *section, void *file) /* .debug_loclists has a per-unit header. Update start if we are detecting it. */ - if (debug_info_p->dwarf_version == 5) + if (debug_info_p->dwarf_version >= 5) { j = locs_sorted ? 0 : array [0]; diff --git a/config/bfd64.m4 b/config/bfd64.m4 index d134f1a..d816f7f 100644 --- a/config/bfd64.m4 +++ b/config/bfd64.m4 @@ -16,21 +16,25 @@ dnl along with this program; see the file COPYING3. If not see dnl <http://www.gnu.org/licenses/>. dnl -dnl See whether 64-bit bfd lib has been enabled. +dnl Make sure your module depends on `all-bfd' when invoking this macro. AC_DEFUN([BFD_64_BIT], [dnl -AC_ARG_ENABLE(64-bit-bfd, - AS_HELP_STRING([--enable-64-bit-bfd], - [64-bit support (on hosts with narrower word sizes)]), - [AS_CASE([$enableval], - [yes|no], [], - [*], [AC_MSG_ERROR(bad value ${enableval} for 64-bit-bfd option)])], - [enable_64_bit_bfd=no]) - -dnl If the host is 64-bit, then 64-bit bfd is enabled automatically. -AS_IF([test "x$enable_64_bit_bfd" = "xno"], [dnl - AC_CHECK_SIZEOF(void *) - AS_IF([test "x$ac_cv_sizeof_void_p" = "x8"], [enable_64_bit_bfd=yes]) -]) - -AM_CONDITIONAL([ENABLE_BFD_64_BIT], [test "x$enable_64_bit_bfd" = "xyes"]) -]) +# 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. +AC_MSG_CHECKING([whether BFD is 64-bit]) +AC_EGREP_CPP([HAVE_BFD64], + AC_LANG_PROGRAM( + [#include "bfd.h"], + [dnl +#ifdef BFD64 +HAVE_BFD64 +#endif]), + [have_64_bit_bfd=yes], + [have_64_bit_bfd=no]) +AC_MSG_RESULT([$have_64_bit_bfd]) +CPPFLAGS=$OLD_CPPFLAGS]) diff --git a/gas/testsuite/gas/ppc/future.d b/gas/testsuite/gas/ppc/future.d index 76a30a5..5c008b5 100644 --- a/gas/testsuite/gas/ppc/future.d +++ b/gas/testsuite/gas/ppc/future.d @@ -57,4 +57,39 @@ Disassembly of section \.text: .*: (d0 1e 22 f0|f0 22 1e d0) xxgfmul128gcm vs1,vs2,vs3 .*: (d6 0f e0 f3|f3 e0 0f d6) xxgfmul128xts vs31,vs32,vs33 .*: (d6 0f e0 f3|f3 e0 0f d6) xxgfmul128xts vs31,vs32,vs33 +.*: (06 00 00 00|00 00 00 06) paddis r12,r9,15 +.*: (3d 89 00 0f|0f 00 89 3d) +.*: (06 00 00 00|00 00 00 06) paddis r12,r9,15 +.*: (3d 89 00 0f|0f 00 89 3d) +.*: (06 00 ff ff|ff ff 00 06) paddis r12,r9,-32769 +.*: (3d 89 7f ff|ff 7f 89 3d) +.*: (06 00 ff ff|ff ff 00 06) paddis r12,r9,-32769 +.*: (3d 89 7f ff|ff 7f 89 3d) +.*: (06 10 00 00|00 00 10 06) paddis r9,0,25,1 # e4 +.*: (3d 20 00 19|19 00 20 3d) +.*: (06 00 7f ff|ff 7f 00 06) plis r24,2147483647 +.*: (3f 00 ff ff|ff ff 00 3f) +.*: (06 00 7f ff|ff 7f 00 06) plis r24,2147483647 +.*: (3f 00 ff ff|ff ff 00 3f) +.*: (60 00 00 00|00 00 00 60) nop +.*: (06 00 7f ff|ff 7f 00 06) plis r24,2147483647 +.*: (3f 00 ff ff|ff ff 00 3f) +.*: (06 00 80 00|00 80 00 06) paddis r30,r10,-2147483648 +.*: (3f ca 00 00|00 00 ca 3f) +.*: (06 00 80 00|00 80 00 06) paddis r30,r10,-2147483648 +.*: (3f ca 00 00|00 00 ca 3f) +.*: (06 00 80 00|00 80 00 06) paddis r30,r10,-2147483648 +.*: (3f ca 00 00|00 00 ca 3f) +.*: (60 00 00 00|00 00 00 60) nop +.*: (06 00 7f ff|ff 7f 00 06) paddis r30,r10,2147483647 +.*: (3f ca ff ff|ff ff ca 3f) +.*: (06 00 7f ff|ff 7f 00 06) paddis r30,r10,2147483647 +.*: (3f ca ff ff|ff ff ca 3f) +.*: (06 00 7f ff|ff 7f 00 06) paddis r30,r10,2147483647 +.*: (3f ca ff ff|ff ff ca 3f) +.*: (60 00 00 00|00 00 00 60) nop +.*: (06 10 7f ff|ff 7f 10 06) paddis r15,0,2147483647,1 # 140 +.* (3d e0 ff ff|ff ff e0 3d) +.*: (06 10 7f ff|ff 7f 10 06) paddis r15,0,2147483647,1 # 148 +.* (3d e0 ff ff|ff ff e0 3d) #pass diff --git a/gas/testsuite/gas/ppc/future.s b/gas/testsuite/gas/ppc/future.s index fec99e3..55867de 100644 --- a/gas/testsuite/gas/ppc/future.s +++ b/gas/testsuite/gas/ppc/future.s @@ -49,3 +49,21 @@ _start: xxgfmul128gcm 1, 2, 3 xxgfmul128 31, 32, 33, 1 xxgfmul128xts 31, 32, 33 + paddis 12, 9, 15, 0 + paddis 12, 9, 15 + paddis 12, 9, ~(1<<15), 0 + paddis 12, 9, ~(1<<15) + paddis 9, 0, 25, 1 + paddis 24, 0, 2147483647, 0 + paddis 24, 0, 2147483647 + plis 24, 2147483647 + paddis 30, 10, -2147483648, 0 + paddis 30, 10, -2147483648 + psubis 30, 10, 2147483648, 0 + nop + paddis 30, 10, 2147483647, 0 + paddis 30, 10, 2147483647 + psubis 30, 10, -2147483647, 0 + paddis 15, 0, 2147483647, 1 + psubis 15, 0, -2147483647, 1 + diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 9f21695..77e03e4 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1098,7 +1098,6 @@ COMMON_SFILES = \ dwarf2/ada-imported.c \ dwarf2/aranges.c \ dwarf2/attribute.c \ - dwarf2/comp-unit-head.c \ dwarf2/cooked-index.c \ dwarf2/cooked-index-entry.c \ dwarf2/cooked-index-shard.c \ @@ -1123,6 +1122,7 @@ COMMON_SFILES = \ dwarf2/read-gdb-index.c \ dwarf2/section.c \ dwarf2/stringify.c \ + dwarf2/unit-head.c \ extract-store-integer.c \ eval.c \ event-top.c \ @@ -17,7 +17,7 @@ Unpacking and Installation -- quick overview 'gdb-VERSION.tar.gz', where VERSION is the version of GDB. The GDB debugger sources, the generic GNU include -files, the BFD ("binary file description") library, the readline +files, the BFD ("Binary File Descriptor") library, the readline library, and other libraries all have directories of their own underneath the gdb-VERSION directory. The idea is that a variety of GNU tools can share a common copy of these things. Be aware of variation diff --git a/gdb/bt-utils.c b/gdb/bt-utils.c index 8e78245..922402e 100644 --- a/gdb/bt-utils.c +++ b/gdb/bt-utils.c @@ -40,6 +40,17 @@ gdb_internal_backtrace_set_cmd (const char *args, int from_tty, #endif } +/* See bt-utils.h. */ + +void +sig_write (const char *msg) +{ + if (gdb_stderr == nullptr || gdb_stderr->fd () == -1) + std::ignore = ::write (2, msg, strlen (msg)); + else + gdb_stderr->write_async_safe (msg, strlen (msg)); +} + #ifdef GDB_PRINT_INTERNAL_BACKTRACE #ifdef GDB_PRINT_INTERNAL_BACKTRACE_USING_LIBBACKTRACE @@ -53,11 +64,6 @@ libbacktrace_error (void *data, const char *errmsg, int errnum) if (errnum < 0) return; - const auto sig_write = [] (const char *msg) -> void - { - gdb_stderr->write_async_safe (msg, strlen (msg)); - }; - sig_write ("error creating backtrace: "); sig_write (errmsg); if (errnum > 0) @@ -77,11 +83,6 @@ static int libbacktrace_print (void *data, uintptr_t pc, const char *filename, int lineno, const char *function) { - const auto sig_write = [] (const char *msg) -> void - { - gdb_stderr->write_async_safe (msg, strlen (msg)); - }; - /* Buffer to print addresses and line numbers into. An 8-byte address with '0x' prefix and a null terminator requires 20 characters. This also feels like it should be enough to represent line numbers in most @@ -128,16 +129,14 @@ gdb_internal_backtrace_1 () static void gdb_internal_backtrace_1 () { - const auto sig_write = [] (const char *msg) -> void - { - gdb_stderr->write_async_safe (msg, strlen (msg)); - }; - /* Allow up to 25 frames of backtrace. */ void *buffer[25]; int frames = backtrace (buffer, ARRAY_SIZE (buffer)); - backtrace_symbols_fd (buffer, frames, gdb_stderr->fd ()); + int fd = ((gdb_stderr == nullptr || gdb_stderr->fd () == -1) + ? 2 + : gdb_stderr->fd ()); + backtrace_symbols_fd (buffer, frames, fd); if (frames == ARRAY_SIZE (buffer)) sig_write (_("Backtrace might be incomplete.\n")); } @@ -171,17 +170,9 @@ gdb_internal_backtrace () return; #ifdef GDB_PRINT_INTERNAL_BACKTRACE - const auto sig_write = [] (const char *msg) -> void - { - gdb_stderr->write_async_safe (msg, strlen (msg)); - }; - sig_write (str_backtrace); - if (gdb_stderr->fd () > -1) - gdb_internal_backtrace_1 (); - else - sig_write (str_backtrace_unavailable); + gdb_internal_backtrace_1 (); sig_write ("---------------------\n"); #endif diff --git a/gdb/bt-utils.h b/gdb/bt-utils.h index ed381d8..c2fbe97 100644 --- a/gdb/bt-utils.h +++ b/gdb/bt-utils.h @@ -75,4 +75,9 @@ extern void gdb_internal_backtrace_set_cmd (const char *args, int from_tty, extern void gdb_internal_backtrace_init_str (); +/* Print MSG to gdb_stderr or stderr in a way that is safe to do from an + interrupt handler. */ + +extern void sig_write (const char *msg); + #endif /* GDB_BT_UTILS_H */ diff --git a/gdb/config.in b/gdb/config.in index 86ff67d..426947e 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -722,9 +722,6 @@ /* The size of `unsigned __int128', as computed by sizeof. */ #undef SIZEOF_UNSIGNED___INT128 -/* The size of `void *', as computed by sizeof. */ -#undef SIZEOF_VOID_P - /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at runtime. diff --git a/gdb/configure b/gdb/configure index c029c30..5ee1982 100755 --- a/gdb/configure +++ b/gdb/configure @@ -761,8 +761,6 @@ TARGET_OBS AMD_DBGAPI_LIBS AMD_DBGAPI_CFLAGS HAVE_GSTACK -ENABLE_BFD_64_BIT_FALSE -ENABLE_BFD_64_BIT_TRUE subdirs GDB_DATADIR DEBUGDIR @@ -934,7 +932,6 @@ with_relocated_sources with_auto_load_dir with_auto_load_safe_path enable_targets -enable_64_bit_bfd with_amd_dbgapi enable_tui enable_gdbtk @@ -1646,7 +1643,6 @@ Optional Features: --disable-nls do not use Native Language Support --enable-targets=TARGETS alternative target configurations - --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes) --enable-tui enable full-screen terminal user interface (TUI) --enable-gdbtk enable gdbtk graphical user interface (GUI) --enable-profiling enable profiling of GDB @@ -11503,7 +11499,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11506 "configure" +#line 11502 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11609,7 +11605,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11612 "configure" +#line 11608 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -24879,70 +24875,40 @@ 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 # Provide defaults for some variables set by the per-host and per-target # configuration. @@ -24992,7 +24958,7 @@ fi done # Check whether this target needs 64-bit CORE_ADDR - if test x${enable_64_bit_bfd} = xno; then + if test x${have_64_bit_bfd} = xno; then . ${srcdir}/../bfd/config.bfd fi @@ -25005,19 +24971,10 @@ fi done 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 TARGET_OBS='$(ALL_TARGET_OBS) $(ALL_64_TARGET_OBS)' else - case ${host} in - mips*) - # If all targets were requested, but 64 bit bfd is not enabled, - # the build will fail. See PR 28684. - as_fn_error $? "--enable-targets=all requires --enable-64-bit-bfd" "$LINENO" 5 - ;; - *) - TARGET_OBS='$(ALL_TARGET_OBS)' - ;; - esac + TARGET_OBS='$(ALL_TARGET_OBS)' fi fi @@ -33946,10 +33903,6 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" 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 "${HAVE_PYTHON_TRUE}" && test -z "${HAVE_PYTHON_FALSE}"; then as_fn_error $? "conditional \"HAVE_PYTHON\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/gdb/configure.ac b/gdb/configure.ac index 7ba799b..5870a61 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -241,7 +241,7 @@ do done # Check whether this target needs 64-bit CORE_ADDR - if test x${enable_64_bit_bfd} = xno; then + if test x${have_64_bit_bfd} = xno; then . ${srcdir}/../bfd/config.bfd fi @@ -254,19 +254,10 @@ do done 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 TARGET_OBS='$(ALL_TARGET_OBS) $(ALL_64_TARGET_OBS)' else - case ${host} in - mips*) - # If all targets were requested, but 64 bit bfd is not enabled, - # the build will fail. See PR 28684. - AC_MSG_ERROR([--enable-targets=all requires --enable-64-bit-bfd]) - ;; - *) - TARGET_OBS='$(ALL_TARGET_OBS)' - ;; - esac + TARGET_OBS='$(ALL_TARGET_OBS)' fi fi diff --git a/gdb/configure.tgt b/gdb/configure.tgt index 72cdcee..e9b3068 100644 --- a/gdb/configure.tgt +++ b/gdb/configure.tgt @@ -85,7 +85,7 @@ hppa*-*-*) i[34567]86-*-*) cpu_obs="${i386_tobjs}" - if test "x$enable_64_bit_bfd" = "xyes"; then + if test "x$have_64_bit_bfd" = "xyes"; then cpu_obs="${amd64_tobjs} ${cpu_obs}" fi ;; @@ -284,7 +284,7 @@ hppa*-*-openbsd*) i[34567]86-*-darwin*) # Target: Darwin/i386 gdb_target_obs="i386-darwin-tdep.o solib-darwin.o" - if test "x$enable_64_bit_bfd" = "xyes"; then + if test "x$have_64_bit_bfd" = "xyes"; then # Target: GNU/Linux x86-64 gdb_target_obs="amd64-darwin-tdep.o ${gdb_target_obs}" fi @@ -319,7 +319,7 @@ i[34567]86-*-linux*) linux-tdep.o linux-record.o \ arch/i386-linux-tdesc.o \ arch/x86-linux-tdesc-features.o" - if test "x$enable_64_bit_bfd" = "xyes"; then + if test "x$have_64_bit_bfd" = "xyes"; then # Target: GNU/Linux x86-64 gdb_target_obs="amd64-linux-tdep.o \ arch/amd64-linux-tdesc.o ${gdb_target_obs}" @@ -580,7 +580,7 @@ sparc-*-linux*) sparc-linux-tdep.o solib-svr4.o symfile-mem.o \ linux-tdep.o \ ravenscar-thread.o sparc-ravenscar-thread.o" - if test "x$enable_64_bit_bfd" = "xyes"; then + if test "x$have_64_bit_bfd" = "xyes"; then # Target: GNU/Linux UltraSPARC gdb_target_obs="sparc64-tdep.o \ sparc64-linux-tdep.o ${gdb_target_obs}" diff --git a/gdb/contrib/license-check-new-files.sh b/gdb/contrib/license-check-new-files.sh new file mode 100755 index 0000000..710afa1 --- /dev/null +++ b/gdb/contrib/license-check-new-files.sh @@ -0,0 +1,149 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2025 Free Software Foundation, Inc. +# +# This file is part of GDB. +# +# 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, see <http://www.gnu.org/licenses/>. + +# This program requires the python modules GitPython (git) and scancode-toolkit. +# It builds a list of all the newly added files to the repository and scans +# each file for a license, printing it to the terminal. If "--skip" is used, +# it will only output non-"common" licenses, e.g., omitting "GPL-3.0-or-later". +# This makes it a little bit easier to detect any possible new licenses. +# +# Example: +# bash$ cd /path/to/binutils-gdb/gdb +# bash$ ./contrib/license-check-new-files.sh -s gdb-15-branchpoint gdb-16-branchpoint +# Scanning directories gdb*/... +# gdb/contrib/common-misspellings.txt: no longer in repo? +# gdb/contrib/spellcheck.sh: no longer in repo? +# gdbsupport/unordered_dense.h: MIT + +import os +import sys +import argparse +from pathlib import PurePath +from git import Repo +from scancode import api + +# A list of "common" licenses. If "--skip" is used, any file +# with a license in this list will be omitted from the output. +COMMON_LICENSES = ["GPL-2.0-or-later", "GPL-3.0-or-later"] + +# Default list of directories to scan. Default scans are limited to +# gdb-specific git directories because much of the rest of binutils-gdb +# is actually owned by other projects/packages. +DEFAULT_SCAN_DIRS = "gdb*" + + +# Get the commit object associated with the string commit CSTR +# from the git repository REPO. +# +# Returns the object or prints an error and exits. +def get_commit(repo, cstr): + try: + return repo.commit(cstr) + except: + print(f'unknown commit "{cstr}"') + sys.exit(2) + + +# Uses scancode-toolkit package to scan FILE's licenses. +# Returns the full license dict from scancode on success or +# propagates any exceptions. +def get_licenses_for_file(file): + return api.get_licenses(file) + + +# Helper function to print FILE to the terminal if skipping +# common licenses. +def skip_print_file(skip, file): + if skip: + print(f"{file}: ", end="") + + +def main(argv): + parser = argparse.ArgumentParser() + parser.add_argument("from_commit") + parser.add_argument("to_commit") + parser.add_argument( + "-s", "--skip", help="skip common licenses in output", action="store_true" + ) + parser.add_argument( + "-p", + "--paths", + help=f'paths to scan (default is "{DEFAULT_SCAN_DIRS}")', + type=str, + default=DEFAULT_SCAN_DIRS, + ) + args = parser.parse_args() + + # Commit boundaries to search for new files + from_commit = args.from_commit + to_commit = args.to_commit + + # Get the list of new files from git. Try the current directory, + # looping up to the root attempting to find a valid git repository. + path = PurePath(os.getcwd()) + paths = list(path.parents) + paths.insert(0, path) + for dir in paths: + try: + repo = Repo(dir) + break + except: + pass + + if dir == path.parents[-1]: + print(f'not a git repository (or any parent up to mount point "{dir}")') + sys.exit(2) + + # Get from/to commits + fc = get_commit(repo, from_commit) + tc = get_commit(repo, to_commit) + + # Loop over new files + paths = [str(dir) for dir in args.paths.split(",")] + print(f'Scanning directories {",".join(f"{s}/" for s in paths)}...') + for file in fc.diff(tc, paths=paths).iter_change_type("A"): + filename = file.a_path + if not args.skip: + print(f"checking licenses for {filename}... ", end="", flush=True) + try: + f = dir.joinpath(dir, filename).as_posix() + lic = get_licenses_for_file(f) + if len(lic["license_clues"]) > 1: + print("multiple licenses detected") + elif ( + not args.skip + or lic["detected_license_expression_spdx"] not in COMMON_LICENSES + ): + skip_print_file(args.skip, filename) + print(f"{lic['detected_license_expression_spdx']}") + except OSError: + # Likely hit a file that was added to the repo and subsequently removed. + skip_print_file(args.skip, filename) + print("no longer in repo?") + except KeyboardInterrupt: + print("interrupted") + break + except Exception as e: + # If scanning fails, there is little we can do but print an error. + skip_print_file(args.skip, filename) + print(e) + + +if __name__ == "__main__": + main(sys.argv) diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y index 10f6e2d..e7317b7 100644 --- a/gdb/cp-name-parser.y +++ b/gdb/cp-name-parser.y @@ -2047,6 +2047,9 @@ cp_demangled_name_to_comp (const char *demangled_name, auto result = std::make_unique<demangle_parse_info> (); cpname_state state (demangled_name, result.get ()); + scoped_restore restore_yydebug = make_scoped_restore (&yydebug, + parser_debug); + if (yyparse (&state)) { if (state.global_errmsg && errmsg) diff --git a/gdb/dwarf2/cooked-index-worker.c b/gdb/dwarf2/cooked-index-worker.c index da51a8c..5d7fc46 100644 --- a/gdb/dwarf2/cooked-index-worker.c +++ b/gdb/dwarf2/cooked-index-worker.c @@ -20,6 +20,7 @@ #include "dwarf2/cooked-index-worker.h" #include "dwarf2/cooked-index.h" #include "gdbsupport/thread-pool.h" +#include "maint.h" #include "run-on-main-thread.h" #include "event-top.h" #include "exceptions.h" @@ -244,8 +245,12 @@ cooked_index_worker::write_to_cache (const cooked_index *idx) void cooked_index_worker::done_reading () { - for (auto &one_result : m_results) - m_all_parents_map.add_map (*one_result.get_parent_map ()); + { + scoped_time_it time_it ("DWARF add parent map"); + + for (auto &one_result : m_results) + m_all_parents_map.add_map (*one_result.get_parent_map ()); + } dwarf2_per_bfd *per_bfd = m_per_objfile->per_bfd; cooked_index *table diff --git a/gdb/dwarf2/cooked-index.c b/gdb/dwarf2/cooked-index.c index 7948ffa..2c7e31e 100644 --- a/gdb/dwarf2/cooked-index.c +++ b/gdb/dwarf2/cooked-index.c @@ -21,6 +21,7 @@ #include "dwarf2/read.h" #include "dwarf2/stringify.h" #include "event-top.h" +#include "maint.h" #include "observable.h" #include "run-on-main-thread.h" #include "gdbsupport/task-group.h" @@ -101,7 +102,11 @@ cooked_index::set_contents () { auto this_shard = shard.get (); const parent_map_map *parent_maps = m_state->get_parent_map_map (); - finalizers.add_task ([=] () { this_shard->finalize (parent_maps); }); + finalizers.add_task ([=] () + { + scoped_time_it time_it ("DWARF finalize worker"); + this_shard->finalize (parent_maps); + }); } finalizers.start (); diff --git a/gdb/dwarf2/cooked-indexer.c b/gdb/dwarf2/cooked-indexer.c index b8b66cf..c093984 100644 --- a/gdb/dwarf2/cooked-indexer.c +++ b/gdb/dwarf2/cooked-indexer.c @@ -89,7 +89,7 @@ cooked_indexer::ensure_cu_exists (cutu_reader *reader, /* Lookups for type unit references are always in the CU, and cross-CU references will crash. */ if (reader->cu ()->per_cu->is_dwz == is_dwz - && reader->cu ()->header.offset_in_cu_p (sect_off)) + && reader->cu ()->header.offset_in_unit_p (sect_off)) return reader; dwarf2_per_objfile *per_objfile = reader->cu ()->per_objfile; @@ -109,20 +109,20 @@ cooked_indexer::ensure_cu_exists (cutu_reader *reader, cutu_reader *result = m_index_storage->get_reader (per_cu); if (result == nullptr) { - cutu_reader new_reader (*per_cu, *per_objfile, nullptr, nullptr, false, - language_minimal, - &m_index_storage->get_abbrev_table_cache ()); - - if (new_reader.is_dummy () || new_reader.top_level_die () == nullptr - || !new_reader.top_level_die ()->has_children) + const abbrev_table_cache &abbrev_table_cache + = m_index_storage->get_abbrev_table_cache (); + auto new_reader + = std::make_unique<cutu_reader> (*per_cu, *per_objfile, nullptr, + nullptr, false, language_minimal, + &abbrev_table_cache); + + if (new_reader->is_dummy ()) return nullptr; - auto copy = std::make_unique<cutu_reader> (std::move (new_reader)); - result = m_index_storage->preserve (std::move (copy)); + result = m_index_storage->preserve (std::move (new_reader)); } - if (result->is_dummy () || result->top_level_die () == nullptr - || !result->top_level_die ()->has_children) + if (result->is_dummy ()) return nullptr; if (for_scanning) diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h index 6eda19b..5338dfe 100644 --- a/gdb/dwarf2/cu.h +++ b/gdb/dwarf2/cu.h @@ -21,7 +21,7 @@ #define GDB_DWARF2_CU_H #include "buildsym.h" -#include "dwarf2/comp-unit-head.h" +#include "dwarf2/unit-head.h" #include <optional> #include "language.h" #include "gdbsupport/unordered_set.h" @@ -109,7 +109,7 @@ struct dwarf2_cu } /* The header of the compilation unit. */ - struct comp_unit_head header; + struct unit_head header; /* Base address of this compilation unit. */ std::optional<unrelocated_addr> base_address; diff --git a/gdb/dwarf2/line-header.c b/gdb/dwarf2/line-header.c index de162b7..4652306 100644 --- a/gdb/dwarf2/line-header.c +++ b/gdb/dwarf2/line-header.c @@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "dwarf2/comp-unit-head.h" +#include "dwarf2/unit-head.h" #include "dwarf2/leb.h" #include "dwarf2/line-header.h" #include "dwarf2/read.h" @@ -95,7 +95,7 @@ dwarf2_statement_list_fits_in_line_number_section_complaint (void) static LONGEST read_checked_initial_length_and_offset (bfd *abfd, const gdb_byte *buf, - const struct comp_unit_head *cu_header, + const struct unit_head *cu_header, unsigned int *bytes_read, unsigned int *offset_size) { @@ -253,11 +253,10 @@ read_formatted_entries (dwarf2_per_objfile *per_objfile, bfd *abfd, /* See line-header.h. */ line_header_up -dwarf_decode_line_header (sect_offset sect_off, bool is_dwz, - dwarf2_per_objfile *per_objfile, - struct dwarf2_section_info *section, - const struct comp_unit_head *cu_header, - const char *comp_dir) +dwarf_decode_line_header (sect_offset sect_off, bool is_dwz, + dwarf2_per_objfile *per_objfile, + struct dwarf2_section_info *section, + const unit_head *cu_header, const char *comp_dir) { const gdb_byte *line_ptr; unsigned int bytes_read, offset_size; diff --git a/gdb/dwarf2/line-header.h b/gdb/dwarf2/line-header.h index 36385b6..e6f9ea9 100644 --- a/gdb/dwarf2/line-header.h +++ b/gdb/dwarf2/line-header.h @@ -218,7 +218,7 @@ file_entry::include_dir (const line_header *lh) const extern line_header_up dwarf_decode_line_header (sect_offset sect_off, bool is_dwz, dwarf2_per_objfile *per_objfile, - struct dwarf2_section_info *section, const struct comp_unit_head *cu_header, + struct dwarf2_section_info *section, const struct unit_head *cu_header, const char *comp_dir); #endif /* GDB_DWARF2_LINE_HEADER_H */ diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 6b7f2c7..0eb248f 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -31,7 +31,7 @@ #include "dwarf2/abbrev.h" #include "dwarf2/aranges.h" #include "dwarf2/attribute.h" -#include "dwarf2/comp-unit-head.h" +#include "dwarf2/unit-head.h" #include "dwarf2/cooked-index-worker.h" #include "dwarf2/cooked-indexer.h" #include "dwarf2/cu.h" @@ -52,6 +52,7 @@ #include "event-top.h" #include "exceptions.h" #include "gdbsupport/task-group.h" +#include "maint.h" #include "symtab.h" #include "gdbtypes.h" #include "objfiles.h" @@ -279,7 +280,7 @@ struct dwo_sections struct dwarf2_section_info str; struct dwarf2_section_info str_offsets; /* In the case of a virtual DWO file, these two are unused. */ - struct dwarf2_section_info info; + std::vector<dwarf2_section_info> infos; std::vector<dwarf2_section_info> types; }; @@ -733,9 +734,6 @@ show_dwarf_synchronous (struct ui_file *file, int from_tty, /* local function prototypes */ -static void build_type_psymtabs_reader (cutu_reader *reader, - cooked_index_worker_result *storage); - static void var_decode_location (struct attribute *attr, struct symbol *sym, struct dwarf2_cu *cu); @@ -748,9 +746,9 @@ static unrelocated_addr read_addr_index (struct dwarf2_cu *cu, static sect_offset read_abbrev_offset (dwarf2_per_objfile *per_objfile, dwarf2_section_info *, sect_offset); -static const char *read_indirect_string - (dwarf2_per_objfile *per_objfile, bfd *, const gdb_byte *, - const struct comp_unit_head *, unsigned int *); +static const char *read_indirect_string (dwarf2_per_objfile *per_objfile, bfd *, + const gdb_byte *, const unit_head *, + unsigned int *); static unrelocated_addr read_addr_index_from_leb128 (struct dwarf2_cu *, const gdb_byte *, @@ -2391,109 +2389,6 @@ read_abbrev_offset (dwarf2_per_objfile *per_objfile, return (sect_offset) read_offset (abfd, info_ptr, offset_size); } -/* A helper for create_dwo_debug_types_hash_table. Read types from SECTION - and fill them into DWO_FILE's type unit hash table. It will process only - type units, therefore DW_UT_type. */ - -void -cutu_reader::create_dwo_debug_type_hash_table (dwarf2_per_bfd *per_bfd, - dwo_file *dwo_file, - dwarf2_section_info *section, - rcuh_kind section_kind) -{ - struct dwarf2_section_info *abbrev_section; - bfd *abfd; - const gdb_byte *info_ptr, *end_ptr; - - abbrev_section = &dwo_file->sections.abbrev; - - dwarf_read_debug_printf ("Reading %s for %s", - section->get_name (), - abbrev_section->get_file_name ()); - - info_ptr = section->buffer; - - if (info_ptr == NULL) - return; - - /* We can't set abfd until now because the section may be empty or - not present, in which case the bfd is unknown. */ - abfd = section->get_bfd_owner (); - - /* We don't use cutu_reader here because we don't need to read - any dies: the signature is in the header. */ - - end_ptr = info_ptr + section->size; - while (info_ptr < end_ptr) - { - const gdb_byte *ptr = info_ptr; - struct comp_unit_head header; - unsigned int length; - - sect_offset sect_off = (sect_offset) (ptr - section->buffer); - - /* Initialize it due to a false compiler warning. */ - header.signature = -1; - header.type_cu_offset_in_tu = (cu_offset) -1; - - /* We need to read the type's signature in order to build the hash - table, but we don't need anything else just yet. */ - - ptr = read_and_check_comp_unit_head (&header, section, abbrev_section, - ptr, section_kind); - - length = header.get_length_with_initial (); - - /* Skip dummy type units. */ - if (ptr >= info_ptr + length - || peek_abbrev_code (abfd, ptr) == 0 - || (header.unit_type != DW_UT_type - && header.unit_type != DW_UT_split_type)) - { - info_ptr += length; - continue; - } - - dwo_unit *dwo_tu = OBSTACK_ZALLOC (&per_bfd->obstack, dwo_unit); - dwo_tu->dwo_file = dwo_file; - dwo_tu->signature = header.signature; - dwo_tu->type_offset_in_tu = header.type_cu_offset_in_tu; - dwo_tu->section = section; - dwo_tu->sect_off = sect_off; - dwo_tu->length = length; - - auto [it, inserted] = dwo_file->tus.emplace (dwo_tu); - if (!inserted) - complaint (_("debug type entry at offset %s is duplicate to" - " the entry at offset %s, signature %s"), - sect_offset_str (sect_off), - sect_offset_str ((*it)->sect_off), - hex_string (header.signature)); - - dwarf_read_debug_printf_v (" offset %s, signature %s", - sect_offset_str (sect_off), - hex_string (header.signature)); - - info_ptr += length; - } -} - -/* Create the hash table of all entries in the .debug_types - (or .debug_types.dwo) section(s). - DWO_FILE is a pointer to the DWO file object. - - Note: This function processes DWO files only, not DWP files. */ - -void -cutu_reader::create_dwo_debug_types_hash_table - (dwarf2_per_bfd *per_bfd, dwo_file *dwo_file, - gdb::array_view<dwarf2_section_info> type_sections) -{ - for (dwarf2_section_info §ion : type_sections) - create_dwo_debug_type_hash_table (per_bfd, dwo_file, §ion, - rcuh_kind::TYPE); -} - /* Add an entry for signature SIG to per_bfd->signatured_types. */ static signatured_type_set::iterator @@ -2795,9 +2690,9 @@ cutu_reader::read_cutu_die_from_dwo (dwarf2_cu *cu, dwo_unit *dwo_unit, { signatured_type *sig_type = (struct signatured_type *) per_cu; - m_info_ptr = read_and_check_comp_unit_head (&cu->header, section, - dwo_abbrev_section, - m_info_ptr, rcuh_kind::TYPE); + m_info_ptr = read_and_check_unit_head (&cu->header, section, + dwo_abbrev_section, m_info_ptr, + ruh_kind::TYPE); /* This is not an assert because it can be caused by bad debug info. */ if (sig_type->signature != cu->header.signature) @@ -2814,7 +2709,7 @@ cutu_reader::read_cutu_die_from_dwo (dwarf2_cu *cu, dwo_unit *dwo_unit, /* For DWOs coming from DWP files, we don't know the CU length nor the type's offset in the TU until now. */ dwo_unit->length = cu->header.get_length_with_initial (); - dwo_unit->type_offset_in_tu = cu->header.type_cu_offset_in_tu; + dwo_unit->type_offset_in_tu = cu->header.type_offset_in_tu; /* Establish the type offset that can be used to lookup the type. For DWO files, we don't know it until now. */ @@ -2823,10 +2718,9 @@ cutu_reader::read_cutu_die_from_dwo (dwarf2_cu *cu, dwo_unit *dwo_unit, } else { - m_info_ptr - = read_and_check_comp_unit_head (&cu->header, section, - dwo_abbrev_section, m_info_ptr, - rcuh_kind::COMPILE); + m_info_ptr = read_and_check_unit_head (&cu->header, section, + dwo_abbrev_section, m_info_ptr, + ruh_kind::COMPILE); gdb_assert (dwo_unit->sect_off == cu->header.sect_off); /* For DWOs coming from DWP files, we don't know the CU length until now. */ @@ -3044,26 +2938,26 @@ cutu_reader::cutu_reader (dwarf2_per_cu &this_cu, } /* Get the header. */ - if (to_underlying (cu->header.first_die_cu_offset) != 0 && !rereading_dwo_cu) + if (to_underlying (cu->header.first_die_offset_in_unit) != 0 + && !rereading_dwo_cu) { /* We already have the header, there's no need to read it in again. */ - m_info_ptr += to_underlying (cu->header.first_die_cu_offset); + m_info_ptr += to_underlying (cu->header.first_die_offset_in_unit); } else { if (this_cu.is_debug_types) { - m_info_ptr - = read_and_check_comp_unit_head (&cu->header, section, - abbrev_section, m_info_ptr, - rcuh_kind::TYPE); + m_info_ptr = read_and_check_unit_head (&cu->header, section, + abbrev_section, m_info_ptr, + ruh_kind::TYPE); /* Since per_cu is the first member of struct signatured_type, we can go from a pointer to one to a pointer to the other. */ sig_type = (struct signatured_type *) &this_cu; gdb_assert (sig_type->signature == cu->header.signature); gdb_assert (sig_type->type_offset_in_tu - == cu->header.type_cu_offset_in_tu); + == cu->header.type_offset_in_tu); gdb_assert (this_cu.sect_off == cu->header.sect_off); /* LENGTH has not been set yet for type units if we're @@ -3076,10 +2970,9 @@ cutu_reader::cutu_reader (dwarf2_per_cu &this_cu, } else { - m_info_ptr - = read_and_check_comp_unit_head (&cu->header, section, - abbrev_section, m_info_ptr, - rcuh_kind::COMPILE); + m_info_ptr = read_and_check_unit_head (&cu->header, section, + abbrev_section, m_info_ptr, + ruh_kind::COMPILE); gdb_assert (this_cu.sect_off == cu->header.sect_off); this_cu.set_length (cu->header.get_length_with_initial ()); @@ -3211,11 +3104,11 @@ cutu_reader::cutu_reader (dwarf2_per_cu &this_cu, m_info_ptr = section->buffer + to_underlying (this_cu.sect_off); const gdb_byte *begin_info_ptr = m_info_ptr; - m_info_ptr = read_and_check_comp_unit_head (&m_new_cu->header, section, - abbrev_section, m_info_ptr, - (this_cu.is_debug_types - ? rcuh_kind::TYPE - : rcuh_kind::COMPILE)); + m_info_ptr = read_and_check_unit_head (&m_new_cu->header, section, + abbrev_section, m_info_ptr, + (this_cu.is_debug_types + ? ruh_kind::TYPE + : ruh_kind::COMPILE)); m_new_cu->str_offsets_base = parent_cu.str_offsets_base; m_new_cu->addr_base = parent_cu.addr_base; @@ -3289,33 +3182,130 @@ get_type_unit_group_key (struct dwarf2_cu *cu, const struct attribute *stmt_list return {cu->dwo_unit, static_cast<sect_offset> (line_offset)}; } -/* Subroutine of dwarf2_build_psymtabs_hard to simplify it. - Process compilation unit THIS_CU for a psymtab. */ +/* A subclass of cooked_index_worker that handles scanning + .debug_info. */ -static void -process_psymtab_comp_unit (dwarf2_per_cu *this_cu, - dwarf2_per_objfile *per_objfile, - cooked_index_worker_result *storage) +class cooked_index_worker_debug_info : public cooked_index_worker +{ +public: + cooked_index_worker_debug_info (dwarf2_per_objfile *per_objfile) + : cooked_index_worker (per_objfile) + { + gdb_assert (is_main_thread ()); + + struct objfile *objfile = per_objfile->objfile; + dwarf2_per_bfd *per_bfd = per_objfile->per_bfd; + + dwarf_read_debug_printf ("Building psymtabs of objfile %s ...", + objfile_name (objfile)); + + per_bfd->map_info_sections (objfile); + } + +private: + void do_reading () override; + + /* Print collected type unit statistics. */ + + void print_tu_stats (dwarf2_per_objfile *per_objfile) + { + struct tu_stats *tu_stats = &per_objfile->per_bfd->tu_stats; + + dwarf_read_debug_printf ("Type unit statistics:"); + dwarf_read_debug_printf (" %d TUs", tu_stats->nr_tus); + dwarf_read_debug_printf (" %d uniq abbrev tables", + tu_stats->nr_uniq_abbrev_tables); + dwarf_read_debug_printf (" %d symtabs from stmt_list entries", + tu_stats->nr_symtabs); + dwarf_read_debug_printf (" %d symtab sharers", + tu_stats->nr_symtab_sharers); + dwarf_read_debug_printf (" %d type units without a stmt_list", + tu_stats->nr_stmt_less_type_units); + dwarf_read_debug_printf (" %d all_type_units reallocs", + tu_stats->nr_all_type_units_reallocs); + } + + void print_stats () override + { + if (dwarf_read_debug > 0) + print_tu_stats (m_per_objfile); + + if (dwarf_read_debug > 1) + { + dwarf_read_debug_printf_v ("Final m_all_parents_map:"); + m_all_parents_map.dump (m_per_objfile->per_bfd); + } + } + + /* After the last DWARF-reading task has finished, this function + does the remaining work to finish the scan. */ + void done_reading () override; + + /* An iterator for the comp units. */ + using unit_iterator = std::vector<dwarf2_per_cu_up>::iterator; + + /* Process a batch of CUs. This may be called multiple times in + separate threads. TASK_NUMBER indicates which task this is -- + the result is stored in that slot of M_RESULTS. */ + void process_units (size_t task_number, unit_iterator first, + unit_iterator end); + + /* Process unit THIS_CU. */ + void process_unit (dwarf2_per_cu *this_cu, dwarf2_per_objfile *per_objfile, + cooked_index_worker_result *storage); + + /* Process all type units existing in PER_OBJFILE::PER_BFD::ALL_UNITS. */ + void process_type_units (dwarf2_per_objfile *per_objfile, + cooked_index_worker_result *storage); + + /* Process the type unit wrapped in READER. */ + void process_type_unit (cutu_reader *reader, + cooked_index_worker_result *storage); + + /* Process all type units of all DWO files. + + This is needed in case a TU was emitted without its skeleton. + Note: This can't be done until we know what all the DWO files are. */ + void process_skeletonless_type_units (dwarf2_per_objfile *per_objfile, + cooked_index_worker_result *storage); + + /* Process the type unit represented by DWO_UNIT. */ + void process_skeletonless_type_unit (dwo_unit *dwo_unit, + dwarf2_per_objfile *per_objfile, + cooked_index_worker_result *storage); + + /* A storage object for "leftovers" -- see the 'start' method, but + essentially things not parsed during the normal CU parsing + passes. */ + cooked_index_worker_result m_index_storage; +}; + +void +cooked_index_worker_debug_info::process_unit + (dwarf2_per_cu *this_cu, dwarf2_per_objfile *per_objfile, + cooked_index_worker_result *storage) { cutu_reader *reader = storage->get_reader (this_cu); if (reader == nullptr) { - cutu_reader new_reader (*this_cu, *per_objfile, nullptr, nullptr, false, - language_minimal, - &storage->get_abbrev_table_cache ()); + const abbrev_table_cache &abbrev_table_cache + = storage->get_abbrev_table_cache (); + auto new_reader = std::make_unique<cutu_reader> (*this_cu, *per_objfile, + nullptr, nullptr, false, + language_minimal, + &abbrev_table_cache); - if (new_reader.cu () == nullptr || new_reader.is_dummy ()) + if (new_reader->is_dummy ()) return; - auto copy = std::make_unique<cutu_reader> (std::move (new_reader)); - reader = storage->preserve (std::move (copy)); + reader = storage->preserve (std::move (new_reader)); } - if (reader->top_level_die () == nullptr || reader->is_dummy ()) + if (reader->is_dummy ()) return; if (this_cu->is_debug_types) - build_type_psymtabs_reader (reader, storage); + process_type_unit (reader, storage); else if (reader->top_level_die ()->tag != DW_TAG_partial_unit) { bool nope = false; @@ -3328,11 +3318,9 @@ process_psymtab_comp_unit (dwarf2_per_cu *this_cu, } } -/* Reader function for build_type_psymtabs. */ - -static void -build_type_psymtabs_reader (cutu_reader *reader, - cooked_index_worker_result *storage) +void +cooked_index_worker_debug_info::process_type_unit + (cutu_reader *reader, cooked_index_worker_result *storage) { struct dwarf2_cu *cu = reader->cu (); dwarf2_per_cu *per_cu = cu->per_cu; @@ -3366,26 +3354,9 @@ struct tu_abbrev_offset sect_offset abbrev_offset; }; -/* Efficiently read all the type units. - - The efficiency is because we sort TUs by the abbrev table they use and - only read each abbrev table once. In one program there are 200K TUs - sharing 8K abbrev tables. - - The main purpose of this function is to support building the - dwarf2_per_objfile->per_bfd->type_unit_groups table. - TUs typically share the DW_AT_stmt_list of the CU they came from, so we - can collapse the search space by grouping them by stmt_list. - The savings can be significant, in the same program from above the 200K TUs - share 8K stmt_list tables. - - FUNC is expected to call get_type_unit_group, which will create the - struct type_unit_group if necessary and add it to - dwarf2_per_objfile->per_bfd->type_unit_groups. */ - -static void -build_type_psymtabs (dwarf2_per_objfile *per_objfile, - cooked_index_worker_result *storage) +void +cooked_index_worker_debug_info::process_type_units + (dwarf2_per_objfile *per_objfile, cooked_index_worker_result *storage) { struct tu_stats *tu_stats = &per_objfile->per_bfd->tu_stats; abbrev_table_up abbrev_table; @@ -3451,38 +3422,14 @@ build_type_psymtabs (dwarf2_per_objfile *per_objfile, abbrev_table.get (), nullptr, false, language_minimal); if (!reader.is_dummy ()) - build_type_psymtabs_reader (&reader, storage); + process_type_unit (&reader, storage); } } -/* Print collected type unit statistics. */ - -static void -print_tu_stats (dwarf2_per_objfile *per_objfile) -{ - struct tu_stats *tu_stats = &per_objfile->per_bfd->tu_stats; - - dwarf_read_debug_printf ("Type unit statistics:"); - dwarf_read_debug_printf (" %d TUs", tu_stats->nr_tus); - dwarf_read_debug_printf (" %d uniq abbrev tables", - tu_stats->nr_uniq_abbrev_tables); - dwarf_read_debug_printf (" %d symtabs from stmt_list entries", - tu_stats->nr_symtabs); - dwarf_read_debug_printf (" %d symtab sharers", - tu_stats->nr_symtab_sharers); - dwarf_read_debug_printf (" %d type units without a stmt_list", - tu_stats->nr_stmt_less_type_units); - dwarf_read_debug_printf (" %d all_type_units reallocs", - tu_stats->nr_all_type_units_reallocs); -} - -/* Traversal function for process_skeletonless_type_units. - Read a TU in a DWO file and build partial symbols for it. */ - -static void -process_skeletonless_type_unit (dwo_unit *dwo_unit, - dwarf2_per_objfile *per_objfile, - cooked_index_worker_result *storage) +void +cooked_index_worker_debug_info::process_skeletonless_type_unit + (dwo_unit *dwo_unit, dwarf2_per_objfile *per_objfile, + cooked_index_worker_result *storage) { dwarf2_per_bfd *per_bfd = per_objfile->per_bfd; @@ -3504,17 +3451,15 @@ process_skeletonless_type_unit (dwo_unit *dwo_unit, cutu_reader reader (**sig_type_it, *per_objfile, nullptr, nullptr, false, language_minimal); if (!reader.is_dummy ()) - build_type_psymtabs_reader (&reader, storage); + process_type_unit (&reader, storage); } -/* Scan all TUs of DWO files, verifying we've processed them. - This is needed in case a TU was emitted without its skeleton. - Note: This can't be done until we know what all the DWO files are. */ - -static void -process_skeletonless_type_units (dwarf2_per_objfile *per_objfile, - cooked_index_worker_result *storage) +void +cooked_index_worker_debug_info::process_skeletonless_type_units + (dwarf2_per_objfile *per_objfile, cooked_index_worker_result *storage) { + scoped_time_it time_it ("DWARF skeletonless type units"); + /* Skeletonless TUs in DWP files without .gdb_index is not supported yet. */ if (per_objfile->per_bfd->dwp_file == nullptr) for (const dwo_file_up &file : per_objfile->per_bfd->dwo_files) @@ -3522,64 +3467,10 @@ process_skeletonless_type_units (dwarf2_per_objfile *per_objfile, process_skeletonless_type_unit (unit, per_objfile, storage); } -/* A subclass of cooked_index_worker that handles scanning - .debug_info. */ - -class cooked_index_worker_debug_info : public cooked_index_worker -{ -public: - cooked_index_worker_debug_info (dwarf2_per_objfile *per_objfile) - : cooked_index_worker (per_objfile) - { - gdb_assert (is_main_thread ()); - - struct objfile *objfile = per_objfile->objfile; - dwarf2_per_bfd *per_bfd = per_objfile->per_bfd; - - dwarf_read_debug_printf ("Building psymtabs of objfile %s ...", - objfile_name (objfile)); - - per_bfd->map_info_sections (objfile); - } - -private: - - void do_reading () override; - - void print_stats () override - { - if (dwarf_read_debug > 0) - print_tu_stats (m_per_objfile); - if (dwarf_read_debug > 1) - { - dwarf_read_debug_printf_v ("Final m_all_parents_map:"); - m_all_parents_map.dump (m_per_objfile->per_bfd); - } - } - - /* After the last DWARF-reading task has finished, this function - does the remaining work to finish the scan. */ - void done_reading () override; - - /* An iterator for the comp units. */ - using unit_iterator = std::vector<dwarf2_per_cu_up>::iterator; - - /* Process a batch of CUs. This may be called multiple times in - separate threads. TASK_NUMBER indicates which task this is -- - the result is stored in that slot of M_RESULTS. */ - void process_cus (size_t task_number, unit_iterator first, - unit_iterator end); - - /* A storage object for "leftovers" -- see the 'start' method, but - essentially things not parsed during the normal CU parsing - passes. */ - cooked_index_worker_result m_index_storage; -}; - void -cooked_index_worker_debug_info::process_cus (size_t task_number, - unit_iterator first, - unit_iterator end) +cooked_index_worker_debug_info::process_units (size_t task_number, + unit_iterator first, + unit_iterator end) { SCOPE_EXIT { bfd_thread_cleanup (); }; @@ -3594,7 +3485,7 @@ cooked_index_worker_debug_info::process_cus (size_t task_number, try { - process_psymtab_comp_unit (per_cu, m_per_objfile, &thread_storage); + process_unit (per_cu, m_per_objfile, &thread_storage); } catch (gdb_exception &except) { @@ -3624,7 +3515,7 @@ cooked_index_worker_debug_info::do_reading () dwarf2_per_bfd *per_bfd = m_per_objfile->per_bfd; create_all_units (m_per_objfile); - build_type_psymtabs (m_per_objfile, &m_index_storage); + process_type_units (m_per_objfile, &m_index_storage); if (!per_bfd->debug_aranges.empty ()) read_addrmap_from_aranges (m_per_objfile, &per_bfd->debug_aranges, @@ -3677,7 +3568,8 @@ cooked_index_worker_debug_info::do_reading () gdb_assert (iter != last); workers.add_task ([this, task_count, iter, last] () { - process_cus (task_count, iter, last); + scoped_time_it time_it ("DWARF indexing worker"); + process_units (task_count, iter, last); }); ++task_count; @@ -3694,7 +3586,7 @@ read_comp_units_from_section (dwarf2_per_objfile *per_objfile, struct dwarf2_section_info *abbrev_section, unsigned int is_dwz, signatured_type_set &sig_types, - rcuh_kind section_kind) + ruh_kind section_kind) { const gdb_byte *info_ptr; struct objfile *objfile = per_objfile->objfile; @@ -3714,9 +3606,9 @@ read_comp_units_from_section (dwarf2_per_objfile *per_objfile, sect_offset sect_off = (sect_offset) (info_ptr - section->buffer); - comp_unit_head cu_header; - read_and_check_comp_unit_head (&cu_header, section, abbrev_section, - info_ptr, section_kind); + unit_head cu_header; + read_and_check_unit_head (&cu_header, section, abbrev_section, info_ptr, + section_kind); unsigned int length = cu_header.get_length_with_initial (); @@ -3729,7 +3621,7 @@ read_comp_units_from_section (dwarf2_per_objfile *per_objfile, = per_bfd->allocate_signatured_type (section, sect_off, length, is_dwz, cu_header.signature); signatured_type *sig_ptr = sig_type.get (); - sig_type->type_offset_in_tu = cu_header.type_cu_offset_in_tu; + sig_type->type_offset_in_tu = cu_header.type_offset_in_tu; this_cu.reset (sig_type.release ()); auto inserted = sig_types.emplace (sig_ptr).second; @@ -3771,17 +3663,17 @@ create_all_units (dwarf2_per_objfile *per_objfile) for (dwarf2_section_info §ion : per_objfile->per_bfd->infos) read_comp_units_from_section (per_objfile, §ion, &per_objfile->per_bfd->abbrev, 0, sig_types, - rcuh_kind::COMPILE); + ruh_kind::COMPILE); for (dwarf2_section_info §ion : per_objfile->per_bfd->types) read_comp_units_from_section (per_objfile, §ion, &per_objfile->per_bfd->abbrev, 0, sig_types, - rcuh_kind::TYPE); + ruh_kind::TYPE); dwz_file *dwz = per_objfile->per_bfd->get_dwz_file (); if (dwz != NULL) { read_comp_units_from_section (per_objfile, &dwz->info, &dwz->abbrev, 1, - sig_types, rcuh_kind::COMPILE); + sig_types, ruh_kind::COMPILE); if (!dwz->types.empty ()) { @@ -6313,79 +6205,131 @@ lookup_dwo_file (dwarf2_per_bfd *per_bfd, const char *dwo_name, return it != per_bfd->dwo_files.end () ? it->get() : nullptr; } -/* Create the dwo_units for the CUs in a DWO_FILE. - Note: This function processes DWO files only, not DWP files. */ - void -cutu_reader::create_dwo_cus_hash_table (dwarf2_cu *cu, dwo_file &dwo_file) +cutu_reader::create_dwo_unit_hash_tables (dwo_file &dwo_file, + dwarf2_cu &skeleton_cu, + dwarf2_section_info §ion, + ruh_kind section_kind) { - dwarf2_per_objfile *per_objfile = cu->per_objfile; - dwarf2_per_bfd *per_bfd = per_objfile->per_bfd; - const gdb_byte *info_ptr, *end_ptr; - auto §ion = dwo_file.sections.info; + dwarf2_per_objfile &per_objfile = *skeleton_cu.per_objfile; + dwarf2_per_bfd &per_bfd = *per_objfile.per_bfd; - info_ptr = section.buffer; + const gdb_byte *info_ptr = section.buffer; if (info_ptr == NULL) return; - dwarf_read_debug_printf ("Reading %s for %s:", - section.get_name (), + dwarf_read_debug_printf ("Reading %s for %s:", section.get_name (), section.get_file_name ()); - end_ptr = info_ptr + section.size; + const gdb_byte *end_ptr = info_ptr + section.size; + while (info_ptr < end_ptr) { sect_offset sect_off = (sect_offset) (info_ptr - section.buffer); + unit_head header; + dwarf2_section_info *abbrev_section = &dwo_file.sections.abbrev; + const gdb_byte *info_ptr_post_header + = read_and_check_unit_head (&header, §ion, abbrev_section, + info_ptr, section_kind); - /* The length of the CU gets set by the cutu_reader just below. */ - dwarf2_per_cu per_cu (per_bfd, §ion, sect_off, 0 /* length */, - false /* is_dwz */); - cutu_reader reader (per_cu, *per_objfile, language_minimal, - *cu, dwo_file); - - info_ptr += per_cu.length (); + unsigned int length = header.get_length_with_initial (); + info_ptr += length; - if (reader.is_dummy()) + /* Skip dummy units. */ + if (info_ptr_post_header >= info_ptr + || peek_abbrev_code (section.get_bfd_owner (), + info_ptr_post_header) == 0) continue; - /* DWARF 5 .debug_info.dwo sections may contain some type units. Skip - everything that is not a compile unit. */ - if (const auto ut = reader.cu ()->header.unit_type; - ut != DW_UT_compile && ut != DW_UT_split_compile) + if (header.unit_type != DW_UT_compile + && header.unit_type != DW_UT_split_compile + && header.unit_type != DW_UT_type + && header.unit_type != DW_UT_split_type) continue; - std::optional<ULONGEST> signature - = lookup_dwo_id (reader.cu (), reader.top_level_die ()); - if (!signature.has_value ()) + ULONGEST signature; + + /* For type units (all DWARF versions) and DWARF 5 compile units, the + signature/DWO ID is already available in the header. For compile + units in DWARF < 5, we need to read the DW_AT_GNU_dwo_id attribute + from the top-level DIE. + + For DWARF < 5 compile units, the unit type will be set to DW_UT_compile + by read_and_check_comp_unit_head. */ + if (header.version < 5 && header.unit_type == DW_UT_compile) { - complaint (_(DWARF_ERROR_PREFIX - "debug entry at offset %s is missing its dwo_id" - " [in module %s]"), - sect_offset_str (sect_off), - dwo_file.dwo_name.c_str ()); - continue; + /* The length of the CU is not necessary. */ + dwarf2_per_cu per_cu (&per_bfd, §ion, sect_off, length, + false /* is_dwz */); + cutu_reader reader (per_cu, per_objfile, language_minimal, + skeleton_cu, dwo_file); + + std::optional<ULONGEST> opt_signature + = lookup_dwo_id (reader.cu (), reader.top_level_die ()); + + if (!opt_signature.has_value ()) + { + complaint (_ (DWARF_ERROR_PREFIX + "debug entry at offset %s is missing its dwo_id" + " [in module %s]"), + sect_offset_str (sect_off), + dwo_file.dwo_name.c_str ()); + continue; + } + + signature = *opt_signature; } + else + signature = header.signature; - dwo_unit *dwo_unit = OBSTACK_ZALLOC (&per_bfd->obstack, struct dwo_unit); + dwo_unit *dwo_unit = OBSTACK_ZALLOC (&per_bfd.obstack, struct dwo_unit); + /* Set the fields common to compile and type units. */ dwo_unit->dwo_file = &dwo_file; - dwo_unit->signature = *signature; + dwo_unit->signature = signature; dwo_unit->section = §ion; dwo_unit->sect_off = sect_off; - dwo_unit->length = per_cu.length (); + dwo_unit->length = length; + + switch (header.unit_type) + { + case DW_UT_compile: + case DW_UT_split_compile: + { + dwarf_read_debug_printf (" compile unit at offset %s, dwo_id %s", + sect_offset_str (sect_off), + hex_string (dwo_unit->signature)); + + auto [it, inserted] = dwo_file.cus.emplace (dwo_unit); + if (!inserted) + complaint (_("debug cu entry at offset %s is duplicate to" + " the entry at offset %s, signature %s"), + sect_offset_str (sect_off), + sect_offset_str ((*it)->sect_off), + hex_string (dwo_unit->signature)); + break; + } + + case DW_UT_type: + case DW_UT_split_type: + { + dwo_unit->type_offset_in_tu = header.type_offset_in_tu; - dwarf_read_debug_printf (" offset %s, dwo_id %s", - sect_offset_str (sect_off), - hex_string (dwo_unit->signature)); + dwarf_read_debug_printf (" type unit at offset %s, signature %s", + sect_offset_str (sect_off), + hex_string (dwo_unit->signature)); - auto [it, inserted] = dwo_file.cus.emplace (dwo_unit); - if (!inserted) - complaint (_("debug cu entry at offset %s is duplicate to" - " the entry at offset %s, signature %s"), - sect_offset_str (sect_off), - sect_offset_str ((*it)->sect_off), - hex_string (dwo_unit->signature)); + auto [it, inserted] = dwo_file.tus.emplace (dwo_unit); + if (!inserted) + complaint (_("debug type entry at offset %s is duplicate to" + " the entry at offset %s, signature %s"), + sect_offset_str (sect_off), + sect_offset_str ((*it)->sect_off), + hex_string (header.signature)); + break; + } + } } } @@ -7572,7 +7516,7 @@ cutu_reader::locate_dwo_sections (struct objfile *objfile, bfd *abfd, if (names->abbrev_dwo.matches (sectp->name)) dw_sect = &dwo_sections->abbrev; else if (names->info_dwo.matches (sectp->name)) - dw_sect = &dwo_sections->info; + dw_sect = &dwo_sections->infos.emplace_back (dwarf2_section_info {}); else if (names->line_dwo.matches (sectp->name)) dw_sect = &dwo_sections->line; else if (names->loc_dwo.matches (sectp->name)) @@ -7590,16 +7534,14 @@ cutu_reader::locate_dwo_sections (struct objfile *objfile, bfd *abfd, else if (names->str_offsets_dwo.matches (sectp->name)) dw_sect = &dwo_sections->str_offsets; else if (names->types_dwo.matches (sectp->name)) - { - struct dwarf2_section_info type_section; - - memset (&type_section, 0, sizeof (type_section)); - dwo_sections->types.push_back (type_section); - dw_sect = &dwo_sections->types.back (); - } + dw_sect = &dwo_sections->types.emplace_back (dwarf2_section_info {}); if (dw_sect != nullptr) { + /* Make sure we don't overwrite a section info that has been filled in + already. */ + gdb_assert (!dw_sect->readin); + dw_sect->s.section = sectp; dw_sect->size = bfd_section_size (sectp); dw_sect->read (objfile); @@ -7615,7 +7557,6 @@ cutu_reader::open_and_init_dwo_file (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir) { dwarf2_per_objfile *per_objfile = cu->per_objfile; - dwarf2_per_bfd *per_bfd = per_objfile->per_bfd; gdb_bfd_ref_ptr dbfd = open_dwo_file (per_objfile->per_bfd, dwo_name, comp_dir); @@ -7635,15 +7576,16 @@ cutu_reader::open_and_init_dwo_file (dwarf2_cu *cu, const char *dwo_name, this->locate_dwo_sections (per_objfile->objfile, dwo_file->dbfd.get (), sec, &dwo_file->sections); - create_dwo_cus_hash_table (cu, *dwo_file); + /* There is normally just one .debug_info.dwo section in a DWO file. But when + building with -fdebug-types-section, gcc produces multiple .debug_info.dwo + sections. One for each produced type unit and one for the compile unit. + This is not expected, but we can easily enough deal with what gcc + produces. This behavior has been observed with gcc 14.2.1. */ + for (dwarf2_section_info §ion : dwo_file->sections.infos) + create_dwo_unit_hash_tables (*dwo_file, *cu, section, ruh_kind::COMPILE); - if (cu->header.version < 5) - create_dwo_debug_types_hash_table (per_bfd, dwo_file.get (), - dwo_file->sections.types); - else - create_dwo_debug_type_hash_table (per_bfd, dwo_file.get (), - &dwo_file->sections.info, - rcuh_kind::COMPILE); + for (dwarf2_section_info §ion : dwo_file->sections.types) + create_dwo_unit_hash_tables (*dwo_file, *cu, section, ruh_kind::TYPE); dwarf_read_debug_printf ("DWO file found: %s", dwo_name); @@ -7679,6 +7621,10 @@ dwarf2_locate_common_dwp_sections (struct objfile *objfile, bfd *abfd, if (dw_sect != nullptr) { + /* Make sure we don't overwrite a section info that has been filled in + already. */ + gdb_assert (!dw_sect->readin); + dw_sect->s.section = sectp; dw_sect->size = bfd_section_size (sectp); dw_sect->read (objfile); @@ -7724,6 +7670,10 @@ dwarf2_locate_v2_dwp_sections (struct objfile *objfile, bfd *abfd, if (dw_sect != nullptr) { + /* Make sure we don't overwrite a section info that has been filled in + already. */ + gdb_assert (!dw_sect->readin); + dw_sect->s.section = sectp; dw_sect->size = bfd_section_size (sectp); dw_sect->read (objfile); @@ -7767,6 +7717,10 @@ dwarf2_locate_v5_dwp_sections (struct objfile *objfile, bfd *abfd, if (dw_sect != nullptr) { + /* Make sure we don't overwrite a section info that has been filled in + already. */ + gdb_assert (!dw_sect->readin); + dw_sect->s.section = sectp; dw_sect->size = bfd_section_size (sectp); dw_sect->read (objfile); @@ -8883,7 +8837,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) parameter->kind = CALL_SITE_PARAMETER_PARAM_OFFSET; sect_offset sect_off = origin->get_ref_die_offset (); - if (!cu->header.offset_in_cu_p (sect_off)) + if (!cu->header.offset_in_unit_p (sect_off)) { /* As DW_OP_GNU_parameter_ref uses CU-relative offset this binding can be done only inside one CU. Such referenced DIE @@ -9251,7 +9205,7 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag, { dwarf2_per_objfile *per_objfile = cu->per_objfile; struct objfile *objfile = per_objfile->objfile; - struct comp_unit_head *cu_header = &cu->header; + unit_head *cu_header = &cu->header; bfd *obfd = objfile->obfd.get (); unsigned int addr_size = cu_header->addr_size; CORE_ADDR mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1)); @@ -12614,7 +12568,7 @@ static struct type * read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu) { struct gdbarch *gdbarch = cu->per_objfile->objfile->arch (); - struct comp_unit_head *cu_header = &cu->header; + unit_head *cu_header = &cu->header; struct type *type; struct attribute *attr_byte_size; struct attribute *attr_address_class; @@ -12729,7 +12683,7 @@ static struct type * read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu, enum type_code refcode) { - struct comp_unit_head *cu_header = &cu->header; + unit_head *cu_header = &cu->header; struct type *type, *target_type; struct attribute *attr; @@ -13634,7 +13588,6 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu) struct type *type; struct attribute *attr; ULONGEST encoding = 0; - int bits = 0; const char *name; attr = dwarf2_attr (die, DW_AT_encoding, cu); @@ -13644,9 +13597,33 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu) if (value.has_value ()) encoding = *value; } + attr = dwarf2_attr (die, DW_AT_byte_size, cu); + std::optional<ULONGEST> byte_size; if (attr != nullptr) - bits = attr->unsigned_constant ().value_or (0) * TARGET_CHAR_BIT; + byte_size = attr->unsigned_constant (); + attr = dwarf2_attr (die, DW_AT_bit_size, cu); + std::optional<ULONGEST> bit_size; + if (attr != nullptr) + bit_size = attr->unsigned_constant (); + + attr = dwarf2_attr (die, DW_AT_data_bit_offset, cu); + std::optional<ULONGEST> bit_offset; + if (attr != nullptr) + bit_offset = attr->unsigned_constant (); + + int bits = 0; + if (byte_size.has_value ()) + bits = TARGET_CHAR_BIT * *byte_size; + else if (bit_size.has_value ()) + bits = align_up (*bit_size, 8); + else + { + /* No size, so arrange for an error type. */ + complaint (_("DW_TAG_base_type has neither bit- nor byte-size")); + encoding = (ULONGEST) -1; + } + name = dwarf2_full_name (nullptr, die, cu); if (!name) complaint (_("DW_AT_name missing from DW_TAG_base_type")); @@ -13792,35 +13769,21 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu) type->set_endianity_is_not_default (not_default); - if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_INT) + /* If both a byte size and bit size were provided, then that means + that not every bit in the object contributes to the value. */ + if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_INT + && byte_size.has_value () + && bit_size.has_value ()) { - attr = dwarf2_attr (die, DW_AT_bit_size, cu); - if (attr != nullptr && attr->form_is_constant ()) + /* DWARF says: If this attribute is omitted a default data bit + offset of zero is assumed. */ + ULONGEST offset = bit_offset.value_or (0); + + /* Only use the attributes if they make sense together. */ + if (*bit_size + offset <= 8 * type->length ()) { - unsigned real_bit_size = attr->unsigned_constant ().value_or (0); - if (real_bit_size >= 0 && real_bit_size <= 8 * type->length ()) - { - attr = dwarf2_attr (die, DW_AT_data_bit_offset, cu); - /* Only use the attributes if they make sense together. */ - std::optional<ULONGEST> bit_offset; - if (attr == nullptr) - bit_offset = 0; - else if (attr->form_is_constant ()) - { - bit_offset = attr->unsigned_constant (); - if (bit_offset.has_value () - && *bit_offset + real_bit_size > 8 * type->length ()) - bit_offset.reset (); - } - if (bit_offset.has_value ()) - { - TYPE_MAIN_TYPE (type)->type_specific.int_stuff.bit_size - = real_bit_size; - if (attr != nullptr) - TYPE_MAIN_TYPE (type)->type_specific.int_stuff.bit_offset - = *bit_offset; - } - } + TYPE_MAIN_TYPE (type)->type_specific.int_stuff.bit_size = *bit_size; + TYPE_MAIN_TYPE (type)->type_specific.int_stuff.bit_offset = offset; } } @@ -14905,7 +14868,7 @@ cutu_reader::read_attribute_value (attribute *attr, unsigned form, { dwarf2_per_objfile *per_objfile = m_cu->per_objfile; struct objfile *objfile = per_objfile->objfile; - struct comp_unit_head *cu_header = &m_cu->header; + unit_head *cu_header = &m_cu->header; unsigned int bytes_read; struct dwarf_block *blk; @@ -15213,8 +15176,7 @@ read_indirect_string_at_offset (dwarf2_per_objfile *per_objfile, static const char * read_indirect_string (dwarf2_per_objfile *per_objfile, bfd *abfd, - const gdb_byte *buf, - const struct comp_unit_head *cu_header, + const gdb_byte *buf, const unit_head *cu_header, unsigned int *bytes_read_ptr) { LONGEST str_offset = cu_header->read_offset (abfd, buf, bytes_read_ptr); @@ -15238,7 +15200,7 @@ dwarf2_per_objfile::read_line_string (const gdb_byte *buf, const char * dwarf2_per_objfile::read_line_string (const gdb_byte *buf, - const struct comp_unit_head *cu_header, + const unit_head *cu_header, unsigned int *bytes_read_ptr) { bfd *abfd = objfile->obfd.get (); @@ -16570,7 +16532,7 @@ var_decode_location (struct attribute *attr, struct symbol *sym, struct dwarf2_cu *cu) { struct objfile *objfile = cu->per_objfile->objfile; - struct comp_unit_head *cu_header = &cu->header; + unit_head *cu_header = &cu->header; /* NOTE drow/2003-01-30: There used to be a comment and some special code here to turn a symbol with DW_AT_external and a @@ -17241,7 +17203,7 @@ dwarf2_const_value_attr (const struct attribute *attr, struct type *type, { dwarf2_per_objfile *per_objfile = cu->per_objfile; struct objfile *objfile = per_objfile->objfile; - struct comp_unit_head *cu_header = &cu->header; + unit_head *cu_header = &cu->header; struct dwarf_block *blk; enum bfd_endian byte_order = (bfd_big_endian (objfile->obfd.get ()) ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE); @@ -18217,18 +18179,18 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz, "source CU contains target offset: %d", sect_offset_str (source_cu->per_cu->sect_off), sect_offset_str (sect_off), - source_cu->header.offset_in_cu_p (sect_off)); + source_cu->header.offset_in_unit_p (sect_off)); if (source_cu->per_cu->is_debug_types) { /* .debug_types CUs cannot reference anything outside their CU. If they need to, they have to reference a signatured type via DW_FORM_ref_sig8. */ - if (!source_cu->header.offset_in_cu_p (sect_off)) + if (!source_cu->header.offset_in_unit_p (sect_off)) return NULL; } else if (offset_in_dwz != source_cu->per_cu->is_dwz - || !source_cu->header.offset_in_cu_p (sect_off)) + || !source_cu->header.offset_in_unit_p (sect_off)) { dwarf2_per_cu *target_per_cu = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz, @@ -19248,7 +19210,7 @@ dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym, /* See read.h. */ -const comp_unit_head * +const unit_head * dwarf2_per_cu::get_header () const { if (!m_header_read_in) @@ -19256,8 +19218,7 @@ dwarf2_per_cu::get_header () const const gdb_byte *info_ptr = this->section->buffer + to_underlying (this->sect_off); - read_comp_unit_head (&m_header, info_ptr, this->section, - rcuh_kind::COMPILE); + read_unit_head (&m_header, info_ptr, this->section, ruh_kind::COMPILE); m_header_read_in = true; } @@ -19286,7 +19247,7 @@ dwarf2_per_cu::offset_size () const int dwarf2_per_cu::ref_addr_size () const { - const comp_unit_head *header = this->get_header (); + const unit_head *header = this->get_header (); if (header->version == 2) return header->addr_size; diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h index f3e043c..5b4c8f6 100644 --- a/gdb/dwarf2/read.h +++ b/gdb/dwarf2/read.h @@ -22,7 +22,7 @@ #include <queue> #include "dwarf2/abbrev.h" -#include "dwarf2/comp-unit-head.h" +#include "dwarf2/unit-head.h" #include "dwarf2/file-and-dir.h" #include "dwarf2/index-cache.h" #include "dwarf2/mapped-index.h" @@ -233,14 +233,14 @@ public: /* Backlink to the owner of this. */ dwarf2_per_bfd *per_bfd; - /* DWARF header of this CU. Note that dwarf2_cu reads its own version of the - header, which may differ from this one, since it may pass rcuh_kind::TYPE - to read_comp_unit_head, whereas for dwarf2_per_cu we always pass - rcuh_kind::COMPILE. + /* DWARF header of this unit. Note that dwarf2_cu reads its own version of + the header, which may differ from this one, since it may pass + rch_kind::TYPE to read_unit_head, whereas for dwarf2_per_cu we always pass + ruh_kind::COMPILE. Don't access this field directly, use the get_header method instead. It should be private, but we can't make it private at the moment. */ - mutable comp_unit_head m_header; + mutable unit_head m_header; /* The file and directory for this CU. This is cached so that we don't need to re-examine the DWO in some situations. This may be @@ -271,7 +271,7 @@ public: std::vector<dwarf2_per_cu *> imported_symtabs; /* Get the header of this per_cu, reading it if necessary. */ - const comp_unit_head *get_header () const; + const unit_head *get_header () const; /* Return the address size given in the compilation unit header for this CU. */ @@ -812,7 +812,7 @@ struct dwarf2_per_objfile BUF is assumed to be in a compilation unit described by CU_HEADER. Return *BYTES_READ_PTR count of bytes read from BUF. */ const char *read_line_string (const gdb_byte *buf, - const struct comp_unit_head *cu_header, + const struct unit_head *unit_header, unsigned int *bytes_read_ptr); /* Return pointer to string at .debug_line_str offset as read from BUF. @@ -934,8 +934,6 @@ public: DISABLE_COPY_AND_ASSIGN (cutu_reader); - cutu_reader (cutu_reader &&) = default; - /* Return true if either: - the unit is empty (just a header without any DIE) @@ -1034,16 +1032,9 @@ private: void locate_dwo_sections (struct objfile *objfile, bfd *abfd, asection *sectp, struct dwo_sections *dwo_sections); - void create_dwo_cus_hash_table (dwarf2_cu *cu, dwo_file &dwo_file); - - void create_dwo_debug_types_hash_table - (dwarf2_per_bfd *per_bfd, dwo_file *dwo_file, - gdb::array_view<dwarf2_section_info> type_sections); - - void create_dwo_debug_type_hash_table (dwarf2_per_bfd *per_bfd, - dwo_file *dwo_file, - dwarf2_section_info *section, - rcuh_kind section_kind); + void create_dwo_unit_hash_tables (dwo_file &dwo_file, dwarf2_cu &skeleton_cu, + dwarf2_section_info §ion, + ruh_kind section_kind); dwo_unit *lookup_dwo_cutu (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir, ULONGEST signature, diff --git a/gdb/dwarf2/comp-unit-head.c b/gdb/dwarf2/unit-head.c index a35d664..0c7614f 100644 --- a/gdb/dwarf2/comp-unit-head.c +++ b/gdb/dwarf2/unit-head.c @@ -24,118 +24,117 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "dwarf2/comp-unit-head.h" +#include "dwarf2/unit-head.h" #include "dwarf2/leb.h" #include "dwarf2/section.h" #include "dwarf2/stringify.h" #include "dwarf2/error.h" -/* See comp-unit-head.h. */ +/* See unit-head.h. */ const gdb_byte * -read_comp_unit_head (struct comp_unit_head *cu_header, - const gdb_byte *info_ptr, - struct dwarf2_section_info *section, - rcuh_kind section_kind) +read_unit_head (struct unit_head *header, const gdb_byte *info_ptr, + struct dwarf2_section_info *section, ruh_kind section_kind) { int signed_addr; unsigned int bytes_read; const char *filename = section->get_file_name (); bfd *abfd = section->get_bfd_owner (); - cu_header->set_length (read_initial_length (abfd, info_ptr, &bytes_read)); - cu_header->initial_length_size = bytes_read; - cu_header->offset_size = (bytes_read == 4) ? 4 : 8; + header->set_length (read_initial_length (abfd, info_ptr, &bytes_read)); + header->initial_length_size = bytes_read; + header->offset_size = (bytes_read == 4) ? 4 : 8; info_ptr += bytes_read; unsigned version = read_2_bytes (abfd, info_ptr); if (version < 2 || version > 5) error (_(DWARF_ERROR_PREFIX - "wrong version in compilation unit header " + "wrong version in unit header " "(is %d, should be 2, 3, 4 or 5) [in module %s]"), version, filename); - cu_header->version = version; + header->version = version; info_ptr += 2; - if (cu_header->version < 5) + if (header->version < 5) switch (section_kind) { - case rcuh_kind::COMPILE: - cu_header->unit_type = DW_UT_compile; + case ruh_kind::COMPILE: + header->unit_type = DW_UT_compile; break; - case rcuh_kind::TYPE: - cu_header->unit_type = DW_UT_type; + case ruh_kind::TYPE: + header->unit_type = DW_UT_type; break; default: - internal_error (_("read_comp_unit_head: invalid section_kind")); + internal_error (_("read_unit_head: invalid section_kind")); } else { - cu_header->unit_type = static_cast<enum dwarf_unit_type> - (read_1_byte (abfd, info_ptr)); + header->unit_type + = static_cast<enum dwarf_unit_type> (read_1_byte (abfd, info_ptr)); info_ptr += 1; - switch (cu_header->unit_type) + switch (header->unit_type) { case DW_UT_compile: case DW_UT_partial: case DW_UT_skeleton: case DW_UT_split_compile: - if (section_kind != rcuh_kind::COMPILE) + if (section_kind != ruh_kind::COMPILE) error (_(DWARF_ERROR_PREFIX - "wrong unit_type in compilation unit header " + "wrong unit_type in unit header " "(is %s, should be %s) [in module %s]"), - dwarf_unit_type_name (cu_header->unit_type), + dwarf_unit_type_name (header->unit_type), dwarf_unit_type_name (DW_UT_type), filename); break; case DW_UT_type: case DW_UT_split_type: - section_kind = rcuh_kind::TYPE; + section_kind = ruh_kind::TYPE; break; default: error (_(DWARF_ERROR_PREFIX - "wrong unit_type in compilation unit header " + "wrong unit_type in unit header " "(is %#04x, should be one of: %s, %s, %s, %s or %s) " "[in module %s]"), - cu_header->unit_type, dwarf_unit_type_name (DW_UT_compile), + header->unit_type, dwarf_unit_type_name (DW_UT_compile), dwarf_unit_type_name (DW_UT_skeleton), dwarf_unit_type_name (DW_UT_split_compile), dwarf_unit_type_name (DW_UT_type), dwarf_unit_type_name (DW_UT_split_type), filename); } - cu_header->addr_size = read_1_byte (abfd, info_ptr); + header->addr_size = read_1_byte (abfd, info_ptr); info_ptr += 1; } - cu_header->abbrev_sect_off - = (sect_offset) cu_header->read_offset (abfd, info_ptr, &bytes_read); + header->abbrev_sect_off + = (sect_offset) header->read_offset (abfd, info_ptr, &bytes_read); info_ptr += bytes_read; - if (cu_header->version < 5) + if (header->version < 5) { - cu_header->addr_size = read_1_byte (abfd, info_ptr); + header->addr_size = read_1_byte (abfd, info_ptr); info_ptr += 1; } signed_addr = bfd_get_sign_extend_vma (abfd); if (signed_addr < 0) - internal_error (_("read_comp_unit_head: dwarf from non elf file")); - cu_header->signed_addr_p = signed_addr; + internal_error (_("read_unit_head: dwarf from non elf file")); + header->signed_addr_p = signed_addr; - bool header_has_signature = section_kind == rcuh_kind::TYPE - || cu_header->unit_type == DW_UT_skeleton - || cu_header->unit_type == DW_UT_split_compile; + bool header_has_signature = + (section_kind == ruh_kind::TYPE + || header->unit_type == DW_UT_skeleton + || header->unit_type == DW_UT_split_compile); if (header_has_signature) { - cu_header->signature = read_8_bytes (abfd, info_ptr); + header->signature = read_8_bytes (abfd, info_ptr); info_ptr += 8; } - if (section_kind == rcuh_kind::TYPE) + if (section_kind == ruh_kind::TYPE) { LONGEST type_offset; - type_offset = cu_header->read_offset (abfd, info_ptr, &bytes_read); + type_offset = header->read_offset (abfd, info_ptr, &bytes_read); info_ptr += bytes_read; - cu_header->type_cu_offset_in_tu = (cu_offset) type_offset; - if (to_underlying (cu_header->type_cu_offset_in_tu) != type_offset) + header->type_offset_in_tu = (cu_offset) type_offset; + if (to_underlying (header->type_offset_in_tu) != type_offset) error (_(DWARF_ERROR_PREFIX - "Too big type_offset in compilation unit " + "Too big type_offset in unit " "header (is %s) [in module %s]"), plongest (type_offset), filename); } @@ -143,60 +142,56 @@ read_comp_unit_head (struct comp_unit_head *cu_header, return info_ptr; } -/* Subroutine of read_and_check_comp_unit_head and - read_and_check_type_unit_head to simplify them. +/* Subroutine of read_and_check_unit_head to to simplify it. Perform various error checking on the header. */ static void -error_check_comp_unit_head (comp_unit_head *header, - dwarf2_section_info *section, - dwarf2_section_info *abbrev_section) +error_check_unit_head (unit_head *header, dwarf2_section_info *section, + dwarf2_section_info *abbrev_section) { const char *filename = section->get_file_name (); if (to_underlying (header->abbrev_sect_off) >= abbrev_section->size) error (_(DWARF_ERROR_PREFIX - "bad offset (%s) in compilation unit header " + "bad offset (%s) in unit header " "(offset %s + 6) [in module %s]"), sect_offset_str (header->abbrev_sect_off), - sect_offset_str (header->sect_off), - filename); + sect_offset_str (header->sect_off), filename); /* Cast to ULONGEST to use 64-bit arithmetic when possible to avoid potential 32-bit overflow. */ if (((ULONGEST) header->sect_off + header->get_length_with_initial ()) > section->size) error (_(DWARF_ERROR_PREFIX - "bad length (0x%x) in compilation unit header " + "bad length (0x%x) in unit header " "(offset %s + 0) [in module %s]"), header->get_length_without_initial (), sect_offset_str (header->sect_off), filename); } -/* See comp-unit-head.h. */ +/* See unit-head.h. */ const gdb_byte * -read_and_check_comp_unit_head (comp_unit_head *header, - dwarf2_section_info *section, - dwarf2_section_info *abbrev_section, - const gdb_byte *info_ptr, rcuh_kind section_kind) +read_and_check_unit_head (unit_head *header, dwarf2_section_info *section, + dwarf2_section_info *abbrev_section, + const gdb_byte *info_ptr, ruh_kind section_kind) { - const gdb_byte *beg_of_comp_unit = info_ptr; + const gdb_byte *beg_of_unit = info_ptr; - header->sect_off = (sect_offset) (beg_of_comp_unit - section->buffer); + header->sect_off = (sect_offset) (beg_of_unit - section->buffer); - info_ptr = read_comp_unit_head (header, info_ptr, section, section_kind); + info_ptr = read_unit_head (header, info_ptr, section, section_kind); - header->first_die_cu_offset = (cu_offset) (info_ptr - beg_of_comp_unit); + header->first_die_offset_in_unit = (cu_offset) (info_ptr - beg_of_unit); - error_check_comp_unit_head (header, section, abbrev_section); + error_check_unit_head (header, section, abbrev_section); return info_ptr; } unrelocated_addr -comp_unit_head::read_address (bfd *abfd, const gdb_byte *buf, - unsigned int *bytes_read) const +unit_head::read_address (bfd *abfd, const gdb_byte *buf, + unsigned int *bytes_read) const { ULONGEST retval = 0; diff --git a/gdb/dwarf2/comp-unit-head.h b/gdb/dwarf2/unit-head.h index ea09153..6272888 100644 --- a/gdb/dwarf2/comp-unit-head.h +++ b/gdb/dwarf2/unit-head.h @@ -24,18 +24,19 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef GDB_DWARF2_COMP_UNIT_HEAD_H -#define GDB_DWARF2_COMP_UNIT_HEAD_H +#ifndef GDB_DWARF2_UNIT_HEAD_H +#define GDB_DWARF2_UNIT_HEAD_H #include "dwarf2.h" #include "dwarf2/leb.h" #include "dwarf2/types.h" struct dwarf2_per_objfile; +struct dwarf2_section_info; -/* The data in a compilation unit header, after target2host - translation, looks like this. */ -struct comp_unit_head +/* The data in a unit header, after target2host translation, looks like + this. */ +struct unit_head { private: unsigned int m_length = 0; @@ -53,16 +54,16 @@ public: enum dwarf_unit_type unit_type {}; - /* Offset to first die in this cu from the start of the cu. - This will be the first byte following the compilation unit header. */ - cu_offset first_die_cu_offset {}; + /* Offset to first die in this unit from the start of the unit. + This will be the first byte following the unit header. */ + cu_offset first_die_offset_in_unit {}; - /* Offset to the first byte of this compilation unit header in the - .debug_info section, for resolving relative reference dies. */ + /* Offset to the first byte of this unit header in the containing section, + for resolving relative reference dies. */ sect_offset sect_off {}; /* For types, offset in the type's DIE of the type defined by this TU. */ - cu_offset type_cu_offset_in_tu {}; + cu_offset type_offset_in_tu {}; /* 64-bit signature of this unit. For type units, it denotes the signature of the type (DW_UT_type in DWARF 4, additionally DW_UT_split_type in DWARF 5). @@ -75,22 +76,22 @@ public: m_length = length; } - /* Return the total length of the CU described by this header, including the + /* Return the total length of the unit described by this header, including the initial length field. */ unsigned int get_length_with_initial () const { return m_length + initial_length_size; } - /* Return the total length of the CU described by this header, excluding the + /* Return the total length of the unit described by this header, excluding the initial length field. */ unsigned int get_length_without_initial () const { return m_length; } - /* Return TRUE if OFF is within this CU. */ - bool offset_in_cu_p (sect_offset off) const + /* Return TRUE if OFF is within this unit. */ + bool offset_in_unit_p (sect_offset off) const { sect_offset bottom = sect_off; sect_offset top = sect_off + get_length_with_initial (); @@ -98,7 +99,7 @@ public: } /* Read an offset from the data stream. The size of the offset is - given by cu_header->offset_size. */ + given by unit_head::offset_size. */ LONGEST read_offset (bfd *abfd, const gdb_byte *buf, unsigned int *bytes_read) const { @@ -112,25 +113,24 @@ public: unsigned int *bytes_read) const; }; -/* Expected enum dwarf_unit_type for read_comp_unit_head. */ -enum class rcuh_kind { COMPILE, TYPE }; +/* Expected enum dwarf_unit_type for read_unit_head. */ +enum class ruh_kind { COMPILE, TYPE }; -/* Read in the comp unit header information from the debug_info at info_ptr. - Use rcuh_kind::COMPILE as the default type if not known by the caller. - NOTE: This leaves members offset, first_die_offset to be filled in +/* Read in the unit header information from the debug_info at info_ptr. + Use ruh_kind::COMPILE as the default type if not known by the caller. + NOTE: This leaves members sect_off, first_die_unit_offset to be filled in by the caller. */ -extern const gdb_byte *read_comp_unit_head - (struct comp_unit_head *cu_header, - const gdb_byte *info_ptr, - struct dwarf2_section_info *section, - rcuh_kind section_kind); +extern const gdb_byte *read_unit_head (unit_head *header, + const gdb_byte *info_ptr, + dwarf2_section_info *section, + ruh_kind section_kind); -/* Read in a CU/TU header and perform some basic error checking. +/* Read in a unit header and perform some basic error checking. The contents of the header are stored in HEADER. The result is a pointer to the start of the first DIE. */ -extern const gdb_byte *read_and_check_comp_unit_head - (comp_unit_head *header, dwarf2_section_info *section, +extern const gdb_byte *read_and_check_unit_head + (unit_head *header, dwarf2_section_info *section, dwarf2_section_info *abbrev_section, const gdb_byte *info_ptr, - rcuh_kind section_kind); + ruh_kind section_kind); -#endif /* GDB_DWARF2_COMP_UNIT_HEAD_H */ +#endif /* GDB_DWARF2_UNIT_HEAD_H */ diff --git a/gdb/event-top.c b/gdb/event-top.c index c533e74..968117c 100644 --- a/gdb/event-top.c +++ b/gdb/event-top.c @@ -980,11 +980,6 @@ handle_fatal_signal (int sig) #endif #ifdef GDB_PRINT_INTERNAL_BACKTRACE - const auto sig_write = [] (const char *msg) -> void - { - gdb_stderr->write_async_safe (msg, strlen (msg)); - }; - if (bt_on_fatal_signal) { sig_write ("\n\n"); @@ -1027,7 +1022,13 @@ handle_fatal_signal (int sig) } sig_write ("\n\n"); - gdb_stderr->flush (); + if (gdb_stderr == nullptr || gdb_stderr->fd () == -1) + { + /* Writing to file descriptor instead of stream, no flush + required. */ + } + else + gdb_stderr->flush (); } #endif diff --git a/gdb/guile/scm-ports.c b/gdb/guile/scm-ports.c index ed43d64..f3e3ec8 100644 --- a/gdb/guile/scm-ports.c +++ b/gdb/guile/scm-ports.c @@ -336,9 +336,15 @@ ioscm_flush (SCM port) return; if (scm_is_eq (port, error_port_scm)) - gdb_flush (gdb_stderr); + { + if (gdb_stderr != nullptr) + gdb_flush (gdb_stderr); + } else - gdb_flush (gdb_stdout); + { + if (gdb_stdout != nullptr) + gdb_flush (gdb_stdout); + } } #else /* !USING_GUILE_BEFORE_2_2 */ diff --git a/gdb/maint.c b/gdb/maint.c index 766ab74..c6f9b32 100644 --- a/gdb/maint.c +++ b/gdb/maint.c @@ -1151,6 +1151,50 @@ set_per_command_cmd (const char *args, int from_tty) } } +/* See maint.h. */ + +scoped_time_it::scoped_time_it (const char *what) + : m_enabled (per_command_time), + m_what (what), + m_start_wall (m_enabled + ? std::chrono::steady_clock::now () + : std::chrono::steady_clock::time_point ()) +{ + if (m_enabled) + get_run_time (m_start_user, m_start_sys, run_time_scope::thread); +} + +/* See maint.h. */ + +scoped_time_it::~scoped_time_it () +{ + if (!m_enabled) + return; + + namespace chr = std::chrono; + auto end_wall = chr::steady_clock::now (); + + user_cpu_time_clock::time_point end_user; + system_cpu_time_clock::time_point end_sys; + get_run_time (end_user, end_sys, run_time_scope::thread); + + auto user = end_user - m_start_user; + auto sys = end_sys - m_start_sys; + auto wall = end_wall - m_start_wall; + auto user_ms = chr::duration_cast<chr::milliseconds> (user).count (); + auto sys_ms = chr::duration_cast<chr::milliseconds> (sys).count (); + auto wall_ms = chr::duration_cast<chr::milliseconds> (wall).count (); + auto user_plus_sys_ms = user_ms + sys_ms; + + auto str + = string_printf ("Time for \"%s\": wall %.03f, user %.03f, sys %.03f, " + "user+sys %.03f, %.01f %% CPU\n", + m_what, wall_ms / 1000.0, user_ms / 1000.0, + sys_ms / 1000.0, user_plus_sys_ms / 1000.0, + user_plus_sys_ms * 100.0 / wall_ms); + gdb_stdlog->write_async_safe (str.data (), str.size ()); +} + /* Options affecting the "maintenance selftest" command. */ struct maintenance_selftest_options diff --git a/gdb/maint.h b/gdb/maint.h index 0ddc62b..28e6280 100644 --- a/gdb/maint.h +++ b/gdb/maint.h @@ -70,6 +70,33 @@ class scoped_command_stats int m_start_nr_blocks; }; +/* RAII structure used to measure the time spent by the current thread in a + given scope. */ + +struct scoped_time_it +{ + /* WHAT is the prefix to show when the summary line is printed. */ + scoped_time_it (const char *what); + + DISABLE_COPY_AND_ASSIGN (scoped_time_it); + ~scoped_time_it (); + +private: + bool m_enabled; + + /* Summary line prefix. */ + const char *m_what; + + /* User time at the start of execution. */ + user_cpu_time_clock::time_point m_start_user; + + /* System time at the start of execution. */ + system_cpu_time_clock::time_point m_start_sys; + + /* Wall-clock time at the start of execution. */ + std::chrono::steady_clock::time_point m_start_wall; +}; + extern obj_section *maint_obj_section_from_bfd_section (bfd *abfd, asection *asection, objfile *ofile); diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c index 850a9ab..cda72ca 100644 --- a/gdb/mi/mi-main.c +++ b/gdb/mi/mi-main.c @@ -2218,7 +2218,7 @@ timestamp (struct mi_timestamp *tv) using namespace std::chrono; tv->wallclock = steady_clock::now (); - run_time_clock::now (tv->utime, tv->stime); + get_run_time (tv->utime, tv->stime, run_time_scope::process); } static void diff --git a/gdb/minsyms.c b/gdb/minsyms.c index 9ac3145..124d96d 100644 --- a/gdb/minsyms.c +++ b/gdb/minsyms.c @@ -37,6 +37,7 @@ #include <ctype.h> +#include "maint.h" #include "symtab.h" #include "bfd.h" #include "filenames.h" @@ -1481,6 +1482,8 @@ minimal_symbol_reader::install () gdb::parallel_for_each (10, &msymbols[0], &msymbols[mcount], [&] (minimal_symbol *start, minimal_symbol *end) { + scoped_time_it time_it ("minsyms install worker"); + for (minimal_symbol *msym = start; msym < end; ++msym) { size_t idx = msym - msymbols; diff --git a/gdb/parse.c b/gdb/parse.c index 3108017..64653c8 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -60,8 +60,8 @@ show_expressiondebug (struct ui_file *file, int from_tty, } -/* True if an expression parser should set yydebug. */ -static bool parser_debug; +/* See parser-defs.h. */ +bool parser_debug; static void show_parserdebug (struct ui_file *file, int from_tty, diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h index c13a56e..f5618f3 100644 --- a/gdb/parser-defs.h +++ b/gdb/parser-defs.h @@ -389,4 +389,7 @@ extern bool fits_in_type (int n_sign, const gdb_mpz &n, int type_bits, extern void parser_fprintf (FILE *, const char *, ...) ATTRIBUTE_PRINTF (2, 3); +/* True if an expression parser should set yydebug. */ +extern bool parser_debug; + #endif /* GDB_PARSER_DEFS_H */ diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 2be5eaa..6659c5a 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -1320,7 +1320,9 @@ process_print_command_args (const char *args, value_print_options *print_opts, value, so invert it for parse_expression. */ parser_flags flags = 0; if (!voidprint) - flags = PARSER_VOID_CONTEXT; + flags |= PARSER_VOID_CONTEXT; + if (parser_debug) + flags |= PARSER_DEBUG; expression_up expr = parse_expression (exp, nullptr, flags); return expr->evaluate (); } diff --git a/gdb/python/python.c b/gdb/python/python.c index 7e28eb6..24cb511 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -1612,16 +1612,19 @@ gdbpy_flush (PyObject *self, PyObject *args, PyObject *kw) { case 1: { - gdb_flush (gdb_stderr); + if (gdb_stderr != nullptr) + gdb_flush (gdb_stderr); break; } case 2: { - gdb_flush (gdb_stdlog); + if (gdb_stdlog != nullptr) + gdb_flush (gdb_stdlog); break; } default: - gdb_flush (gdb_stdout); + if (gdb_stdout != nullptr) + gdb_flush (gdb_stdout); } Py_RETURN_NONE; diff --git a/gdb/testsuite/gdb.base/exprs.exp b/gdb/testsuite/gdb.base/exprs.exp index eb2d0e4..f703c18 100644 --- a/gdb/testsuite/gdb.base/exprs.exp +++ b/gdb/testsuite/gdb.base/exprs.exp @@ -284,3 +284,21 @@ gdb_test "print v_short + " \ # Test for a syntax error in the middle of an expression. gdb_test "print v_short =}{= 3" \ "A syntax error in expression, near `\\}\\{= 3'\\." + +gdb_test_no_output "set debug parse 1" +set saw_start 0 +set saw_val 0 +gdb_test_multiple "print 23" "print with debugging" -lbl { + -re "\r\nStarting parse(?=\r\n)" { + set saw_start 1 + exp_continue + } + -re "\r\n.$decimal = 23(?=\r\n)" { + set saw_val 1 + exp_continue + } + + -re -wrap "" { + gdb_assert {$saw_start && $saw_val} $gdb_test_name + } +} diff --git a/gdb/testsuite/gdb.base/jit-bfd-name.exp b/gdb/testsuite/gdb.base/jit-bfd-name.exp index 9e4daa1..219929b 100644 --- a/gdb/testsuite/gdb.base/jit-bfd-name.exp +++ b/gdb/testsuite/gdb.base/jit-bfd-name.exp @@ -67,11 +67,13 @@ gdb_breakpoint [gdb_get_line_number "break here 1" $::main_srcfile] gdb_continue_to_breakpoint "break here 1" # Confirm that the two expected functions are available. +set re_f1 [string_to_regexp "int jit_function_0001(void)"] +set re_f2 [string_to_regexp "int jit_function_0002(void)"] gdb_test "info function ^jit_function" \ [multi_line \ "File \[^\r\n\]+jit-elf-solib.c:" \ - "${decimal}:\\s+int jit_function_0001\\(\\);" \ - "${decimal}:\\s+int jit_function_0002\\(\\);"] + "${decimal}:\\s+$re_f1;" \ + "${decimal}:\\s+$re_f2;"] # Capture the addresses of each JIT symfile. set symfile_addrs {} diff --git a/gdb/testsuite/gdb.base/jit-elf-solib.c b/gdb/testsuite/gdb.base/jit-elf-solib.c index 690d7a0..c6fcb89 100644 --- a/gdb/testsuite/gdb.base/jit-elf-solib.c +++ b/gdb/testsuite/gdb.base/jit-elf-solib.c @@ -22,4 +22,4 @@ #error "Must define the FUNCTION_NAME macro to set a jited function name" #endif -int FUNCTION_NAME() { return 42; } +int FUNCTION_NAME(void) { return 42; } diff --git a/gdb/testsuite/gdb.base/options.exp b/gdb/testsuite/gdb.base/options.exp index f32d258..7822e4a 100644 --- a/gdb/testsuite/gdb.base/options.exp +++ b/gdb/testsuite/gdb.base/options.exp @@ -62,8 +62,7 @@ proc check_completion_result {expected test} { # just checking whether GDB recognizes the option and auto-appends a # space. proc test_completer_recognizes {res input_line} { - set expected_re [string_to_regexp $input_line] - test_gdb_complete_unique $input_line $expected_re + test_gdb_complete_unique $input_line $input_line check_completion_result $res $input_line } diff --git a/gdb/testsuite/gdb.base/ptype.exp b/gdb/testsuite/gdb.base/ptype.exp index 788cdfc..6971f4c 100644 --- a/gdb/testsuite/gdb.base/ptype.exp +++ b/gdb/testsuite/gdb.base/ptype.exp @@ -544,10 +544,10 @@ proc ptype_maybe_prototyped { id prototyped plain { overprototyped "NO-MATCH" } fail "ptype $id (compiler doesn't emit prototyped types)" } -re "type = $overprototyped\[\r\n\]+$gdb_prompt $" { - if { [test_compiler_info "armcc-*"] } { - setup_xfail "*-*-*" - } - fail "ptype $id (compiler doesn't emit unprototyped types)" + # C23 no longer supports non-prototype function declaration, in which + # case the overprototyped regexp is the expected one. Simply pass + # in all cases. + pass "ptype $id (overprototyped)" } } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-error.exp b/gdb/testsuite/gdb.dwarf2/dw2-error.exp index f1c8617..0701ec6 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-error.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-error.exp @@ -37,7 +37,7 @@ set host_binfile [gdb_remote_download host $binfile] # First test that reading symbols fails. gdb_test "file $host_binfile" \ - {Reading symbols.*DWARF Error: wrong version in compilation unit header \(is 153, should be 2, 3, 4 or 5\).*} \ + {Reading symbols.*DWARF Error: wrong version in unit header \(is 153, should be 2, 3, 4 or 5\).*} \ "file $testfile" # We can't use proc readnow, because the PR makes it return 0. diff --git a/gdb/testsuite/gdb.dwarf2/intbits.c b/gdb/testsuite/gdb.dwarf2/intbits.c index 82e6ae8..909d283 100644 --- a/gdb/testsuite/gdb.dwarf2/intbits.c +++ b/gdb/testsuite/gdb.dwarf2/intbits.c @@ -41,6 +41,9 @@ unsigned char be30_1_off[4] = { 0x80, 0, 0, 2 }; here, to catch any situation where gdb tries to use the memory. */ unsigned char u32_0[4] = { 0xff, 0xff, 0xff, 0xff }; +/* An 8 bit slot holding a 3 bit value. */ +unsigned char just_bit_0 = 5; + int main (void) { diff --git a/gdb/testsuite/gdb.dwarf2/intbits.exp b/gdb/testsuite/gdb.dwarf2/intbits.exp index 7b50e15..ff1d69a 100644 --- a/gdb/testsuite/gdb.dwarf2/intbits.exp +++ b/gdb/testsuite/gdb.dwarf2/intbits.exp @@ -36,7 +36,7 @@ Dwarf::assemble ${asm_file} { {DW_AT_language @DW_LANG_C_plus_plus} } { declare_labels i7_type u1_type u17_type u31_type \ - u31_1_type u32_0_type u0_0_type be30_1_type + u31_1_type u32_0_type u0_0_type be30_1_type just_bit_type i7_type: DW_TAG_base_type { {DW_AT_encoding @DW_ATE_signed} @@ -167,6 +167,20 @@ Dwarf::assemble ${asm_file} { {DW_AT_location {DW_OP_addr [gdb_target_symbol "u32_0"]} SPECIAL_expr} } + + just_bit_type: DW_TAG_base_type { + {DW_AT_encoding @DW_ATE_unsigned} + {DW_AT_name "just_bit_type"} + {DW_AT_bit_size 3 DW_FORM_udata} + } + + DW_TAG_variable { + {DW_AT_name "v_just_bit"} + {DW_AT_type :${just_bit_type}} + {DW_AT_external 1 DW_FORM_flag} + {DW_AT_location {DW_OP_addr [gdb_target_symbol "just_bit_0"]} + SPECIAL_expr} + } } } } @@ -197,3 +211,6 @@ gdb_test "x/4xb &v_u32_1_off" ":\t0x0e\t0x00\t0x00\t0x00" gdb_test "print v_be30_1_off" "= 1" gdb_test "print v_be30_1_off = 7" " = 7" gdb_test "x/4xb &v_be30_1_off" ":\t0x00\t0x00\t0x00\t0x0e" + +gdb_test "print/x v_just_bit" " = 0x5" +gdb_test "print/x (just_bit_type) 5" " = 0x5" diff --git a/gdb/testsuite/gdb.python/py-color-leak.py b/gdb/testsuite/gdb.python/py-color-leak.py index 50dc315..28afd59 100644 --- a/gdb/testsuite/gdb.python/py-color-leak.py +++ b/gdb/testsuite/gdb.python/py-color-leak.py @@ -13,6 +13,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +import sys + +# Avoid generating +# src/gdb/testsuite/gdb.python/__pycache__/gdb_leak_detector.cpython-<n>.pyc. +sys.dont_write_bytecode = True + import gdb_leak_detector diff --git a/gdb/testsuite/gdb.python/py-inferior-leak.py b/gdb/testsuite/gdb.python/py-inferior-leak.py index f764688..bf61668 100644 --- a/gdb/testsuite/gdb.python/py-inferior-leak.py +++ b/gdb/testsuite/gdb.python/py-inferior-leak.py @@ -13,6 +13,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +import sys + +# Avoid generating +# src/gdb/testsuite/gdb.python/__pycache__/gdb_leak_detector.cpython-<n>.pyc. +sys.dont_write_bytecode = True + import re import gdb_leak_detector diff --git a/gdb/testsuite/gdb.python/py-objfile.c b/gdb/testsuite/gdb.python/py-objfile.c index fe68671..d721e0c 100644 --- a/gdb/testsuite/gdb.python/py-objfile.c +++ b/gdb/testsuite/gdb.python/py-objfile.c @@ -19,7 +19,7 @@ int global_var = 42; static int __attribute__ ((used)) static_var = 50; int -main () +main (void) { int some_var = 0; return 0; diff --git a/gdb/testsuite/gdb.python/py-objfile.exp b/gdb/testsuite/gdb.python/py-objfile.exp index d14eec6..8d11028 100644 --- a/gdb/testsuite/gdb.python/py-objfile.exp +++ b/gdb/testsuite/gdb.python/py-objfile.exp @@ -144,7 +144,8 @@ gdb_test "python print (sep_objfile.owner.filename)" "${testfile}2" \ gdb_test "python print (sep_objfile.owner.username)" "${testfile}2" \ "Test user-name of owner of separate debug file" -gdb_test "p main" "= {int \\(\\)} $hex <main>" \ +set re_prototype [string_to_regexp "int (void)"] +gdb_test "p main" "= {$re_prototype} $hex <main>" \ "print main with debug info" # Separate debug files are not findable. diff --git a/gdb/testsuite/gdb.python/py-read-memory-leak.py b/gdb/testsuite/gdb.python/py-read-memory-leak.py index 71edf47..89647cf 100644 --- a/gdb/testsuite/gdb.python/py-read-memory-leak.py +++ b/gdb/testsuite/gdb.python/py-read-memory-leak.py @@ -13,6 +13,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +import sys + +# Avoid generating +# src/gdb/testsuite/gdb.python/__pycache__/gdb_leak_detector.cpython-<n>.pyc. +sys.dont_write_bytecode = True + import gdb_leak_detector diff --git a/gdbsupport/run-time-clock.cc b/gdbsupport/run-time-clock.cc index 43da1d9..621ba77 100644 --- a/gdbsupport/run-time-clock.cc +++ b/gdbsupport/run-time-clock.cc @@ -38,13 +38,29 @@ timeval_to_microseconds (struct timeval *tv) #endif void -run_time_clock::now (user_cpu_time_clock::time_point &user, - system_cpu_time_clock::time_point &system) noexcept +get_run_time (user_cpu_time_clock::time_point &user, + system_cpu_time_clock::time_point &system, + run_time_scope scope) noexcept { #ifdef HAVE_GETRUSAGE struct rusage rusage; + int who; - getrusage (RUSAGE_SELF, &rusage); + switch (scope) + { + case run_time_scope::thread: + who = RUSAGE_THREAD; + break; + + case run_time_scope::process: + who = RUSAGE_SELF; + break; + + default: + gdb_assert_not_reached ("invalid run_time_scope value"); + } + + getrusage (who, &rusage); microseconds utime = timeval_to_microseconds (&rusage.ru_utime); microseconds stime = timeval_to_microseconds (&rusage.ru_stime); diff --git a/gdbsupport/run-time-clock.h b/gdbsupport/run-time-clock.h index a961f4c..a985dbb 100644 --- a/gdbsupport/run-time-clock.h +++ b/gdbsupport/run-time-clock.h @@ -51,6 +51,26 @@ struct system_cpu_time_clock static time_point now () noexcept = delete; }; +/* Whether to measure time run time for the whole process or just one + thread. */ + +enum class run_time_scope +{ + process, + thread, +}; + +/* Return the user/system time as separate time points, if + supported. If not supported, then the combined user+kernel time + is returned in USER and SYSTEM is set to zero. + + SCOPE indicates whether to return the run time for the whole process or + just for the calling thread. */ + +void get_run_time (user_cpu_time_clock::time_point &user, + system_cpu_time_clock::time_point &system, + run_time_scope scope) noexcept; + /* Count the total amount of time spent executing in userspace+kernel mode. */ @@ -64,12 +84,6 @@ struct run_time_clock static constexpr bool is_steady = true; static time_point now () noexcept; - - /* Return the user/system time as separate time points, if - supported. If not supported, then the combined user+kernel time - is returned in USER and SYSTEM is set to zero. */ - static void now (user_cpu_time_clock::time_point &user, - system_cpu_time_clock::time_point &system) noexcept; }; #endif /* GDBSUPPORT_RUN_TIME_CLOCK_H */ diff --git a/gprofng/src/Dwarf.cc b/gprofng/src/Dwarf.cc index a613c63..3b3fd63 100644 --- a/gprofng/src/Dwarf.cc +++ b/gprofng/src/Dwarf.cc @@ -454,7 +454,7 @@ DwrCU::parseChild (Dwarf_cnt *ctx) Dwarf_Die next_die; if (read_ref_attr (DW_AT_sibling, &next_die) == DW_DLV_OK) { - next_die_offset = next_die + cu_offset; + next_die_offset = next_die; if (next_die_offset <= debug_infoSec->offset) { Dprintf (DEBUG_ERR_MSG, NTXT ("DwrCU::parseChild: next_die(0x%llx) <= debug_infoSec->offset(%llx)\n"), @@ -723,7 +723,7 @@ DwrCU::read_hwcprof_info (Dwarf_cnt *ctx) Dwarf_Die next_die; if (read_ref_attr (DW_AT_sibling, &next_die) == DW_DLV_OK) { - next_die_offset = next_die + cu_offset; + next_die_offset = next_die; if (next_die_offset <= debug_infoSec->offset) next_die_offset = 0; else if (debug_infoSec->size > next_die_offset) diff --git a/gprofng/src/DwarfLib.cc b/gprofng/src/DwarfLib.cc index d399c33..3594c2f 100644 --- a/gprofng/src/DwarfLib.cc +++ b/gprofng/src/DwarfLib.cc @@ -1847,7 +1847,7 @@ DwrCU::DwrCU (Dwarf *_dwarf) (long long) cu_offset, (long long) cu_offset, (long long) next_cu_offset, (long long) next_cu_offset, (long long) debug_abbrev_offset, (long long) debug_abbrev_offset, - (long long) (next_cu_offset - cu_offset), + (long long) (next_cu_offset), (int) version, (int) address_size, debug_infoSec->fmt64 ? "true" : "false", debug_infoSec->need_swap_endian ? "true" : "false", @@ -1945,7 +1945,7 @@ DwrCU::set_die (Dwarf_Die die) || debug_infoSec->offset >= debug_infoSec->size) return DW_DLV_ERROR; dwrTag.offset = debug_infoSec->offset; - dwrTag.die = debug_infoSec->offset - cu_offset; + dwrTag.die = debug_infoSec->offset; dwrTag.num = debug_infoSec->GetULEB128_32 (); if (dwrTag.num == 0) return DW_DLV_NO_ENTRY; @@ -1994,19 +1994,19 @@ DwrCU::set_die (Dwarf_Die die) atf->u.str = debug_infoSec->GetData (atf->len); break; case DW_FORM_ref1: - atf->u.offset = debug_infoSec->Get_8 (); + atf->u.offset = debug_infoSec->Get_8 () + cu_offset; break; case DW_FORM_ref2: - atf->u.offset = debug_infoSec->Get_16 (); + atf->u.offset = debug_infoSec->Get_16 () + cu_offset; break; case DW_FORM_ref4: - atf->u.offset = debug_infoSec->Get_32 (); + atf->u.offset = debug_infoSec->Get_32 () + cu_offset; break; case DW_FORM_ref8: - atf->u.offset = debug_infoSec->Get_64 (); + atf->u.offset = debug_infoSec->Get_64 () + cu_offset; break; case DW_FORM_ref_udata: - atf->u.offset = debug_infoSec->GetULEB128 (); + atf->u.offset = debug_infoSec->GetULEB128 () + cu_offset; break; case DW_FORM_data1: atf->u.offset = debug_infoSec->Get_8 (); 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/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/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-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/opcodes/config.in b/opcodes/config.in index 409998f..64b3303 100644 --- a/opcodes/config.in +++ b/opcodes/config.in @@ -98,9 +98,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/opcodes/configure b/opcodes/configure index 554a070..4b6e965 100755 --- a/opcodes/configure +++ b/opcodes/configure @@ -646,8 +646,6 @@ cgendir CGEN_MAINT_FALSE CGEN_MAINT_TRUE HDEFINES -ENABLE_BFD_64_BIT_FALSE -ENABLE_BFD_64_BIT_TRUE EXEEXT_FOR_BUILD CC_FOR_BUILD CATOBJEXT @@ -819,7 +817,6 @@ with_libiconv_prefix with_libiconv_type with_libintl_prefix with_libintl_type -enable_64_bit_bfd enable_cgen_maint ' ac_precious_vars='build_alias @@ -1471,7 +1468,6 @@ Optional Features: --enable-install-libbfd controls installation of libbfd and related headers --disable-nls do not use Native Language Support --disable-rpath do not hardcode runtime library paths - --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes) --enable-cgen-maint=dir build cgen generated files Optional Packages: @@ -1926,189 +1922,6 @@ $as_echo "$ac_res" >&6; } } # ac_fn_c_check_func -# 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 @@ -11090,7 +10903,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11093 "configure" +#line 10906 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11196,7 +11009,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11199 "configure" +#line 11012 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -14025,70 +13838,40 @@ $as_echo "$bfd_cv_build_exeext" >&6; } test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext} 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 @@ -14567,7 +14350,7 @@ if test x${all_targets} = xfalse ; then else # all_targets is true archdefs=-DARCH_all - if test "$enable_64_bit_bfd" = "yes" ; then + if test "$have_64_bit_bfd" = "yes" ; then BFD_MACHINES='$(ALL32_MACHINES) $(ALL64_MACHINES)' else BFD_MACHINES='$(ALL32_MACHINES)' @@ -14720,10 +14503,6 @@ if test -z "${INSTALL_LIBBFD_TRUE}" && test -z "${INSTALL_LIBBFD_FALSE}"; then as_fn_error $? "conditional \"INSTALL_LIBBFD\" 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 "${CGEN_MAINT_TRUE}" && test -z "${CGEN_MAINT_FALSE}"; then as_fn_error $? "conditional \"CGEN_MAINT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/opcodes/configure.ac b/opcodes/configure.ac index 4f8c734..b30f9f8 100644 --- a/opcodes/configure.ac +++ b/opcodes/configure.ac @@ -383,7 +383,7 @@ if test x${all_targets} = xfalse ; then else # all_targets is true archdefs=-DARCH_all - if test "$enable_64_bit_bfd" = "yes" ; then + if test "$have_64_bit_bfd" = "yes" ; then BFD_MACHINES='$(ALL32_MACHINES) $(ALL64_MACHINES)' else BFD_MACHINES='$(ALL32_MACHINES)' diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c index ba93e56..712cd31 100644 --- a/opcodes/ppc-opc.c +++ b/opcodes/ppc-opc.c @@ -691,6 +691,52 @@ extract_imm32 (uint64_t insn, return (insn & 0xffff) | ((insn >> 16) & 0xffff0000); } +/* The 32bit SI field in a 64-bit D form prefix instruction when the field is split + into separate SI0 and SI1 fields. */ + +static uint64_t +insert_si32 (uint64_t insn, + int64_t value, + ppc_cpu_t dialect ATTRIBUTE_UNUSED, + const char **errmsg ATTRIBUTE_UNUSED) +{ + return insn | ((value & 0xffff0000ULL) << 16) | (value & 0xffff); +} + +static int64_t +extract_si32 (uint64_t insn, + ppc_cpu_t dialect ATTRIBUTE_UNUSED, + int *invalid ATTRIBUTE_UNUSED) +{ + int64_t mask = 1ULL << 31; + int64_t value = ((insn >> 16) & 0xffff0000ULL) | (insn & 0xffff); + value = (value ^ mask) - mask; + return value; +} + +/* The NSI32 field in an 8-byte D form prefix instruction. This is the same + as the SI32 field, only negated. The extraction function always marks it + as invalid, since we never want to recognize an instruction which uses + a field of this type. */ +static uint64_t +insert_nsi32 (uint64_t insn, + int64_t value, + ppc_cpu_t dialect, + const char **errmsg) +{ + return insert_si32 (insn, -value, dialect, errmsg); +} + +static int64_t +extract_nsi32 (uint64_t insn, + ppc_cpu_t dialect, + int *invalid) +{ + int64_t value = extract_si32 (insn, dialect, invalid); + *invalid = 1; + return -value; +} + /* The R field in an 8-byte prefix instruction when there are restrictions between R's value and the RA value (ie, they cannot both be non zero). */ @@ -3073,8 +3119,18 @@ const struct powerpc_operand powerpc_operands[] = { UINT64_C(0x3ffffffff), PPC_OPSHIFT_INV, insert_nsi34, extract_nsi34, PPC_OPERAND_NEGATIVE | PPC_OPERAND_SIGNED }, + /* The 32bit SI field in an 8-byte D form prefix instruction. */ +#define SI32 NSI34 + 1 + { UINT64_C(0xffffffff), PPC_OPSHIFT_INV, insert_si32, extract_si32, PPC_OPERAND_SIGNED }, + + /* The NSI field in an 8-byte D form prefix instruction with 32bit SI field. This is + the same as the SI32 field, only negated. */ +#define NSI32 SI32 + 1 + { UINT64_C(0xffffffff), PPC_OPSHIFT_INV, insert_nsi32, extract_nsi32, + PPC_OPERAND_NEGATIVE | PPC_OPERAND_SIGNED }, + /* The IMM32 field in a vector splat immediate prefix instruction. */ -#define IMM32 NSI34 + 1 +#define IMM32 NSI32 + 1 { 0xffffffff, PPC_OPSHIFT_INV, insert_imm32, extract_imm32, 0}, /* The UIM field in a vector permute extended prefix instruction. */ @@ -4031,9 +4087,15 @@ const unsigned int num_powerpc_operands = ARRAY_SIZE (powerpc_operands); /* An 8-byte D form prefix instruction. */ #define P_D_MASK (((-1ULL << 50) & ~PCREL_MASK) | OP_MASK) +/* An 8-byte D form prefix instruction with 32bit SI field. */ +#define P_D_SI32_MASK (((-1ULL << 48) & ~PCREL_MASK) | OP_MASK) + /* The same as P_D_MASK, but with the RA and PCREL fields specified. */ #define P_DRAPCREL_MASK (P_D_MASK | PCREL_MASK | RA_MASK) +/* The same as P_D_SI32_MASK, but with the RA and PCREL fields specified. */ +#define P_DRAPCREL_SI32_MASK (P_D_SI32_MASK | PCREL_MASK | RA_MASK) + /* Mask for prefix X form instructions. */ #define P_X_MASK (PREFIX_MASK | X_MASK) #define P_XX1_MASK (PREFIX_MASK | XX1_MASK) @@ -9863,6 +9925,9 @@ const struct powerpc_opcode prefix_opcodes[] = { {"pla", PMLS|OP(14), P_D_MASK, POWER10, EXT, {RT, D34, PRA0, PCREL1}}, {"paddi", PMLS|OP(14), P_D_MASK, POWER10, 0, {RT, RA0, SI34, PCREL}}, {"psubi", PMLS|OP(14), P_D_MASK, POWER10, EXT, {RT, RA0, NSI34, PCREL}}, +{"plis", PMLS|OP(15), P_DRAPCREL_SI32_MASK, FUTURE, EXT, {RT, SI32}}, +{"paddis", PMLS|OP(15), P_D_SI32_MASK, FUTURE, 0, {RT, RA0, SI32, PCREL}}, +{"psubis", PMLS|OP(15), P_D_SI32_MASK, FUTURE, EXT, {RT, RA0, NSI32, PCREL}}, {"xxsplti32dx", P8RR|VSOP(32,0), P_VSI_MASK, POWER10, 0, {XTS, IX, IMM32}}, {"xxspltidp", P8RR|VSOP(32,2), P_VS_MASK, POWER10, 0, {XTS, IMM32}}, {"xxspltiw", P8RR|VSOP(32,3), P_VS_MASK, POWER10, 0, {XTS, IMM32}}, diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index e07f72b..6f49fdb 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -907,8 +907,8 @@ const struct riscv_opcode riscv_opcodes[] = {"feq.h", 0, INSN_CLASS_ZFH_INX, "d,S,T", MATCH_FEQ_H, MASK_FEQ_H, match_opcode, 0 }, {"flt.h", 0, INSN_CLASS_ZFH_INX, "d,S,T", MATCH_FLT_H, MASK_FLT_H, match_opcode, 0 }, {"fle.h", 0, INSN_CLASS_ZFH_INX, "d,S,T", MATCH_FLE_H, MASK_FLE_H, match_opcode, 0 }, -{"fgt.h", 0, INSN_CLASS_ZFH_INX, "d,T,S", MATCH_FLT_H, MASK_FLT_H, match_opcode, 0 }, -{"fge.h", 0, INSN_CLASS_ZFH_INX, "d,T,S", MATCH_FLE_H, MASK_FLE_H, match_opcode, 0 }, +{"fgt.h", 0, INSN_CLASS_ZFH_INX, "d,T,S", MATCH_FLT_H, MASK_FLT_H, match_opcode, INSN_ALIAS }, +{"fge.h", 0, INSN_CLASS_ZFH_INX, "d,T,S", MATCH_FLE_H, MASK_FLE_H, match_opcode, INSN_ALIAS }, {"fcvt.l.h", 64, INSN_CLASS_ZFH_INX, "d,S", MATCH_FCVT_L_H|MASK_RM, MASK_FCVT_L_H|MASK_RM, match_opcode, 0 }, {"fcvt.l.h", 64, INSN_CLASS_ZFH_INX, "d,S,m", MATCH_FCVT_L_H, MASK_FCVT_L_H, match_opcode, 0 }, {"fcvt.lu.h", 64, INSN_CLASS_ZFH_INX, "d,S", MATCH_FCVT_LU_H|MASK_RM, MASK_FCVT_LU_H|MASK_RM, match_opcode, 0 }, @@ -990,8 +990,8 @@ const struct riscv_opcode riscv_opcodes[] = {"feq.s", 0, INSN_CLASS_F_INX, "d,S,T", MATCH_FEQ_S, MASK_FEQ_S, match_opcode, 0 }, {"flt.s", 0, INSN_CLASS_F_INX, "d,S,T", MATCH_FLT_S, MASK_FLT_S, match_opcode, 0 }, {"fle.s", 0, INSN_CLASS_F_INX, "d,S,T", MATCH_FLE_S, MASK_FLE_S, match_opcode, 0 }, -{"fgt.s", 0, INSN_CLASS_F_INX, "d,T,S", MATCH_FLT_S, MASK_FLT_S, match_opcode, 0 }, -{"fge.s", 0, INSN_CLASS_F_INX, "d,T,S", MATCH_FLE_S, MASK_FLE_S, match_opcode, 0 }, +{"fgt.s", 0, INSN_CLASS_F_INX, "d,T,S", MATCH_FLT_S, MASK_FLT_S, match_opcode, INSN_ALIAS }, +{"fge.s", 0, INSN_CLASS_F_INX, "d,T,S", MATCH_FLE_S, MASK_FLE_S, match_opcode, INSN_ALIAS }, {"fcvt.l.s", 64, INSN_CLASS_F_INX, "d,S", MATCH_FCVT_L_S|MASK_RM, MASK_FCVT_L_S|MASK_RM, match_opcode, 0 }, {"fcvt.l.s", 64, INSN_CLASS_F_INX, "d,S,m", MATCH_FCVT_L_S, MASK_FCVT_L_S, match_opcode, 0 }, {"fcvt.lu.s", 64, INSN_CLASS_F_INX, "d,S", MATCH_FCVT_LU_S|MASK_RM, MASK_FCVT_LU_S|MASK_RM, match_opcode, 0 }, @@ -1049,8 +1049,8 @@ const struct riscv_opcode riscv_opcodes[] = {"feq.d", 0, INSN_CLASS_D_INX, "d,S,T", MATCH_FEQ_D, MASK_FEQ_D, match_opcode, 0 }, {"flt.d", 0, INSN_CLASS_D_INX, "d,S,T", MATCH_FLT_D, MASK_FLT_D, match_opcode, 0 }, {"fle.d", 0, INSN_CLASS_D_INX, "d,S,T", MATCH_FLE_D, MASK_FLE_D, match_opcode, 0 }, -{"fgt.d", 0, INSN_CLASS_D_INX, "d,T,S", MATCH_FLT_D, MASK_FLT_D, match_opcode, 0 }, -{"fge.d", 0, INSN_CLASS_D_INX, "d,T,S", MATCH_FLE_D, MASK_FLE_D, match_opcode, 0 }, +{"fgt.d", 0, INSN_CLASS_D_INX, "d,T,S", MATCH_FLT_D, MASK_FLT_D, match_opcode, INSN_ALIAS }, +{"fge.d", 0, INSN_CLASS_D_INX, "d,T,S", MATCH_FLE_D, MASK_FLE_D, match_opcode, INSN_ALIAS }, {"fmv.x.d", 64, INSN_CLASS_D, "d,S", MATCH_FMV_X_D, MASK_FMV_X_D, match_opcode, 0 }, {"fmv.d.x", 64, INSN_CLASS_D, "D,s", MATCH_FMV_D_X, MASK_FMV_D_X, match_opcode, 0 }, {"fcvt.l.d", 64, INSN_CLASS_D_INX, "d,S", MATCH_FCVT_L_D|MASK_RM, MASK_FCVT_L_D|MASK_RM, match_opcode, 0 }, @@ -1109,8 +1109,8 @@ const struct riscv_opcode riscv_opcodes[] = {"feq.q", 0, INSN_CLASS_Q_INX, "d,S,T", MATCH_FEQ_Q, MASK_FEQ_Q, match_opcode, 0 }, {"flt.q", 0, INSN_CLASS_Q_INX, "d,S,T", MATCH_FLT_Q, MASK_FLT_Q, match_opcode, 0 }, {"fle.q", 0, INSN_CLASS_Q_INX, "d,S,T", MATCH_FLE_Q, MASK_FLE_Q, match_opcode, 0 }, -{"fgt.q", 0, INSN_CLASS_Q_INX, "d,T,S", MATCH_FLT_Q, MASK_FLT_Q, match_opcode, 0 }, -{"fge.q", 0, INSN_CLASS_Q_INX, "d,T,S", MATCH_FLE_Q, MASK_FLE_Q, match_opcode, 0 }, +{"fgt.q", 0, INSN_CLASS_Q_INX, "d,T,S", MATCH_FLT_Q, MASK_FLT_Q, match_opcode, INSN_ALIAS }, +{"fge.q", 0, INSN_CLASS_Q_INX, "d,T,S", MATCH_FLE_Q, MASK_FLE_Q, match_opcode, INSN_ALIAS }, {"fcvt.l.q", 64, INSN_CLASS_Q_INX, "d,S", MATCH_FCVT_L_Q|MASK_RM, MASK_FCVT_L_Q|MASK_RM, match_opcode, 0 }, {"fcvt.l.q", 64, INSN_CLASS_Q_INX, "d,S,m", MATCH_FCVT_L_Q, MASK_FCVT_L_Q, match_opcode, 0 }, {"fcvt.lu.q", 64, INSN_CLASS_Q_INX, "d,S", MATCH_FCVT_LU_Q|MASK_RM, MASK_FCVT_LU_Q|MASK_RM, match_opcode, 0 }, |