From 6efde559c98c21020b27d8293ad3e969113502262c103e4300d373969677d811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Schr=C3=B6ter?= Date: Fri, 25 Apr 2025 21:16:26 +0200 Subject: [PATCH] Sync from SUSE:SLFO:Main gdb revision de16ec04e97db4a7d01aef1f6f4187fa --- add-dwarf_expr_piece.op.patch | 100 + ...gdbarch_dwarf2_reg_piece_offset-hook.patch | 220 + ...slators-not-to-translate-z-architect.patch | 25 - ...b.base-examine-backwards.exp-for-aix.patch | 53 - ...lding-for-the-s390-target-with-clang.patch | 30 - ...da-o2_float_param.exp-on-s390x-linux.patch | 144 + fix-gdb.base-finish-pretty.exp-on-s390x.patch | 188 + fix-gdb.base-readnever.exp-on-s390x.patch | 187 + fix-gdb.base-store.exp-on-s390x.patch | 143 + fix-gdb.dap-step-out.exp-on-s390x.patch | 97 + fix-gdb.dwarf2-shortpiece.exp-on-s390x.patch | 56 + ...egression-on-aarch64-linux-gdbserver.patch | 366 - ...e-gdb.ada-inline-section-gc.exp-test.patch | 80 - fixup-gdb-6.3-attach-see-vdso-test.patch | 30 - fixup-gdb-6.3-gstack-20050411.patch | 25 - ...5-bz243845-stale-testing-zombie-test.patch | 35 - fixup-gdb-6.5-gcore-buffer-limit-test.patch | 25 + fixup-gdb-add-rpm-suggestion-script.patch | 26 + fixup-gdb-bz634108-solib_address.patch | 22 - fixup-gdb-glibc-strstr-workaround.patch | 19 - fixup-gdb-linux_perf-bundle.patch | 40 - ...61564-aarch64-hw-watchpoint-test.pat.patch | 43 - fixup-gdb-test-bt-cfi-without-die.patch | 38 - fixup-gdb-test-dw2-aranges.patch | 21 - ...d-aarch64-fix-reverse-stepping-failu.patch | 70 - fixup-skip-tests.patch | 101 - gdb-14.2.tar.bz2 | 3 - gdb-15.2.tar.bz2 | 3 + gdb-6.3-attach-see-vdso-test.patch | 120 - gdb-6.3-gstack-20050411.patch | 24 +- ...337-resolve-tls-without-debuginfo-v2.patch | 265 - ...5-bz243845-stale-testing-zombie-test.patch | 89 - gdb-6.5-section-num-fixup-test.patch | 127 - ...buildid-locate-rpm-librpm-workaround.patch | 19 - gdb-6.6-buildid-locate-rpm-suse.patch | 123 - gdb-6.6-buildid-locate-rpm.patch | 1084 --- gdb-6.6-buildid-locate-tests-suse.patch | 40 + ...atch => gdb-6.6-buildid-locate-tests.patch | 143 +- gdb-6.6-buildid-locate.patch | 1925 ----- gdb-6.6-bz229517-gcore-without-terminal.patch | 188 - gdb-6.6-testsuite-timeouts.patch | 32 - gdb-add-deprecated-settings-py-script.patch | 68 + gdb-add-rpm-suggestion-script-suse.patch | 40 + gdb-add-rpm-suggestion-script.patch | 806 ++ gdb-archer-next-over-throw-cxx-exec.patch | 2 +- gdb-arm-fix-epilogue-frame-id.patch | 47 - ...humb-bit-in-arm_adjust_breakpoint_ad.patch | 77 - ...pidruro-register-from-non-freebsd-ta.patch | 219 - gdb-backport-buildid-related-changes.patch | 6753 +++++++++++++++++ ...gdbserver-linux-aarch64-low.cc-build.patch | 41 - gdb-build-fix-unused-var-in-corelow.c.patch | 46 + gdb-bz634108-solib_address.patch | 41 - gdb-catchpoint-re-set.patch | 575 ++ gdb-cli-print-at_hwcap3-and-at_hwcap4.patch | 41 + gdb-core-open-vdso-warning.patch | 58 - gdb-doc-fix-gdb.unwinder-docs.patch | 61 + gdb-doc-fix-qisaddresstagged-anchor.patch | 41 + gdb-doc-fix-standard-replies-xref.patch | 44 + ...xp-fix-cast-handling-for-indirection.patch | 150 - ...b.fortran-intrinsics.exp-fail-on-arm.patch | 232 + ...ting-of-out-of-bounds-struct-members.patch | 365 - ...p-redo-cast-handling-for-indirection.patch | 86 - gdb-fedora-libncursesw.patch | 333 - ...p-use-after-free-in-select_event_lwp.patch | 144 - ...ix-segfault-in-for_each_block-part-1.patch | 636 -- ...ix-segfault-in-for_each_block-part-2.patch | 168 - gdb-ftbs-swapped-calloc-args.patch | 42 - gdb-gcore-bash.patch | 2 +- gdb-glibc-strstr-workaround.patch | 132 - ...le-use-scm_debug_typing_strictness-0.patch | 68 + gdb-linux_perf-bundle.patch | 226 - ...ne-inferior-after-switching-inferior.patch | 130 + gdb-python-finishbreakpoint-update.patch | 28 +- ...db.python-py-disasm.exp-on-arm-linux.patch | 125 - ...windinfo.add_saved_register-mo-fixup.patch | 70 - ...gdb.unwindinfo.add_saved_register-mo.patch | 61 - ...ut-of-bounds-write-in-aarch64_record.patch | 89 + ...mote-fix-abort-on-remote_close_error.patch | 229 - gdb-remove-qnx-neutrino-support.patch | 2923 +++++++ gdb-rhbz-2232086-cpp-ify-mapped-symtab.patch | 264 - ...-generate-dwarf-5-index-consistently.patch | 101 - ...2086-generate-gdb-index-consistently.patch | 230 - ...hbz-2232086-reduce-size-of-gdb-index.patch | 222 - ...07614-memleak-infpy_read_memory-test.patch | 170 - ...bz1261564-aarch64-hw-watchpoint-test.patch | 104 - ...hbz2232086-refactor-selftest-support.patch | 77 - ...hbz2250652-avoid-PyOS_ReadlineTState.patch | 48 - gdb-rhbz2250652-gdbpy_gil.patch | 81 - ...2261580-intrusive_list-assertion-fix.patch | 55 - ...dvar-assertion-frame-failed-testcase.patch | 147 - ...390-add-arch14-record-replay-support.patch | 50 - ...ltaneous-step-resume-breakpoint-test.patch | 162 - gdb-symtab-add-producer_is_gas.patch | 125 - ...-defer-backward-refs-inter-cu-intra-.patch | 74 - ...-factor-out-m_deferred_entries-usage.patch | 76 - ...tab-factor-out-m_die_range_map-usage.patch | 151 - ...w_tag_inlined_subroutine-entries-in-.patch | 112 - ...arget-type-of-complex-long-double-on.patch | 337 + ...e-nullptr-parent-in-parent_map-set_p.patch | 37 - ...track-of-all-parents-for-cooked-inde.patch | 38 - ...eep-track-of-processed-dies-in-shard.patch | 126 - ...efactor-condition-in-scan_attributes.patch | 70 - ...ve-deferred-entries-inter-shard-case.patch | 500 -- ...ve-deferred-entries-intra-shard-case.patch | 120 - gdb-symtab-work-around-gas-pr28629.patch | 278 - ...work-around-pr-gas-29517-dwarf2-case.patch | 137 - gdb-symtab-work-around-pr-gas-29517.patch | 256 - gdb-symtab-workaround-pr-gas-31115.patch | 122 - ...t-i386_canonicalize_syscall-rewrite-.patch | 192 + gdb-tdep-fix-arm-thumb2-hw-breakpoint.patch | 264 + ...catching-syscall-execve-exit-for-arm.patch | 130 - ....base-watch-bitfields.exp-on-aarch64.patch | 349 - ....base-watchpoint-running-on-arm-ppc6.patch | 76 - ....base-watchpoint-unaligned.exp-on-aa.patch | 262 - ....cp-non-trivial-retval.exp-on-riscv6.patch | 191 + ...array-elements-in-ppc64_aggregate_ca.patch | 86 - gdb-tdep-fix-recording-of-t1-push.patch | 69 + ...everse-execution-of-ldr-immediate-t4.patch | 80 - ...ep-handle-sycall-statx-for-arm-linux.patch | 46 + ...syscall-clock_gettime64-for-arm-linu.patch | 80 + gdb-test-bt-cfi-without-die.patch | 214 - gdb-test-dw2-aranges.patch | 220 - ...te-add-gdb.arch-s390-disassemble.exp.patch | 4 +- ...d-gdb.dwarf2-backward-spec-inter-cu..patch | 128 - ...d-gdb.dwarf2-forward-spec-inter-cu.e.patch | 128 - ...d-missing-include-in-gdb.base-ctf-pt.patch | 51 - ...d-missing-include-in-gdb.base-rtld-s.patch | 47 - ...d-missing-includes-in-gdb.trace-coll.patch | 60 - ...d-missing-no-prompt-anchor-in-gdb.ba.patch | 45 - ...d-pr-gdb-26967-kfail-in-two-more-tes.patch | 167 - ...ll-ldd-version-in-gdb.testsuite-dump.patch | 39 - ...eck-gnatmake-version-in-gdb.ada-scal.patch | 48 + ...ite-don-t-use-set-auto-solib-add-off.patch | 274 + ...estsuite-factor-out-proc-get_portnum.patch | 98 - gdb-testsuite-factor-out-proc-lock_dir.patch | 63 - gdb-testsuite-factor-out-proc-with_lock.patch | 160 - ...x-another-regexp-in-gdb.threads-step.patch | 40 + ...x-gdb.ada-big_packed_array.exp-on-s3.patch | 62 + ...x-gdb.ada-convvar_comp.exp-on-s390x-.patch | 113 + ...x-gdb.ada-mi_task_arg.exp-on-arm-lin.patch | 70 + ...x-gdb.ada-verylong.exp-on-32-bit-tar.patch | 84 - ...x-gdb.arch-arm-pseudo-unwind.exp-wit.patch | 88 + ...x-gdb.arch-arm-single-step-kernel-he.patch | 79 + ...te-fix-gdb.arch-riscv-tdesc-regs.exp.patch | 84 + ...x-gdb.base-branch-to-self.exp-on-arm.patch | 96 + ...testsuite-fix-gdb.base-eh_return.exp.patch | 80 - ...fix-gdb.base-empty-host-env-vars.exp.patch | 132 + ...x-gdb.base-ending-run.exp-on-manjaro.patch | 58 - ...x-gdb.base-list-dot-nodebug-and-make.patch | 83 + ...x-gdb.base-list-dot-nodebug.exp-on-o.patch | 60 + ...x-gdb.base-list-no-debug.exp-on-debi.patch | 103 - ...tep-over-syscall.exp-with-glibc-2-41.patch | 119 + ...p-over-syscall.exp-with-m32-amd-case.patch | 71 - ...ep-over-syscall.exp-with-m32-for-amd.patch | 61 + ...suite-fix-gdb.cp-m-static.exp-on-arm.patch | 88 + ...-fix-gdb.cp-namespace.exp-with-read1.patch | 57 - ...x-gdb.cp-non-trivial-retval.exp-on-a.patch | 99 + ...x-gdb.dwarf2-dw2-fixed-point.exp-on-.patch | 54 + ...ix-gdb.dwarf2-dw2-gas-workaround.exp.patch | 41 - ...x-gdb.dwarf2-dw2-lines.exp-on-arm-li.patch | 279 + ...fix-gdb.mi-mi-dprintf.exp-with-read1.patch | 72 - ...x-gdb.python-py-format-address.exp-o.patch | 88 + ...x-gdb.python-py-format-string.exp-wi.patch | 65 + ...x-gdb.python-py-mi-cmd.exp-with-pyth.patch | 154 + ...x-gdb.rust-completion.exp-timeout-on.patch | 70 + ...x-gdb.server-server-connect.exp-for-.patch | 74 - ...x-gdb.threads-access-mem-running-thr.patch | 119 + ...x-gdb.threads-leader-exit-attach.exp.patch | 80 + ...x-gdb_py_module_available-for-python.patch | 39 + ...x-gdbserver-pid-in-gdb.server-server.patch | 117 - ...x-license-text-in-gdb.reverse-map-to.patch | 49 - ...x-missing-return-type-in-gdb.linespe.patch | 40 - ...x-regexp-in-gdb.ada-mi_var_access.ex.patch | 50 + ...x-regexp-in-gdb.arch-i386-disp-step-.patch | 71 + ...x-regexp-in-gdb.threads-stepi-over-c.patch | 42 + gdb-testsuite-fix-regexp-in-vgdb_start.patch | 66 - ...x-spurious-fails-with-examine-backwa.patch | 221 - ...x-test-case-gdb.threads-attach-stopp.patch | 65 - ...x-test-in-gdb.python-py-finish-break.patch | 67 - ...x-timeout-in-gdb.mi-mi-multi-command.patch | 69 + ...x-timeouts-in-gdb.threads-step-over-.patch | 103 + ...x-typo-in-gdb.base-catch-syscall.exp.patch | 52 - ...stsuite-fix-valgrind-tests-on-debian.patch | 54 - ...rther-handle-long-filenames-in-gdb.b.patch | 49 - ...ndle-core-without-build-id-in-gdb.ba.patch | 66 - gdb-testsuite-handle-pac-marker.patch | 213 - ...ndle-unordered-dict-in-gdb.python-py.patch | 65 + ...ke-gdb.base-solib-search.exp-more-ro.patch | 93 - ...ite-make-portnum-a-persistent-global.patch | 68 - ...-move-gpu-parallel.lock-to-cache-dir.patch | 42 - ...cord-less-in-gdb.reverse-time-revers.patch | 92 + ...stsuite-remove-spurious-in-save_vars.patch | 53 - ...quire-can_spawn_for_attach-in-gdb.ba.patch | 40 + ...quire-supports_process_record-in-gdb.patch | 36 + ...set-errcnt-and-warncnt-in-default_gd.patch | 68 - ...mplify-gdb.server-server-kill-python.patch | 65 - ...testsuite-use-c-flag-in-c-test-cases.patch | 454 ++ ...e-find_gnatmake-instead-of-gdb_find_.patch | 139 - gdb-testsuite-use-more-progbits-for-arm.patch | 858 --- ...e-nostdlib-in-gdb.base-list-dot-node.patch | 172 + ...allel-testing-check-slash-slash-case.patch | 95 - ...e-unique-portnum-in-parallel-testing.patch | 102 - ...allow-command-window-of-1-or-2-lines.patch | 80 - ...resizing-of-terminal-to-1-or-2-lines.patch | 147 - ...be-uninitialized-in-tui_find_disasse.patch | 57 - gdb.changes | 748 +- gdb.spec | 504 +- ...lass-annotation-for-s390x-in-some-te.patch | 125 + import-fedora.sh | 9 +- ...uage-print_type-handle-varstring-nul.patch | 43 - ...gnu23-compatibility-wrt-static_asser.patch | 8 +- ...aarch64-fix-reverse-stepping-failure.patch | 478 -- ...pc-fix-test-gdb.ada-finish-large.exp.patch | 49 - qa-local.sh | 8 +- qa.sh | 57 +- rs6000-unwind-on-each-instruction-fix.patch | 97 - ...-concurrent-functions-facility-insns.patch | 10 +- s390-add-arch15-instruction-names.patch | 8 +- s390-add-arch15-instructions.patch | 14 +- s390-add-missing-extended-mnemonics.patch | 265 - ...to-conditional-branch-instruction-de.patch | 159 - ...test-cases-for-base-index-register-0.patch | 54 - ...ter-case-of-instruction-descriptions.patch | 103 - s390-align-opcodes-to-lower-case.patch | 10 +- ...optional-operand-definition-to-specs.patch | 111 - s390-correct-prno-instruction-name.patch | 36 - ...enhance-error-handling-in-s390-mkopc.patch | 147 - ...mbly-of-optional-addressing-operands.patch | 8 +- ...ional-branch-relative-insns-as-condj.patch | 46 - ...d-table-indices-relative-to-each-oth.patch | 351 - ...print-instruction-description-in-dis.patch | 302 - ...-base-register-0-as-0-in-disassembly.patch | 85 - ...-z16-arch14-instruction-descriptions.patch | 103 - ...-n-z-risb-h-l-gz-rns-ros-rxs-bgt-ope.patch | 8 +- ...s-assembly-of-insn-operands-with-con.patch | 12 +- ...or-jump-visualization-in-disassembly.patch | 367 - ...ssing-operand-sequence-as-one-in-dis.patch | 8 +- ...string-lengths-when-parsing-opcode-t.patch | 45 - ...ring-functions-and-length-macros-in-.patch | 161 - ...egister-name-type-does-not-match-ope.patch | 195 - ...fixes-in-conditional-branch-flavor-d.patch | 45 - use-setvariable-in-gdb.dap-scopes.exp.patch | 64 + 242 files changed, 19351 insertions(+), 21883 deletions(-) create mode 100644 add-dwarf_expr_piece.op.patch create mode 100644 add-gdbarch_dwarf2_reg_piece_offset-hook.patch delete mode 100644 add-note-to-translators-not-to-translate-z-architect.patch delete mode 100644 change-gdb.base-examine-backwards.exp-for-aix.patch delete mode 100644 fix-building-for-the-s390-target-with-clang.patch create mode 100644 fix-gdb.ada-o2_float_param.exp-on-s390x-linux.patch create mode 100644 fix-gdb.base-finish-pretty.exp-on-s390x.patch create mode 100644 fix-gdb.base-readnever.exp-on-s390x.patch create mode 100644 fix-gdb.base-store.exp-on-s390x.patch create mode 100644 fix-gdb.dap-step-out.exp-on-s390x.patch create mode 100644 fix-gdb.dwarf2-shortpiece.exp-on-s390x.patch delete mode 100644 fix-regression-on-aarch64-linux-gdbserver.patch delete mode 100644 fix-the-gdb.ada-inline-section-gc.exp-test.patch delete mode 100644 fixup-gdb-6.3-attach-see-vdso-test.patch delete mode 100644 fixup-gdb-6.3-gstack-20050411.patch delete mode 100644 fixup-gdb-6.5-bz243845-stale-testing-zombie-test.patch create mode 100644 fixup-gdb-6.5-gcore-buffer-limit-test.patch create mode 100644 fixup-gdb-add-rpm-suggestion-script.patch delete mode 100644 fixup-gdb-bz634108-solib_address.patch delete mode 100644 fixup-gdb-glibc-strstr-workaround.patch delete mode 100644 fixup-gdb-linux_perf-bundle.patch delete mode 100644 fixup-gdb-rhbz1261564-aarch64-hw-watchpoint-test.pat.patch delete mode 100644 fixup-gdb-test-bt-cfi-without-die.patch delete mode 100644 fixup-gdb-test-dw2-aranges.patch delete mode 100644 fixup-powerpc-and-aarch64-fix-reverse-stepping-failu.patch delete mode 100644 fixup-skip-tests.patch delete mode 100644 gdb-14.2.tar.bz2 create mode 100644 gdb-15.2.tar.bz2 delete mode 100644 gdb-6.3-attach-see-vdso-test.patch delete mode 100644 gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch delete mode 100644 gdb-6.5-bz243845-stale-testing-zombie-test.patch delete mode 100644 gdb-6.5-section-num-fixup-test.patch delete mode 100644 gdb-6.6-buildid-locate-rpm-librpm-workaround.patch delete mode 100644 gdb-6.6-buildid-locate-rpm-suse.patch delete mode 100644 gdb-6.6-buildid-locate-rpm.patch create mode 100644 gdb-6.6-buildid-locate-tests-suse.patch rename gdb-6.6-buildid-locate-solib-missing-ids.patch => gdb-6.6-buildid-locate-tests.patch (67%) delete mode 100644 gdb-6.6-buildid-locate.patch delete mode 100644 gdb-6.6-bz229517-gcore-without-terminal.patch delete mode 100644 gdb-6.6-testsuite-timeouts.patch create mode 100644 gdb-add-deprecated-settings-py-script.patch create mode 100644 gdb-add-rpm-suggestion-script-suse.patch create mode 100644 gdb-add-rpm-suggestion-script.patch delete mode 100644 gdb-arm-fix-epilogue-frame-id.patch delete mode 100644 gdb-arm-remove-thumb-bit-in-arm_adjust_breakpoint_ad.patch delete mode 100644 gdb-arm-remove-tpidruro-register-from-non-freebsd-ta.patch create mode 100644 gdb-backport-buildid-related-changes.patch delete mode 100644 gdb-build-fix-gdbserver-linux-aarch64-low.cc-build.patch create mode 100644 gdb-build-fix-unused-var-in-corelow.c.patch delete mode 100644 gdb-bz634108-solib_address.patch create mode 100644 gdb-catchpoint-re-set.patch create mode 100644 gdb-cli-print-at_hwcap3-and-at_hwcap4.patch delete mode 100644 gdb-core-open-vdso-warning.patch create mode 100644 gdb-doc-fix-gdb.unwinder-docs.patch create mode 100644 gdb-doc-fix-qisaddresstagged-anchor.patch create mode 100644 gdb-doc-fix-standard-replies-xref.patch delete mode 100644 gdb-exp-fix-cast-handling-for-indirection.patch create mode 100644 gdb-exp-fix-gdb.fortran-intrinsics.exp-fail-on-arm.patch delete mode 100644 gdb-exp-fix-printing-of-out-of-bounds-struct-members.patch delete mode 100644 gdb-exp-redo-cast-handling-for-indirection.patch delete mode 100644 gdb-fedora-libncursesw.patch delete mode 100644 gdb-fix-heap-use-after-free-in-select_event_lwp.patch delete mode 100644 gdb-fix-segfault-in-for_each_block-part-1.patch delete mode 100644 gdb-fix-segfault-in-for_each_block-part-2.patch delete mode 100644 gdb-ftbs-swapped-calloc-args.patch delete mode 100644 gdb-glibc-strstr-workaround.patch create mode 100644 gdb-guile-use-scm_debug_typing_strictness-0.patch delete mode 100644 gdb-linux_perf-bundle.patch create mode 100644 gdb-prune-inferior-after-switching-inferior.patch delete mode 100644 gdb-python-fix-gdb.python-py-disasm.exp-on-arm-linux.patch delete mode 100644 gdb-python-make-gdb.unwindinfo.add_saved_register-mo-fixup.patch delete mode 100644 gdb-python-make-gdb.unwindinfo.add_saved_register-mo.patch create mode 100644 gdb-record-fix-out-of-bounds-write-in-aarch64_record.patch delete mode 100644 gdb-remote-fix-abort-on-remote_close_error.patch create mode 100644 gdb-remove-qnx-neutrino-support.patch delete mode 100644 gdb-rhbz-2232086-cpp-ify-mapped-symtab.patch delete mode 100644 gdb-rhbz-2232086-generate-dwarf-5-index-consistently.patch delete mode 100644 gdb-rhbz-2232086-generate-gdb-index-consistently.patch delete mode 100644 gdb-rhbz-2232086-reduce-size-of-gdb-index.patch delete mode 100644 gdb-rhbz1007614-memleak-infpy_read_memory-test.patch delete mode 100644 gdb-rhbz1261564-aarch64-hw-watchpoint-test.patch delete mode 100644 gdb-rhbz2232086-refactor-selftest-support.patch delete mode 100644 gdb-rhbz2250652-avoid-PyOS_ReadlineTState.patch delete mode 100644 gdb-rhbz2250652-gdbpy_gil.patch delete mode 100644 gdb-rhbz2261580-intrusive_list-assertion-fix.patch delete mode 100644 gdb-rhbz947564-findvar-assertion-frame-failed-testcase.patch delete mode 100644 gdb-s390-add-arch14-record-replay-support.patch delete mode 100644 gdb-simultaneous-step-resume-breakpoint-test.patch delete mode 100644 gdb-symtab-add-producer_is_gas.patch delete mode 100644 gdb-symtab-don-t-defer-backward-refs-inter-cu-intra-.patch delete mode 100644 gdb-symtab-factor-out-m_deferred_entries-usage.patch delete mode 100644 gdb-symtab-factor-out-m_die_range_map-usage.patch delete mode 100644 gdb-symtab-fix-dw_tag_inlined_subroutine-entries-in-.patch create mode 100644 gdb-symtab-fix-target-type-of-complex-long-double-on.patch delete mode 100644 gdb-symtab-handle-nullptr-parent-in-parent_map-set_p.patch delete mode 100644 gdb-symtab-keep-track-of-all-parents-for-cooked-inde.patch delete mode 100644 gdb-symtab-keep-track-of-processed-dies-in-shard.patch delete mode 100644 gdb-symtab-refactor-condition-in-scan_attributes.patch delete mode 100644 gdb-symtab-resolve-deferred-entries-inter-shard-case.patch delete mode 100644 gdb-symtab-resolve-deferred-entries-intra-shard-case.patch delete mode 100644 gdb-symtab-work-around-gas-pr28629.patch delete mode 100644 gdb-symtab-work-around-pr-gas-29517-dwarf2-case.patch delete mode 100644 gdb-symtab-work-around-pr-gas-29517.patch delete mode 100644 gdb-symtab-workaround-pr-gas-31115.patch create mode 100644 gdb-tdep-backport-i386_canonicalize_syscall-rewrite-.patch create mode 100644 gdb-tdep-fix-arm-thumb2-hw-breakpoint.patch delete mode 100644 gdb-tdep-fix-catching-syscall-execve-exit-for-arm.patch delete mode 100644 gdb-tdep-fix-gdb.base-watch-bitfields.exp-on-aarch64.patch delete mode 100644 gdb-tdep-fix-gdb.base-watchpoint-running-on-arm-ppc6.patch delete mode 100644 gdb-tdep-fix-gdb.base-watchpoint-unaligned.exp-on-aa.patch create mode 100644 gdb-tdep-fix-gdb.cp-non-trivial-retval.exp-on-riscv6.patch delete mode 100644 gdb-tdep-fix-nr-array-elements-in-ppc64_aggregate_ca.patch create mode 100644 gdb-tdep-fix-recording-of-t1-push.patch delete mode 100644 gdb-tdep-fix-reverse-execution-of-ldr-immediate-t4.patch create mode 100644 gdb-tdep-handle-sycall-statx-for-arm-linux.patch create mode 100644 gdb-tdep-handle-syscall-clock_gettime64-for-arm-linu.patch delete mode 100644 gdb-test-bt-cfi-without-die.patch delete mode 100644 gdb-test-dw2-aranges.patch delete mode 100644 gdb-testsuite-add-gdb.dwarf2-backward-spec-inter-cu..patch delete mode 100644 gdb-testsuite-add-gdb.dwarf2-forward-spec-inter-cu.e.patch delete mode 100644 gdb-testsuite-add-missing-include-in-gdb.base-ctf-pt.patch delete mode 100644 gdb-testsuite-add-missing-include-in-gdb.base-rtld-s.patch delete mode 100644 gdb-testsuite-add-missing-includes-in-gdb.trace-coll.patch delete mode 100644 gdb-testsuite-add-missing-no-prompt-anchor-in-gdb.ba.patch delete mode 100644 gdb-testsuite-add-pr-gdb-26967-kfail-in-two-more-tes.patch delete mode 100644 gdb-testsuite-call-ldd-version-in-gdb.testsuite-dump.patch create mode 100644 gdb-testsuite-check-gnatmake-version-in-gdb.ada-scal.patch create mode 100644 gdb-testsuite-don-t-use-set-auto-solib-add-off.patch delete mode 100644 gdb-testsuite-factor-out-proc-get_portnum.patch delete mode 100644 gdb-testsuite-factor-out-proc-lock_dir.patch delete mode 100644 gdb-testsuite-factor-out-proc-with_lock.patch create mode 100644 gdb-testsuite-fix-another-regexp-in-gdb.threads-step.patch create mode 100644 gdb-testsuite-fix-gdb.ada-big_packed_array.exp-on-s3.patch create mode 100644 gdb-testsuite-fix-gdb.ada-convvar_comp.exp-on-s390x-.patch create mode 100644 gdb-testsuite-fix-gdb.ada-mi_task_arg.exp-on-arm-lin.patch delete mode 100644 gdb-testsuite-fix-gdb.ada-verylong.exp-on-32-bit-tar.patch create mode 100644 gdb-testsuite-fix-gdb.arch-arm-pseudo-unwind.exp-wit.patch create mode 100644 gdb-testsuite-fix-gdb.arch-arm-single-step-kernel-he.patch create mode 100644 gdb-testsuite-fix-gdb.arch-riscv-tdesc-regs.exp.patch create mode 100644 gdb-testsuite-fix-gdb.base-branch-to-self.exp-on-arm.patch delete mode 100644 gdb-testsuite-fix-gdb.base-eh_return.exp.patch create mode 100644 gdb-testsuite-fix-gdb.base-empty-host-env-vars.exp.patch delete mode 100644 gdb-testsuite-fix-gdb.base-ending-run.exp-on-manjaro.patch create mode 100644 gdb-testsuite-fix-gdb.base-list-dot-nodebug-and-make.patch create mode 100644 gdb-testsuite-fix-gdb.base-list-dot-nodebug.exp-on-o.patch delete mode 100644 gdb-testsuite-fix-gdb.base-list-no-debug.exp-on-debi.patch create mode 100644 gdb-testsuite-fix-gdb.base-step-over-syscall.exp-with-glibc-2-41.patch delete mode 100644 gdb-testsuite-fix-gdb.base-step-over-syscall.exp-with-m32-amd-case.patch create mode 100644 gdb-testsuite-fix-gdb.base-step-over-syscall.exp-with-m32-for-amd.patch create mode 100644 gdb-testsuite-fix-gdb.cp-m-static.exp-on-arm.patch delete mode 100644 gdb-testsuite-fix-gdb.cp-namespace.exp-with-read1.patch create mode 100644 gdb-testsuite-fix-gdb.cp-non-trivial-retval.exp-on-a.patch create mode 100644 gdb-testsuite-fix-gdb.dwarf2-dw2-fixed-point.exp-on-.patch delete mode 100644 gdb-testsuite-fix-gdb.dwarf2-dw2-gas-workaround.exp.patch create mode 100644 gdb-testsuite-fix-gdb.dwarf2-dw2-lines.exp-on-arm-li.patch delete mode 100644 gdb-testsuite-fix-gdb.mi-mi-dprintf.exp-with-read1.patch create mode 100644 gdb-testsuite-fix-gdb.python-py-format-address.exp-o.patch create mode 100644 gdb-testsuite-fix-gdb.python-py-format-string.exp-wi.patch create mode 100644 gdb-testsuite-fix-gdb.python-py-mi-cmd.exp-with-pyth.patch create mode 100644 gdb-testsuite-fix-gdb.rust-completion.exp-timeout-on.patch delete mode 100644 gdb-testsuite-fix-gdb.server-server-connect.exp-for-.patch create mode 100644 gdb-testsuite-fix-gdb.threads-access-mem-running-thr.patch create mode 100644 gdb-testsuite-fix-gdb.threads-leader-exit-attach.exp.patch create mode 100644 gdb-testsuite-fix-gdb_py_module_available-for-python.patch delete mode 100644 gdb-testsuite-fix-gdbserver-pid-in-gdb.server-server.patch delete mode 100644 gdb-testsuite-fix-license-text-in-gdb.reverse-map-to.patch delete mode 100644 gdb-testsuite-fix-missing-return-type-in-gdb.linespe.patch create mode 100644 gdb-testsuite-fix-regexp-in-gdb.ada-mi_var_access.ex.patch create mode 100644 gdb-testsuite-fix-regexp-in-gdb.arch-i386-disp-step-.patch create mode 100644 gdb-testsuite-fix-regexp-in-gdb.threads-stepi-over-c.patch delete mode 100644 gdb-testsuite-fix-regexp-in-vgdb_start.patch delete mode 100644 gdb-testsuite-fix-spurious-fails-with-examine-backwa.patch delete mode 100644 gdb-testsuite-fix-test-case-gdb.threads-attach-stopp.patch delete mode 100644 gdb-testsuite-fix-test-in-gdb.python-py-finish-break.patch create mode 100644 gdb-testsuite-fix-timeout-in-gdb.mi-mi-multi-command.patch create mode 100644 gdb-testsuite-fix-timeouts-in-gdb.threads-step-over-.patch delete mode 100644 gdb-testsuite-fix-typo-in-gdb.base-catch-syscall.exp.patch delete mode 100644 gdb-testsuite-fix-valgrind-tests-on-debian.patch delete mode 100644 gdb-testsuite-further-handle-long-filenames-in-gdb.b.patch delete mode 100644 gdb-testsuite-handle-core-without-build-id-in-gdb.ba.patch delete mode 100644 gdb-testsuite-handle-pac-marker.patch create mode 100644 gdb-testsuite-handle-unordered-dict-in-gdb.python-py.patch delete mode 100644 gdb-testsuite-make-gdb.base-solib-search.exp-more-ro.patch delete mode 100644 gdb-testsuite-make-portnum-a-persistent-global.patch delete mode 100644 gdb-testsuite-move-gpu-parallel.lock-to-cache-dir.patch create mode 100644 gdb-testsuite-record-less-in-gdb.reverse-time-revers.patch delete mode 100644 gdb-testsuite-remove-spurious-in-save_vars.patch create mode 100644 gdb-testsuite-require-can_spawn_for_attach-in-gdb.ba.patch create mode 100644 gdb-testsuite-require-supports_process_record-in-gdb.patch delete mode 100644 gdb-testsuite-reset-errcnt-and-warncnt-in-default_gd.patch delete mode 100644 gdb-testsuite-simplify-gdb.server-server-kill-python.patch create mode 100644 gdb-testsuite-use-c-flag-in-c-test-cases.patch delete mode 100644 gdb-testsuite-use-find_gnatmake-instead-of-gdb_find_.patch delete mode 100644 gdb-testsuite-use-more-progbits-for-arm.patch create mode 100644 gdb-testsuite-use-nostdlib-in-gdb.base-list-dot-node.patch delete mode 100644 gdb-testsuite-use-unique-portnum-in-parallel-testing-check-slash-slash-case.patch delete mode 100644 gdb-testsuite-use-unique-portnum-in-parallel-testing.patch delete mode 100644 gdb-tui-allow-command-window-of-1-or-2-lines.patch delete mode 100644 gdb-tui-fix-resizing-of-terminal-to-1-or-2-lines.patch delete mode 100644 gdb-tui-fix-wmaybe-uninitialized-in-tui_find_disasse.patch create mode 100644 handle-address-class-annotation-for-s390x-in-some-te.patch delete mode 100644 make-pascal_language-print_type-handle-varstring-nul.patch delete mode 100644 powerpc-and-aarch64-fix-reverse-stepping-failure.patch delete mode 100644 powerpc-fix-test-gdb.ada-finish-large.exp.patch delete mode 100644 rs6000-unwind-on-each-instruction-fix.patch delete mode 100644 s390-add-missing-extended-mnemonics.patch delete mode 100644 s390-add-suffix-to-conditional-branch-instruction-de.patch delete mode 100644 s390-add-test-cases-for-base-index-register-0.patch delete mode 100644 s390-align-letter-case-of-instruction-descriptions.patch delete mode 100644 s390-align-optional-operand-definition-to-specs.patch delete mode 100644 s390-correct-prno-instruction-name.patch delete mode 100644 s390-enhance-error-handling-in-s390-mkopc.patch delete mode 100644 s390-flag-conditional-branch-relative-insns-as-condj.patch delete mode 100644 s390-make-operand-table-indices-relative-to-each-oth.patch delete mode 100644 s390-optionally-print-instruction-description-in-dis.patch delete mode 100644 s390-print-base-register-0-as-0-in-disassembly.patch delete mode 100644 s390-provide-ibm-z16-arch14-instruction-descriptions.patch delete mode 100644 s390-support-for-jump-visualization-in-disassembly.patch delete mode 100644 s390-use-proper-string-lengths-when-parsing-opcode-t.patch delete mode 100644 s390-use-safe-string-functions-and-length-macros-in-.patch delete mode 100644 s390-warn-when-register-name-type-does-not-match-ope.patch delete mode 100644 s390-whitespace-fixes-in-conditional-branch-flavor-d.patch create mode 100644 use-setvariable-in-gdb.dap-scopes.exp.patch diff --git a/add-dwarf_expr_piece.op.patch b/add-dwarf_expr_piece.op.patch new file mode 100644 index 0000000..1a75e3e --- /dev/null +++ b/add-dwarf_expr_piece.op.patch @@ -0,0 +1,100 @@ +From 89cf6ba4a207f5342db58d9e43178ae516cc220e Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Wed, 15 Jan 2025 17:02:00 +0100 +Subject: [PATCH 23/46] Add dwarf_expr_piece.op + +Add a new field "dwarf_location_atom op" to dwarf_expr_piece to keep track of +which dwarf_location_atom caused a dwarf_expr_piece to be added. + +This is used in the following patch. + +Tested on s390x-linux. + +Approved-By: Tom Tromey +--- + gdb/dwarf2/expr.c | 10 ++++++---- + gdb/dwarf2/expr.h | 6 +++++- + 2 files changed, 11 insertions(+), 5 deletions(-) + +diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c +index cb80dbf60b1..03107f90575 100644 +--- a/gdb/dwarf2/expr.c ++++ b/gdb/dwarf2/expr.c +@@ -1198,13 +1198,15 @@ dwarf_expr_context::stack_empty_p () const + + /* Add a new piece to the dwarf_expr_context's piece list. */ + void +-dwarf_expr_context::add_piece (ULONGEST size, ULONGEST offset) ++dwarf_expr_context::add_piece (ULONGEST size, ULONGEST offset, ++ enum dwarf_location_atom op) + { + dwarf_expr_piece &p = this->m_pieces.emplace_back (); + + p.location = this->m_location; + p.size = size; + p.offset = offset; ++ p.op = op; + + if (p.location == DWARF_VALUE_LITERAL) + { +@@ -2169,7 +2171,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, + + /* Record the piece. */ + op_ptr = safe_read_uleb128 (op_ptr, op_end, &size); +- add_piece (8 * size, 0); ++ add_piece (8 * size, 0, op); + + /* Pop off the address/regnum, and reset the location + type. */ +@@ -2187,7 +2189,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, + /* Record the piece. */ + op_ptr = safe_read_uleb128 (op_ptr, op_end, &size); + op_ptr = safe_read_uleb128 (op_ptr, op_end, &uleb_offset); +- add_piece (size, uleb_offset); ++ add_piece (size, uleb_offset, op); + + /* Pop off the address/regnum, and reset the location + type. */ +@@ -2389,7 +2391,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, + pointer, then make a pieced value. This is ok because we can't + have implicit pointers in contexts where pieces are invalid. */ + if (this->m_location == DWARF_VALUE_IMPLICIT_POINTER) +- add_piece (8 * this->m_addr_size, 0); ++ add_piece (8 * this->m_addr_size, 0, DW_OP_implicit_pointer); + + this->m_recursion_depth--; + gdb_assert (this->m_recursion_depth >= 0); +diff --git a/gdb/dwarf2/expr.h b/gdb/dwarf2/expr.h +index b02cc531640..957c58f30c4 100644 +--- a/gdb/dwarf2/expr.h ++++ b/gdb/dwarf2/expr.h +@@ -24,6 +24,7 @@ + + #include "leb128.h" + #include "dwarf2/call-site.h" ++#include "dwarf2.h" + + struct dwarf2_per_objfile; + +@@ -54,6 +55,9 @@ enum dwarf_value_location + /* A piece of an object, as recorded by DW_OP_piece or DW_OP_bit_piece. */ + struct dwarf_expr_piece + { ++ /* The DWARF operation for which the piece was created. */ ++ enum dwarf_location_atom op; ++ + enum dwarf_value_location location; + + union +@@ -208,7 +212,7 @@ struct dwarf_expr_context + struct type *address_type () const; + void push (struct value *value, bool in_stack_memory); + bool stack_empty_p () const; +- void add_piece (ULONGEST size, ULONGEST offset); ++ void add_piece (ULONGEST size, ULONGEST offset, enum dwarf_location_atom op); + void execute_stack_op (const gdb_byte *op_ptr, const gdb_byte *op_end); + void pop (); + struct value *fetch (int n); +-- +2.43.0 + diff --git a/add-gdbarch_dwarf2_reg_piece_offset-hook.patch b/add-gdbarch_dwarf2_reg_piece_offset-hook.patch new file mode 100644 index 0000000..447bc38 --- /dev/null +++ b/add-gdbarch_dwarf2_reg_piece_offset-hook.patch @@ -0,0 +1,220 @@ +From 29b185c531fcd933da62142debcb088321be7c4c Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Wed, 15 Jan 2025 17:02:00 +0100 +Subject: [PATCH 24/46] Add gdbarch_dwarf2_reg_piece_offset hook + +In rw_pieced_value, when reading/writing part of a register, DW_OP_piece and +DW_OP_bit_piece are handled the same, but the standard tells us: +- DW_OP_piece: if the piece is located in a register, but does not occupy the + entire register, the placement of the piece within that register is defined + by the ABI. +- DW_OP_bit_piece: if the location is a register, the offset is from the least + significant bit end of the register. + +Add a new hook gdbarch_dwarf2_reg_piece_offset that allows us to define the +ABI-specific behaviour for DW_OP_piece. + +The default implementation of the hook is the behaviour of DW_OP_bit_piece, so +there should not be any functional changes. + +Tested on s390x-linux. + +Approved-By: Tom Tromey +--- + gdb/dwarf2/expr.c | 31 +++++++++++++++++++++++++------ + gdb/findvar.c | 18 ++++++++++++++++++ + gdb/gdbarch-gen.h | 8 ++++++++ + gdb/gdbarch.c | 22 ++++++++++++++++++++++ + gdb/gdbarch_components.py | 16 ++++++++++++++++ + gdb/value.h | 2 ++ + 6 files changed, 91 insertions(+), 6 deletions(-) + +diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c +index 03107f90575..ece713ee7cd 100644 +--- a/gdb/dwarf2/expr.c ++++ b/gdb/dwarf2/expr.c +@@ -211,14 +211,33 @@ rw_pieced_value (value *v, value *from, bool check_optimized) + ULONGEST reg_bits = 8 * register_size (arch, gdb_regnum); + int optim, unavail; + +- if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG +- && p->offset + p->size < reg_bits) ++ if (p->offset + p->size < reg_bits) + { +- /* Big-endian, and we want less than full size. */ +- bits_to_skip += reg_bits - (p->offset + p->size); ++ /* We want less than full size. */ ++ ++ if (p->op == DW_OP_piece) ++ { ++ gdb_assert (p->offset == 0); ++ ++ /* If the piece is located in a register, but does not ++ occupy the entire register, the placement of the piece ++ within that register is defined by the ABI. */ ++ bits_to_skip ++ += 8 * gdbarch_dwarf2_reg_piece_offset (arch, gdb_regnum, ++ p->size / 8); ++ } ++ else if (p->op == DW_OP_bit_piece) ++ { ++ /* If the location is a register, the offset is from the ++ least significant bit end of the register. */ ++ if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG) ++ bits_to_skip += reg_bits - (p->offset + p->size); ++ else ++ bits_to_skip += p->offset; ++ } ++ else ++ error (_("Don't know how to get part of implicit pointer")); + } +- else +- bits_to_skip += p->offset; + + this_size = bits_to_bytes (bits_to_skip, this_size_bits); + buffer.resize (this_size); +diff --git a/gdb/findvar.c b/gdb/findvar.c +index df4ab1a28b9..3b20974474a 100644 +--- a/gdb/findvar.c ++++ b/gdb/findvar.c +@@ -541,6 +541,24 @@ default_value_from_register (gdbarch *gdbarch, type *type, int regnum, + return value; + } + ++/* Default implementation of gdbarch_dwarf2_reg_piece_offset. Implements ++ DW_OP_bits_piece for DW_OP_piece. */ ++ ++ULONGEST ++default_dwarf2_reg_piece_offset (gdbarch *gdbarch, int gdb_regnum, ULONGEST size) ++{ ++ ULONGEST reg_size = register_size (gdbarch, gdb_regnum); ++ gdb_assert (size <= reg_size); ++ if (reg_size == size) ++ return 0; ++ ++ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) ++ return reg_size - size; ++ ++ return 0; ++} ++ ++ + /* VALUE must be an lval_register value. If regnum is the value's + associated register number, and len the length of the value's type, + read one or more registers in VALUE's frame, starting with register REGNUM, +diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h +index b982fd7cd09..2e20a9dbccd 100644 +--- a/gdb/gdbarch-gen.h ++++ b/gdb/gdbarch-gen.h +@@ -430,6 +430,14 @@ typedef struct value * (gdbarch_value_from_register_ftype) (struct gdbarch *gdba + extern struct value * gdbarch_value_from_register (struct gdbarch *gdbarch, struct type *type, int regnum, const frame_info_ptr &this_frame); + extern void set_gdbarch_value_from_register (struct gdbarch *gdbarch, gdbarch_value_from_register_ftype *value_from_register); + ++/* For a DW_OP_piece located in a register, but not occupying the ++ entire register, return the placement of the piece within that ++ register as defined by the ABI. */ ++ ++typedef ULONGEST (gdbarch_dwarf2_reg_piece_offset_ftype) (struct gdbarch *gdbarch, int regnum, ULONGEST size); ++extern ULONGEST gdbarch_dwarf2_reg_piece_offset (struct gdbarch *gdbarch, int regnum, ULONGEST size); ++extern void set_gdbarch_dwarf2_reg_piece_offset (struct gdbarch *gdbarch, gdbarch_dwarf2_reg_piece_offset_ftype *dwarf2_reg_piece_offset); ++ + typedef CORE_ADDR (gdbarch_pointer_to_address_ftype) (struct gdbarch *gdbarch, struct type *type, const gdb_byte *buf); + extern CORE_ADDR gdbarch_pointer_to_address (struct gdbarch *gdbarch, struct type *type, const gdb_byte *buf); + extern void set_gdbarch_pointer_to_address (struct gdbarch *gdbarch, gdbarch_pointer_to_address_ftype *pointer_to_address); +diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c +index 58e9ebbdc59..ed5b5859277 100644 +--- a/gdb/gdbarch.c ++++ b/gdb/gdbarch.c +@@ -109,6 +109,7 @@ struct gdbarch + gdbarch_register_to_value_ftype *register_to_value = nullptr; + gdbarch_value_to_register_ftype *value_to_register = nullptr; + gdbarch_value_from_register_ftype *value_from_register = default_value_from_register; ++ gdbarch_dwarf2_reg_piece_offset_ftype *dwarf2_reg_piece_offset = default_dwarf2_reg_piece_offset; + gdbarch_pointer_to_address_ftype *pointer_to_address = unsigned_pointer_to_address; + gdbarch_address_to_pointer_ftype *address_to_pointer = unsigned_address_to_pointer; + gdbarch_integer_to_address_ftype *integer_to_address = nullptr; +@@ -371,6 +372,7 @@ verify_gdbarch (struct gdbarch *gdbarch) + /* Skip verify of value_from_register, invalid_p == 0 */ + /* Skip verify of pointer_to_address, invalid_p == 0 */ + /* Skip verify of address_to_pointer, invalid_p == 0 */ ++ /* Skip verify of dwarf2_reg_piece_offset, invalid_p == 0. */ + /* Skip verify of integer_to_address, has predicate. */ + /* Skip verify of return_value, invalid_p == 0 */ + if ((gdbarch->return_value_as_value == default_gdbarch_return_value) == (gdbarch->return_value == nullptr)) +@@ -783,6 +785,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) + gdb_printf (file, + "gdbarch_dump: value_from_register = <%s>\n", + host_address_to_string (gdbarch->value_from_register)); ++ gdb_printf (file, ++ "gdbarch_dump: dwarf2_reg_piece_offset = <%s>\n", ++ host_address_to_string (gdbarch->dwarf2_reg_piece_offset)); + gdb_printf (file, + "gdbarch_dump: pointer_to_address = <%s>\n", + host_address_to_string (gdbarch->pointer_to_address)); +@@ -2573,6 +2578,23 @@ set_gdbarch_value_from_register (struct gdbarch *gdbarch, + gdbarch->value_from_register = value_from_register; + } + ++ULONGEST ++gdbarch_dwarf2_reg_piece_offset (struct gdbarch *gdbarch, int regnum, ULONGEST size) ++{ ++ gdb_assert (gdbarch != NULL); ++ gdb_assert (gdbarch->dwarf2_reg_piece_offset != NULL); ++ if (gdbarch_debug >= 2) ++ gdb_printf (gdb_stdlog, "gdbarch_dwarf2_reg_piece_offset called\n"); ++ return gdbarch->dwarf2_reg_piece_offset (gdbarch, regnum, size); ++} ++ ++void ++set_gdbarch_dwarf2_reg_piece_offset (struct gdbarch *gdbarch, ++ gdbarch_dwarf2_reg_piece_offset_ftype dwarf2_reg_piece_offset) ++{ ++ gdbarch->dwarf2_reg_piece_offset = dwarf2_reg_piece_offset; ++} ++ + CORE_ADDR + gdbarch_pointer_to_address (struct gdbarch *gdbarch, struct type *type, const gdb_byte *buf) + { +diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py +index 4006380076d..4a228b5d27c 100644 +--- a/gdb/gdbarch_components.py ++++ b/gdb/gdbarch_components.py +@@ -829,6 +829,22 @@ allocate and return a struct value with all value attributes + invalid=False, + ) + ++Method( ++ comment=""" ++For a DW_OP_piece located in a register, but not occupying the ++entire register, return the placement of the piece within that ++register as defined by the ABI. ++""", ++ type="ULONGEST", ++ name="dwarf2_reg_piece_offset", ++ params=[ ++ ("int", "regnum"), ++ ("ULONGEST", "size") ++ ], ++ predefault="default_dwarf2_reg_piece_offset", ++ invalid=False, ++) ++ + Method( + type="CORE_ADDR", + name="pointer_to_address", +diff --git a/gdb/value.h b/gdb/value.h +index 9d7e88d9433..47df66e0961 100644 +--- a/gdb/value.h ++++ b/gdb/value.h +@@ -1128,6 +1128,8 @@ extern value *default_value_from_register (gdbarch *gdbarch, type *type, + int regnum, + const frame_info_ptr &this_frame); + ++extern ULONGEST default_dwarf2_reg_piece_offset (gdbarch *gdbarch, int regnum, ULONGEST size); ++ + extern struct value *value_from_register (struct type *type, int regnum, + const frame_info_ptr &frame); + +-- +2.43.0 + diff --git a/add-note-to-translators-not-to-translate-z-architect.patch b/add-note-to-translators-not-to-translate-z-architect.patch deleted file mode 100644 index e1de341..0000000 --- a/add-note-to-translators-not-to-translate-z-architect.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 28c32a89ab9ed6caa60dd6fb8e13ef0b447aa779 Mon Sep 17 00:00:00 2001 -From: Nick Clifton -Date: Thu, 13 Mar 2025 15:09:49 +0100 -Subject: [PATCH 12/28] Add note to translators not to translate z/Architecture - -(cherry picked from commit 0d656dfe5b4) ---- - opcodes/s390-dis.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/opcodes/s390-dis.c b/opcodes/s390-dis.c -index fca965fbb5d..ebf56c1c7e4 100644 ---- a/opcodes/s390-dis.c -+++ b/opcodes/s390-dis.c -@@ -42,6 +42,7 @@ typedef struct - static const s390_options_t options[] = - { - { "esa" , N_("Disassemble in ESA architecture mode") }, -+ /* TRANSLATORS: Please do not translate 'z/Architecture' as this is a technical name. */ - { "zarch", N_("Disassemble in z/Architecture mode") }, - { "insnlength", N_("Print unknown instructions according to " - "length from first two bits") }, --- -2.43.0 - diff --git a/change-gdb.base-examine-backwards.exp-for-aix.patch b/change-gdb.base-examine-backwards.exp-for-aix.patch deleted file mode 100644 index 56d1ff4..0000000 --- a/change-gdb.base-examine-backwards.exp-for-aix.patch +++ /dev/null @@ -1,53 +0,0 @@ -From acc7b542a08819bec4aae767de547c531a7ab62e Mon Sep 17 00:00:00 2001 -From: Aditya Vidyadhar Kamath -Date: Mon, 6 Nov 2023 07:26:24 -0600 -Subject: [PATCH 03/48] Change gdb.base/examine-backwards.exp for AIX. - -In AIX unused or constant variables are collected as garbage by the linker and in the dwarf dump -an address with all f's in hexadecimal are assigned. Hence the testcase fails with many failures stating -it cannot access memory. - -This patch is a small change to get it working in AIX as well. ---- - gdb/testsuite/gdb.base/examine-backward.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/gdb/testsuite/gdb.base/examine-backward.c b/gdb/testsuite/gdb.base/examine-backward.c -index e30b58fb005..354c2e2f323 100644 ---- a/gdb/testsuite/gdb.base/examine-backward.c -+++ b/gdb/testsuite/gdb.base/examine-backward.c -@@ -36,11 +36,11 @@ literals. The content of each array is the same as followings: - TestStrings, to avoid showing garbage when we look for strings - backwards from TestStrings. */ - --const unsigned char Barrier[] = { -+unsigned char Barrier[] = { - 0x00, - }; - --const unsigned char TestStrings[] = { -+unsigned char TestStrings[] = { - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, - 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, -@@ -54,7 +54,7 @@ const unsigned char TestStrings[] = { - 0x00 - }; - --const short TestStringsH[] = { -+short TestStringsH[] = { - 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, - 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, - 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, -@@ -67,7 +67,7 @@ const short TestStringsH[] = { - 0x0000 - }; - --const int TestStringsW[] = { -+int TestStringsW[] = { - 0x00000041, 0x00000042, 0x00000043, 0x00000044, - 0x00000045, 0x00000046, 0x00000047, 0x00000048, - 0x00000049, 0x0000004a, 0x0000004b, 0x0000004c, --- -2.35.3 - diff --git a/fix-building-for-the-s390-target-with-clang.patch b/fix-building-for-the-s390-target-with-clang.patch deleted file mode 100644 index 736d62f..0000000 --- a/fix-building-for-the-s390-target-with-clang.patch +++ /dev/null @@ -1,30 +0,0 @@ -From e2d364caa1ddd8b046bd671e71c407522224b42c Mon Sep 17 00:00:00 2001 -From: Nick Clifton -Date: Thu, 13 Mar 2025 15:09:46 +0100 -Subject: [PATCH 05/28] Fix building for the s390 target with clang - -(cherry picked from commit 6c0c7d489bd) ---- - opcodes/s390-opc.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/opcodes/s390-opc.c b/opcodes/s390-opc.c -index 0427bd8b2e0..cbfdb3df0b7 100644 ---- a/opcodes/s390-opc.c -+++ b/opcodes/s390-opc.c -@@ -262,9 +262,10 @@ const struct s390_operand s390_operands[] = - - }; - --static inline void unused_s390_operands_static_asserts(void) -+static inline void ATTRIBUTE_UNUSED -+unused_s390_operands_static_asserts (void) - { -- static_assert(ARRAY_SIZE(s390_operands) - 1 == J32_16); -+ static_assert (ARRAY_SIZE (s390_operands) - 1 == J32_16); - } - - /* Macros used to form opcodes. */ --- -2.43.0 - diff --git a/fix-gdb.ada-o2_float_param.exp-on-s390x-linux.patch b/fix-gdb.ada-o2_float_param.exp-on-s390x-linux.patch new file mode 100644 index 0000000..3b09d3e --- /dev/null +++ b/fix-gdb.ada-o2_float_param.exp-on-s390x-linux.patch @@ -0,0 +1,144 @@ +From 0ac8e9af3cd6713f4b230e9e335e1398c3161210 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Fri, 10 Jan 2025 21:25:53 +0100 +Subject: [PATCH 26/46] Fix gdb.ada/O2_float_param.exp on s390x-linux + +With test-case gdb.ada/O2_float_param.exp on s390x-linux, I get: +... + (gdb) frame^M + #0 callee.increment (val=99.0, val@entry=, msg=...) at callee.adb:19^M + 19 procedure Increment (Val : in out Float; Msg: String) is^M + (gdb) FAIL: $exp: scenario=all: frame +... + +The frame command calls read_frame_arg to get: +- the current value of val, and +- the value of val at function entry. + +The first scenario succeeds, and the second scenario fails. + +For context and contrast, let's also investigate the first scenario: getting +the current value of val. + +Function parameter val: +... + <2>: Abbrev Number: 4 (DW_TAG_formal_parameter) + DW_AT_name : val + DW_AT_type : <0xb86> + DW_AT_location : 0xab (location list) +... +has location list: +... + 000000ab 0000000001002928 0000000001002967 + (DW_OP_reg16 (f0)) + 000000be 0000000001002967 0000000001002968 + (DW_OP_reg24 (f8)) + 000000d1 0000000001002968 0000000001002974 + (DW_OP_GNU_regval_type: 24 (f8) <0xb29>; + DW_OP_GNU_const_type: <0xb29> 4 byte block: 3f 80 0 0 ; DW_OP_plus; + DW_OP_stack_value) + 000000ef 0000000001002974 0000000001002982 + (DW_OP_GNU_entry_value: (DW_OP_GNU_regval_type: 16 (f0) <0xb29>); + DW_OP_GNU_const_type: <0xb29> 4 byte block: 3f 80 0 0 ; DW_OP_plus; + DW_OP_stack_value) + 0000010f +... +and since we're stopped at address 0x1002928: +... +(gdb) print $pc +$1 = (access procedure) 0x1002928 +... +we get the value from dwarf register 16. + +The s390x ABI [1] specifies that dwarf register 16 maps onto 8-byte register +f0 or 16-byte register v0 (where f0 is part of v0), and in this case (because +the v0 register is available) s390_dwarf_reg_to_regnum maps it to v0. + +Val is only 4 bytes: +... +(gdb) ptype val +type = <4-byte float> +... +and s390_value_from_register takes care to get the value from the correct part +of v0. + +The value of v0 is found in the prologue cache, and the value of parameter val +is printed. + +Now the second scenario: getting the value of val at function entry. + +FWIW, since we're stopped at function entry, we could simply return the same +value, reading the same register, but that's currently not implemented [2]. + +Instead we start from the fact that val is in dwarf reg 16 at function entry, +and then use call site information: +... + <4>: Abbrev Number: 13 (DW_TAG_GNU_call_site) + DW_AT_low_pc : 0x1002a46 + DW_AT_abstract_origin: <0xdda> + <5>: Abbrev Number: 12 (DW_TAG_GNU_call_site_parameter) + DW_AT_location : 1 byte block: 60 (DW_OP_reg16 (f0)) + DW_AT_GNU_call_site_value: 3 byte block: f5 18 2d \ + (DW_OP_GNU_regval_type: 24 (f8) <0xc42>) + <5>: Abbrev Number: 12 (DW_TAG_GNU_call_site_parameter) +... +to conclude that the value we're looking for is in dwarf reg 24, which +s390_dwarf_reg_to_regnum maps to v8. + +As before, s390_value_from_register takes care to get the value from the +correct part of v8. + +However, v8 is not available in the prologue cache, and we take a different +path and end up in s390_unwind_pseudo_register, where v8 and similar +(regnum_is_vxr_full) is unhandled, and we get: +... + return value::allocate_optimized_out (type); +... +which eventually causes the "error reading variable: register has not been +saved in frame". + +Fix this by handling the regnum_is_vxr_full case in +s390_unwind_pseudo_register, similar to how that is done in +s390_pseudo_register_read. + +Tested on s390x-linux. + +This also fixes test-case gdb.base/savedregs.exp. + +[1] https://github.com/IBM/s390x-abi +[2] https://sourceware.org/pipermail/gdb-patches/2024-September/211589.html +--- + gdb/s390-tdep.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c +index a7c58b37276..31730296ef1 100644 +--- a/gdb/s390-tdep.c ++++ b/gdb/s390-tdep.c +@@ -2332,6 +2332,22 @@ s390_unwind_pseudo_register (const frame_info_ptr &this_frame, int regnum) + return value_cast (type, val); + } + ++ if (regnum_is_vxr_full (tdep, regnum)) ++ { ++ struct value *val = value::allocate_register (this_frame, regnum); ++ ++ int reg = regnum - tdep->v0_full_regnum; ++ struct value *val1 ++ = frame_unwind_register_value (this_frame, S390_F0_REGNUM + reg); ++ struct value *val2 ++ = frame_unwind_register_value (this_frame, S390_V0_LOWER_REGNUM + reg); ++ ++ val1->contents_copy (val, 0, 0, 8); ++ val2->contents_copy (val, 8, 0, 8); ++ ++ return value_cast (type, val); ++ } ++ + return value::allocate_optimized_out (type); + } + +-- +2.43.0 + diff --git a/fix-gdb.base-finish-pretty.exp-on-s390x.patch b/fix-gdb.base-finish-pretty.exp-on-s390x.patch new file mode 100644 index 0000000..c28101c --- /dev/null +++ b/fix-gdb.base-finish-pretty.exp-on-s390x.patch @@ -0,0 +1,188 @@ +From de696a57729423bf643e530fdb638dff6cf3c08b Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Sat, 4 Jan 2025 11:31:02 +0100 +Subject: [PATCH 21/46] Fix gdb.base/finish-pretty.exp on s390x + +On s390x-linux, with test-case gdb.base/finish-pretty.exp I ran into: +... +(gdb) finish +Run till exit from #0 foo () at finish-pretty.c:28 +main () at finish-pretty.c:40 +40 return v.a + v.b; +Value returned has type: struct s. Cannot determine contents +(gdb) FAIL: $exp: finish foo prettyprinted function result +... + +The function being finished is foo, which returns a value of type struct s. + +The ABI [1] specifies: +- that the value is returned in a storage buffer allocated by the caller, and +- that the address of this buffer is passed as a hidden argument in r2. + +GDB fails to print the value when finishing foo, because it doesn't know the +address of the buffer. + +Implement the gdbarch_get_return_buf_addr hook for s390x to fix this. + +This is based on ppc_sysv_get_return_buf_addr, the only other implementation +of gdbarch_get_return_buf_addr. For readability I've factored out +dwarf_reg_on_entry. + +There is one difference with ppc_sysv_get_return_buf_addr: only +NO_ENTRY_VALUE_ERROR is caught. If this patch is approved, I intend to submit +a follow-up patch to fix this in ppc_sysv_get_return_buf_addr as well. + +The hook is not guaranteed to work, because it attempts to get the value r2 +had at function entry. + +The hook can be called after function entry, and the ABI doesn't guarantee +that r2 is the same throughout the function. + +Using -fvar-tracking adds debug information, which allows the hook to succeed +more often, and indeed after adding this to the test-case, it passes. + +Do likewise in one more test-case. + +Tested on s390x-linux. + +Fixes: +- gdb.ada/finish-large.exp +- gdb.base/finish-pretty.exp +- gdb.base/retval-large-struct.exp +- gdb.cp/non-trivial-retval.exp +- gdb.ada/array_return.exp + +AFAICT, I've also enabled the hook for s390 and from the ABI I get the +impression that it should work, but I haven't been able to test it. + +[1] https://github.com/IBM/s390x-abi +--- + gdb/s390-tdep.c | 58 ++++++++++++++++++++++++ + gdb/testsuite/gdb.ada/array_return.exp | 8 +++- + gdb/testsuite/gdb.base/finish-pretty.exp | 8 +++- + 3 files changed, 72 insertions(+), 2 deletions(-) + +diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c +index 4844b7e9bc8..4e7dce70c12 100644 +--- a/gdb/s390-tdep.c ++++ b/gdb/s390-tdep.c +@@ -40,6 +40,7 @@ + #include "trad-frame.h" + #include "value.h" + #include "inferior.h" ++#include "dwarf2/loc.h" + + #include "features/s390-linux32.c" + #include "features/s390x-linux64.c" +@@ -2119,6 +2120,62 @@ s390_return_value (struct gdbarch *gdbarch, struct value *function, + return rvc; + } + ++/* Try to get the value of DWARF_REG in FRAME at function entry. If successful, ++ return it as value of type VAL_TYPE. */ ++ ++static struct value * ++dwarf_reg_on_entry (int dwarf_reg, struct type *val_type, ++ const frame_info_ptr &frame) ++{ ++ enum call_site_parameter_kind kind = CALL_SITE_PARAMETER_DWARF_REG; ++ union call_site_parameter_u kind_u = { .dwarf_reg = dwarf_reg }; ++ ++ try ++ { ++ return value_of_dwarf_reg_entry (val_type, frame, kind, kind_u); ++ } ++ catch (const gdb_exception_error &e) ++ { ++ if (e.error == NO_ENTRY_VALUE_ERROR) ++ return nullptr; ++ ++ throw; ++ } ++} ++ ++/* Both the 32-bit and 64-bit ABIs specify that values of some types are ++ returned in a storage buffer provided by the caller. Return the address of ++ that storage buffer, if possible. Implements the ++ gdbarch_get_return_buf_addr hook. */ ++ ++static CORE_ADDR ++s390_get_return_buf_addr (struct type *val_type, ++ const frame_info_ptr &cur_frame) ++{ ++ /* The address of the storage buffer is provided as a hidden argument in ++ register r2. */ ++ int dwarf_reg = 2; ++ ++ /* The ABI does not guarantee that the register will not be changed while ++ executing the function. Hence, it cannot be assumed that it will still ++ contain the address of the storage buffer when execution reaches the end ++ of the function. ++ ++ Attempt to determine the value on entry using the DW_OP_entry_value DWARF ++ entries. This requires compiling the user program with -fvar-tracking. */ ++ struct value *val_on_entry ++ = dwarf_reg_on_entry (dwarf_reg, lookup_pointer_type (val_type), cur_frame); ++ ++ if (val_on_entry == nullptr) ++ { ++ warning ("Cannot determine the function return value.\n" ++ "Try compiling with -fvar-tracking."); ++ return 0; ++ } ++ ++ return value_as_address (val_on_entry); ++} ++ + /* Frame unwinding. */ + + /* Implement the stack_frame_destroyed_p gdbarch method. */ +@@ -7183,6 +7240,7 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + set_gdbarch_dummy_id (gdbarch, s390_dummy_id); + set_gdbarch_frame_align (gdbarch, s390_frame_align); + set_gdbarch_return_value (gdbarch, s390_return_value); ++ set_gdbarch_get_return_buf_addr (gdbarch, s390_get_return_buf_addr); + + /* Frame handling. */ + /* Stack grows downward. */ +diff --git a/gdb/testsuite/gdb.ada/array_return.exp b/gdb/testsuite/gdb.ada/array_return.exp +index c6edee11f17..d1fc2ac2c98 100644 +--- a/gdb/testsuite/gdb.ada/array_return.exp ++++ b/gdb/testsuite/gdb.ada/array_return.exp +@@ -19,7 +19,13 @@ require allow_ada_tests + + standard_ada_testfile p + +-if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug}] != ""} { ++set opts {} ++lappend opts debug ++if { [have_fvar_tracking] } { ++ lappend opts "additional_flags=-fvar-tracking" ++} ++ ++if {[gdb_compile_ada "${srcfile}" "${binfile}" executable $opts] != ""} { + return -1 + } + +diff --git a/gdb/testsuite/gdb.base/finish-pretty.exp b/gdb/testsuite/gdb.base/finish-pretty.exp +index 44f3340f41c..0b6bea6681d 100644 +--- a/gdb/testsuite/gdb.base/finish-pretty.exp ++++ b/gdb/testsuite/gdb.base/finish-pretty.exp +@@ -18,7 +18,13 @@ + + standard_testfile + +-if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { ++set opts {} ++lappend opts debug ++if { [have_fvar_tracking] } { ++ lappend opts "additional_flags=-fvar-tracking" ++} ++ ++if { [prepare_for_testing "failed to prepare" $testfile $srcfile $opts] } { + return -1 + } + +-- +2.43.0 + diff --git a/fix-gdb.base-readnever.exp-on-s390x.patch b/fix-gdb.base-readnever.exp-on-s390x.patch new file mode 100644 index 0000000..ff7e605 --- /dev/null +++ b/fix-gdb.base-readnever.exp-on-s390x.patch @@ -0,0 +1,187 @@ +From 1d761604714b32883d2bbc4a5f274fc3e2c668fe Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Thu, 9 Jan 2025 14:32:19 +0100 +Subject: [PATCH 22/46] Fix gdb.base/readnever.exp on s390x + +On s390x-linux, I run into: +... + (gdb) backtrace + #0 0x000000000100061a in fun_three () + #1 0x000000000100067a in fun_two () + #2 0x000003fffdfa9470 in ?? () + Backtrace stopped: frame did not save the PC + (gdb) FAIL: gdb.base/readnever.exp: backtrace +... + +This is really due to a problem handling the fun_three frame. When generating +a backtrace from fun_two, everying looks ok: +... + $ gdb -readnever -q -batch outputs/gdb.base/readnever/readnever \ + -ex "b fun_two" \ + -ex run \ + -ex bt + ... + #0 0x0000000001000650 in fun_two () + #1 0x00000000010006b6 in fun_one () + #2 0x00000000010006ee in main () +... + +For reference the frame info with debug info (without -readnever) looks like this: +... +$ gdb -q -batch outputs/gdb.base/readnever/readnever \ + -ex "b fun_three" \ + -ex run \ + -ex "info frame" + ... +Stack level 0, frame at 0x3fffffff140: + pc = 0x1000632 in fun_three (readnever.c:20); saved pc = 0x100067a + called by frame at 0x3fffffff1f0 + source language c. + Arglist at 0x3fffffff140, args: a=10, b=49 '1', c=0x3fffffff29c + Locals at 0x3fffffff140, Previous frame's sp in v0 +... + +But with -readnever, like this instead: +... +Stack level 0, frame at 0x0: + pc = 0x100061a in fun_three; saved pc = 0x100067a + called by frame at 0x3fffffff140 + Arglist at 0xffffffffffffffff, args: + Locals at 0xffffffffffffffff, Previous frame's sp in r15 +... + +An obvious difference is the "Previous frame's sp in" v0 vs. r15. + +Looking at the code: +... +0000000001000608 : + 1000608: b3 c1 00 2b ldgr %f2,%r11 + 100060c: b3 c1 00 0f ldgr %f0,%r15 + 1000610: e3 f0 ff 50 ff 71 lay %r15,-176(%r15) + 1000616: b9 04 00 bf lgr %r11,%r15 +... +it becomes clear what is going on. This is an unusual prologue. + +Rather than saving r11 (frame pointer) and r15 (stack pointer) to stack, +instead they're saved into call-clobbered floating point registers. + +[ For reference, this is the prologue of fun_two: +... +0000000001000640 : + 1000640: eb bf f0 58 00 24 stmg %r11,%r15,88(%r15) + 1000646: e3 f0 ff 50 ff 71 lay %r15,-176(%r15) + 100064c: b9 04 00 bf lgr %r11,%r15 +... +where the first instruction stores registers r11 to r15 to stack. ] + +Gdb fails to properly analyze the prologue, which causes the problems getting +the frame info. + +Fix this by: +- adding handling of the ldgr insn [1] in s390_analyze_prologue, and +- recognizing the insn as saving a register in + s390_prologue_frame_unwind_cache. + +This gets us instead: +... +Stack level 0, frame at 0x0: + pc = 0x100061a in fun_three; saved pc = 0x100067a + called by frame at 0x3fffffff1f0 + Arglist at 0xffffffffffffffff, args: + Locals at 0xffffffffffffffff, Previous frame's sp in f0 +... +and: +... + (gdb) backtrace^M + #0 0x000000000100061a in fun_three ()^M + #1 0x000000000100067a in fun_two ()^M + #2 0x00000000010006b6 in fun_one ()^M + #3 0x00000000010006ee in main ()^M + (gdb) PASS: gdb.base/readnever.exp: backtrace +... + +Tested on s390x-linux. + +PR tdep/32417 +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32417 + +Approved-By: Andreas Arnez + +[1] https://www.ibm.com/support/pages/sites/default/files/2021-05/SA22-7871-10.pdf +--- + gdb/s390-tdep.c | 39 +++++++++++++++++++++++++++++++++++++++ + gdb/s390-tdep.h | 1 + + 2 files changed, 40 insertions(+) + +diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c +index 4e7dce70c12..2609b42f797 100644 +--- a/gdb/s390-tdep.c ++++ b/gdb/s390-tdep.c +@@ -855,6 +855,11 @@ s390_analyze_prologue (struct gdbarch *gdbarch, + || is_rre (insn64, op_lgr, &r1, &r2)) + data->gpr[r1] = data->gpr[r2]; + ++ /* LDGR r1, r2 --- load from register to floating-point register ++ (64-bit version). */ ++ else if (is_rre (insn64, op_ldgr, &r1, &r2)) ++ data->fpr[r1] = data->gpr[r2]; ++ + /* L r1, d2(x2, b2) --- load. */ + /* LY r1, d2(x2, b2) --- load (long-displacement version). */ + /* LG r1, d2(x2, b2) --- load (64-bit version). */ +@@ -2542,6 +2547,40 @@ s390_prologue_frame_unwind_cache (const frame_info_ptr &this_frame, + && data.fpr_slot[i] != 0) + info->saved_regs[S390_F0_REGNUM + i].set_addr (cfa - data.fpr_slot[i]); + ++ /* Handle this type of prologue: ++ ldgr %f2,%r11 ++ ldgr %f0,%r15 ++ where call-clobbered floating point registers are used as register save ++ slots. */ ++ for (i = 0; i < S390_NUM_FPRS; i++) ++ { ++ int fpr = S390_F0_REGNUM + i; ++ ++ /* Check that fpr is a call-clobbered register. */ ++ if (s390_register_call_saved (gdbarch, fpr)) ++ continue; ++ ++ /* Check that fpr contains the value of a register at function ++ entry. */ ++ if (data.fpr[i].kind != pvk_register) ++ continue; ++ ++ int entry_val_reg = data.fpr[i].reg; ++ ++ /* Check that entry_val_reg is a call-saved register. */ ++ if (!s390_register_call_saved (gdbarch, entry_val_reg)) ++ continue; ++ ++ /* In the prologue, we've copied: ++ - the value of a call-saved register (entry_val_reg) at function ++ entry, to ++ - a call-clobbered floating point register (fpr). ++ ++ Heuristic: assume that makes the floating point register a register ++ save slot, leaving the value constant throughout the function. */ ++ info->saved_regs[entry_val_reg].set_realreg (fpr); ++ } ++ + /* Function return will set PC to %r14. */ + info->saved_regs[S390_PSWA_REGNUM] = info->saved_regs[S390_RETADDR_REGNUM]; + +diff --git a/gdb/s390-tdep.h b/gdb/s390-tdep.h +index 10f775f468f..b098d735a13 100644 +--- a/gdb/s390-tdep.h ++++ b/gdb/s390-tdep.h +@@ -82,6 +82,7 @@ enum + op1_lgfi = 0xc0, op2_lgfi = 0x01, + op_lr = 0x18, + op_lgr = 0xb904, ++ op_ldgr = 0xb3c1, + op_l = 0x58, + op1_ly = 0xe3, op2_ly = 0x58, + op1_lg = 0xe3, op2_lg = 0x04, +-- +2.43.0 + diff --git a/fix-gdb.base-store.exp-on-s390x.patch b/fix-gdb.base-store.exp-on-s390x.patch new file mode 100644 index 0000000..74e14df --- /dev/null +++ b/fix-gdb.base-store.exp-on-s390x.patch @@ -0,0 +1,143 @@ +From 69e165afa3d45cfac89ed6be298ac6465c84c0fd Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Wed, 15 Jan 2025 17:02:00 +0100 +Subject: [PATCH 25/46] Fix gdb.base/store.exp on s390x + +On s390x-linux, I get: +... +(gdb) print l^M +$29 = 0^M +(gdb) FAIL: gdb.base/store.exp: var doublest l; print old l, expecting -1 +... + +So, we're in wack_doublest trying to print l, which is a copy of parameter u: +... + register doublest l = u, r = v; +... +which does have the expected value: +... +(gdb) p u +$1 = -1 +... +which is a long double, 16 bytes and looks like this: +... +(gdb) p /x u +$3 = 0xbfff0000000000000000000000000000 +... + +Parameter u is passed in two registers: +... + <2><6a5>: Abbrev Number: 15 (DW_TAG_formal_parameter) + <6a6> DW_AT_name : v + <69e> DW_AT_location : 6 byte block: 50 93 8 51 93 8 \ + (DW_OP_reg0 (r0); DW_OP_piece: 8; DW_OP_reg1 (r1); DW_OP_piece: 8) +... +and indeed we find the msw in r0 and the lsw in r1: +... +(gdb) p /x $r0 +$4 = 0xbfff000000000000 +(gdb) p /x $r1 +$5 = 0x0 +(gdb) +... + +Likewise, variable l consists of two registers: +... + <2><6b5>: Abbrev Number: 13 (DW_TAG_variable) + <6b6> DW_AT_name : l + <6be> DW_AT_location : 6 byte block: 68 93 8 69 93 8 \ + (DW_OP_reg24 (f8); DW_OP_piece: 8; DW_OP_reg25 (f10); DW_OP_piece: 8) +... +and we find the same values there: +... +(gdb) p /x $f8 +$6 = 0xbfff000000000000 +(gdb) p /x $f10 +$7 = 0x0 +... + +So, we get the expected results when fetching the value from two gprs, but not +when fetching the value from two fprs. + +When fetching the values from the two fprs, we stumble upon a particularity of +the DWARF register numbers as defined by the s390x ABI [1]: dwarf register 24 +maps to both floating-point register f8 (8 bytes), and vector register v8 +(16 bytes). + +In s390_dwarf_reg_to_regnum, it's determined which of the two is chosen, and +if available vector registers are preferred over floating-point registers, so +v8 is chosen, and used to fetch the value. + +Since the size of the DW_OP_piece is 8 bytes, and the register size is 16 +bytes, this bit in rw_pieced_value is activated: +... + /* If the piece is located in a register, but does not + occupy the entire register, the placement of the piece + within that register is defined by the ABI. */ + bits_to_skip + += 8 * gdbarch_dwarf2_reg_piece_offset (arch, gdb_regnum, + p->size / 8); +... +but since the default implemention default_dwarf2_reg_piece_offset does not +match the s390x ABI, we get the wrong answer. + +This is a known problem, see FOSDEM 2018 presentation "DWARF Pieces And Other +DWARF Location Woes" [2]. + +Fix this by adding s390_dwarf2_reg_piece_offset, roughly implementing the same +logic as in s390_value_from_register. + +Tested on s390x-linux. + +Approved-By: Tom Tromey + +[1] https://github.com/IBM/s390x-abi +[2] https://archive.fosdem.org/2018/schedule/event/dwarfpieces +--- + gdb/s390-tdep.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c +index 2609b42f797..a7c58b37276 100644 +--- a/gdb/s390-tdep.c ++++ b/gdb/s390-tdep.c +@@ -1260,6 +1260,28 @@ s390_value_from_register (gdbarch *gdbarch, type *type, int regnum, + return value; + } + ++/* Implementation of the gdbarch_dwarf2_reg_piece_offset hook. */ ++ ++static ULONGEST ++s390_dwarf2_reg_piece_offset (gdbarch *gdbarch, int gdb_regnum, ULONGEST size) ++{ ++ s390_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ ++ /* Floating point register. */ ++ if (gdb_regnum >= S390_F0_REGNUM && gdb_regnum <= S390_F15_REGNUM) ++ return 0; ++ ++ /* Vector register, v0 - v15. */ ++ if (regnum_is_vxr_full (tdep, gdb_regnum)) ++ return 0; ++ ++ /* Vector register, v16 - v31. */ ++ if (gdb_regnum >= S390_V16_REGNUM && gdb_regnum <= S390_V31_REGNUM) ++ return 0; ++ ++ return default_dwarf2_reg_piece_offset (gdbarch, gdb_regnum, size); ++} ++ + /* Implement pseudo_register_name tdesc method. */ + + static const char * +@@ -7259,6 +7281,7 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + set_gdbarch_stab_reg_to_regnum (gdbarch, s390_dwarf_reg_to_regnum); + set_gdbarch_dwarf2_reg_to_regnum (gdbarch, s390_dwarf_reg_to_regnum); + set_gdbarch_value_from_register (gdbarch, s390_value_from_register); ++ set_gdbarch_dwarf2_reg_piece_offset (gdbarch, s390_dwarf2_reg_piece_offset); + + /* Pseudo registers. */ + set_gdbarch_pseudo_register_read (gdbarch, s390_pseudo_register_read); +-- +2.43.0 + diff --git a/fix-gdb.dap-step-out.exp-on-s390x.patch b/fix-gdb.dap-step-out.exp-on-s390x.patch new file mode 100644 index 0000000..d0393ed --- /dev/null +++ b/fix-gdb.dap-step-out.exp-on-s390x.patch @@ -0,0 +1,97 @@ +From 6775ce3f5e936a50d883abfb60cafa80f8b76cf6 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Tue, 10 Dec 2024 11:53:31 +0100 +Subject: [PATCH 19/46] Fix gdb.dap/step-out.exp on s390x + +With test-case gdb.dap/step-out.exp on s390x-linux, I get: +... +>>> {"seq": 7, "type": "request", "command": "scopes", "arguments": {"frameId": 0}} +Content-Length: 569^M +^M +{"request_seq": 7, "type": "response", "command": "scopes", "body": {"scopes": [{"variablesReference": 1, "name": "Locals", "presentationHint": "locals", "expensive": false, "namedVariables": 1, "line": 35, "source": {"name": "step-out.c", "path": "/home/vries/gdb/src/gdb/testsuite/gdb.dap/step-out.c"}}, {"variablesReference": 2, "name": "Registers", "presentationHint": "registers", "expensive": false, "namedVariables": 114, "line": 35, "source": {"name": "step-out.c", "path": "/home/vries/gdb/src/gdb/testsuite/gdb.dap/step-out.c"}}]}, "success": true, "seq": 21}PASS: gdb.dap/step-out.exp: get scopes success +FAIL: gdb.dap/step-out.exp: three scopes +... + +The problem is that the test-case expects three scopes: +... +lassign $scopes scope reg_scope return_scope +... +but the return_scope is missing because this doesn't work: +... +$ gdb -q -batch outputs/gdb.dap/step-out/step-out \ + -ex "b function_breakpoint_here" \ + -ex run \ + -ex finish + ... +Value returned has type: struct result. Cannot determine contents +... + +This is likely caused by a problem in gdb, but there's nothing wrong the DAP +support. + +Fix this by: +- allowing two scopes, and +- declaring the tests of return_scope unsupported. + +Tested on s390x-linux. + +Approved-By: Tom Tromey +--- + gdb/testsuite/gdb.dap/step-out.exp | 42 ++++++++++++++++-------------- + 1 file changed, 23 insertions(+), 19 deletions(-) + +diff --git a/gdb/testsuite/gdb.dap/step-out.exp b/gdb/testsuite/gdb.dap/step-out.exp +index 757f4ebdaca..491eaf71197 100644 +--- a/gdb/testsuite/gdb.dap/step-out.exp ++++ b/gdb/testsuite/gdb.dap/step-out.exp +@@ -59,24 +59,28 @@ set scopes [dap_check_request_and_response "get scopes" scopes \ + [format {o frameId [i %d]} $frame_id]] + set scopes [dict get [lindex $scopes 0] body scopes] + +-gdb_assert {[llength $scopes] == 2} "two scopes" +- +-lassign $scopes scope reg_scope +-gdb_assert {[dict get $scope name] == "Locals"} "scope is locals" +-gdb_assert {[dict get $scope presentationHint] == "locals"} \ +- "locals presentation hint" +-gdb_assert {[dict get $scope namedVariables] == 2} "two vars in scope" +- +-set num [dict get $scope variablesReference] +-set refs [lindex [dap_check_request_and_response "fetch arguments" \ +- "variables" \ +- [format {o variablesReference [i %d]} $num]] \ +- 0] +-set varlist [lindex [dict get $refs body variables] 0] +- +-gdb_assert {[dict get $varlist variablesReference] > 0} \ +- "variable has children" +-gdb_assert {[dict get $varlist name] == "(return)"} \ +- "variable is return value" ++gdb_assert {[llength $scopes] == 2 || [llength $scopes] == 3} "two or three scopes" ++lassign $scopes scope reg_scope return_scope ++ ++set test "scope is locals" ++if { $return_scope == "" } { ++ unsupported $test ++} else { ++ gdb_assert {[dict get $scope presentationHint] == "locals"} \ ++ "locals presentation hint" ++ gdb_assert {[dict get $scope namedVariables] == 2} "two vars in scope" ++ ++ set num [dict get $scope variablesReference] ++ set refs [lindex [dap_check_request_and_response "fetch arguments" \ ++ "variables" \ ++ [format {o variablesReference [i %d]} $num]] \ ++ 0] ++ set varlist [lindex [dict get $refs body variables] 0] ++ ++ gdb_assert {[dict get $varlist variablesReference] > 0} \ ++ "variable has children" ++ gdb_assert {[dict get $varlist name] == "(return)"} \ ++ "variable is return value" ++} + + dap_shutdown +-- +2.43.0 + diff --git a/fix-gdb.dwarf2-shortpiece.exp-on-s390x.patch b/fix-gdb.dwarf2-shortpiece.exp-on-s390x.patch new file mode 100644 index 0000000..87ab318 --- /dev/null +++ b/fix-gdb.dwarf2-shortpiece.exp-on-s390x.patch @@ -0,0 +1,56 @@ +From 2ccefe53891d9c1393853f5179f8e8046c95a6ce Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Wed, 19 Jun 2024 10:04:22 +0200 +Subject: [PATCH 17/46] Fix gdb.dwarf2/shortpiece.exp on s390x + +On s390x-linux, I run into: +... +(gdb) p (short []) s1^M +$3 = {0, 1, 0, }^M +(gdb) FAIL: gdb.dwarf2/shortpiece.exp: p (short []) s1 +... +while this is expected: +... +(gdb) p (short []) s1^M +$3 = {1, 0, 0, }^M +(gdb) PASS: gdb.dwarf2/shortpiece.exp: p (short []) s1 +... + +The type of s1 is: +... +(gdb) ptype s1 +type = struct S { + myint a; + myushort b; +} +... +so the difference is due the fact that viewing an int as two shorts gives +different results depending on the endianness. + +Fix this by allowing both results. + +Tested on x86_64-linux and s390x-linux. + +Approved-By: Tom Tromey +--- + gdb/testsuite/gdb.dwarf2/shortpiece.exp | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/gdb/testsuite/gdb.dwarf2/shortpiece.exp b/gdb/testsuite/gdb.dwarf2/shortpiece.exp +index f7ff805de7c..4fcdfcae57a 100644 +--- a/gdb/testsuite/gdb.dwarf2/shortpiece.exp ++++ b/gdb/testsuite/gdb.dwarf2/shortpiece.exp +@@ -138,7 +138,9 @@ gdb_test "p s2" \ + # This test verifies that GDB can print a pieced value casted to a + # different type. + gdb_test "p (int \[\]) s1" " = \\{1, \\}" +-gdb_test "p (short \[\]) s1" " = \\{1, 0, 0, \\}" ++set re_little [string_to_regexp "{1, 0, 0, }"] ++set re_big [string_to_regexp "{0, 1, 0, }"] ++gdb_test {p (short []) s1} " = ($re_little|$re_big)" + + # Test for correct output if the size of the original object is not a + # multiple of the array's element size. +-- +2.43.0 + diff --git a/fix-regression-on-aarch64-linux-gdbserver.patch b/fix-regression-on-aarch64-linux-gdbserver.patch deleted file mode 100644 index 2599a44..0000000 --- a/fix-regression-on-aarch64-linux-gdbserver.patch +++ /dev/null @@ -1,366 +0,0 @@ -From 2a7e48ca27f4c080151ce9da5a29239aa5d3b66f Mon Sep 17 00:00:00 2001 -From: Tom Tromey -Date: Fri, 19 Apr 2024 07:54:19 -0600 -Subject: [PATCH 15/48] Fix regression on aarch64-linux gdbserver - -Commit 9a03f218 ("Fix gdb.base/watchpoint-unaligned.exp on aarch64") -fixed a watchpoint bug in gdb -- but did not touch the corresponding -code in gdbserver. - -This patch moves the gdb code into gdb/nat, so that it can be shared -with gdbserver, and then changes gdbserver to use it, fixing the bug. - -This is yet another case where having a single back end would prevent -bugs. - -I tested this using the AdaCore internal gdb testsuite. - -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29423 -Approved-By: Luis Machado ---- - gdb/aarch64-nat.c | 115 --------------------------------- - gdb/aarch64-nat.h | 8 --- - gdb/nat/aarch64-hw-point.c | 115 +++++++++++++++++++++++++++++++++ - gdb/nat/aarch64-hw-point.h | 8 +++ - gdbserver/linux-aarch64-low.cc | 38 +---------- - 5 files changed, 126 insertions(+), 158 deletions(-) - -diff --git a/gdb/aarch64-nat.c b/gdb/aarch64-nat.c -index a173e4e18d5..97e3048568a 100644 ---- a/gdb/aarch64-nat.c -+++ b/gdb/aarch64-nat.c -@@ -225,121 +225,6 @@ aarch64_remove_watchpoint (CORE_ADDR addr, int len, enum target_hw_bp_type type, - return ret; - } - --/* See aarch64-nat.h. */ -- --bool --aarch64_stopped_data_address (const struct aarch64_debug_reg_state *state, -- CORE_ADDR addr_trap, CORE_ADDR *addr_p) --{ -- bool found = false; -- for (int phase = 0; phase <= 1; ++phase) -- for (int i = aarch64_num_wp_regs - 1; i >= 0; --i) -- { -- if (!(state->dr_ref_count_wp[i] -- && DR_CONTROL_ENABLED (state->dr_ctrl_wp[i]))) -- { -- /* Watchpoint disabled. */ -- continue; -- } -- -- const enum target_hw_bp_type type -- = aarch64_watchpoint_type (state->dr_ctrl_wp[i]); -- if (type == hw_execute) -- { -- /* Watchpoint disabled. */ -- continue; -- } -- -- if (phase == 0) -- { -- /* Phase 0: No hw_write. */ -- if (type == hw_write) -- continue; -- } -- else -- { -- /* Phase 1: Only hw_write. */ -- if (type != hw_write) -- continue; -- } -- -- const unsigned int offset -- = aarch64_watchpoint_offset (state->dr_ctrl_wp[i]); -- const unsigned int len -- = aarch64_watchpoint_length (state->dr_ctrl_wp[i]); -- const CORE_ADDR addr_watch = state->dr_addr_wp[i] + offset; -- const CORE_ADDR addr_watch_aligned -- = align_down (state->dr_addr_wp[i], AARCH64_HWP_MAX_LEN_PER_REG); -- const CORE_ADDR addr_orig = state->dr_addr_orig_wp[i]; -- -- /* ADDR_TRAP reports the first address of the memory range -- accessed by the CPU, regardless of what was the memory -- range watched. Thus, a large CPU access that straddles -- the ADDR_WATCH..ADDR_WATCH+LEN range may result in an -- ADDR_TRAP that is lower than the -- ADDR_WATCH..ADDR_WATCH+LEN range. E.g.: -- -- addr: | 4 | 5 | 6 | 7 | 8 | -- |---- range watched ----| -- |----------- range accessed ------------| -- -- In this case, ADDR_TRAP will be 4. -- -- The access size also can be larger than that of the watchpoint -- itself. For instance, the access size of an stp instruction is 16. -- So, if we use stp to store to address p, and set a watchpoint on -- address p + 8, the reported ADDR_TRAP can be p + 8 (observed on -- RK3399 SOC). But it also can be p (observed on M1 SOC). Checking -- for this situation introduces the possibility of false positives, -- so we only do this for hw_write watchpoints. */ -- const CORE_ADDR max_access_size = type == hw_write ? 16 : 8; -- const CORE_ADDR addr_watch_base = addr_watch_aligned - -- (max_access_size - AARCH64_HWP_MAX_LEN_PER_REG); -- if (!(addr_trap >= addr_watch_base -- && addr_trap < addr_watch + len)) -- { -- /* Not a match. */ -- continue; -- } -- -- /* To match a watchpoint known to GDB core, we must never -- report *ADDR_P outside of any ADDR_WATCH..ADDR_WATCH+LEN -- range. ADDR_WATCH <= ADDR_TRAP < ADDR_ORIG is a false -- positive on kernels older than 4.10. See PR -- external/20207. */ -- if (addr_p != nullptr) -- *addr_p = addr_orig; -- -- if (phase == 0) -- { -- /* Phase 0: Return first match. */ -- return true; -- } -- -- /* Phase 1. */ -- if (addr_p == nullptr) -- { -- /* First match, and we don't need to report an address. No need -- to look for other matches. */ -- return true; -- } -- -- if (!found) -- { -- /* First match, and we need to report an address. Look for other -- matches. */ -- found = true; -- continue; -- } -- -- /* More than one match, and we need to return an address. No need to -- look for further matches. */ -- return false; -- } -- -- return found; --} -- - /* Define AArch64 maintenance commands. */ - - static void -diff --git a/gdb/aarch64-nat.h b/gdb/aarch64-nat.h -index fee6bda2577..f95a9d745e5 100644 ---- a/gdb/aarch64-nat.h -+++ b/gdb/aarch64-nat.h -@@ -45,14 +45,6 @@ struct aarch64_debug_reg_state *aarch64_get_debug_reg_state (pid_t pid); - - void aarch64_remove_debug_reg_state (pid_t pid); - --/* Helper for the "stopped_data_address" target method. Returns TRUE -- if a hardware watchpoint trap at ADDR_TRAP matches a set -- watchpoint. The address of the matched watchpoint is returned in -- *ADDR_P. */ -- --bool aarch64_stopped_data_address (const struct aarch64_debug_reg_state *state, -- CORE_ADDR addr_trap, CORE_ADDR *addr_p); -- - /* Helper functions used by aarch64_nat_target below. See their - definitions. */ - -diff --git a/gdb/nat/aarch64-hw-point.c b/gdb/nat/aarch64-hw-point.c -index 3b8cdcba23b..9eb78923e86 100644 ---- a/gdb/nat/aarch64-hw-point.c -+++ b/gdb/nat/aarch64-hw-point.c -@@ -647,3 +647,118 @@ aarch64_region_ok_for_watchpoint (CORE_ADDR addr, int len) - the checking is costly. */ - return 1; - } -+ -+/* See nat/aarch64-hw-point.h. */ -+ -+bool -+aarch64_stopped_data_address (const struct aarch64_debug_reg_state *state, -+ CORE_ADDR addr_trap, CORE_ADDR *addr_p) -+{ -+ bool found = false; -+ for (int phase = 0; phase <= 1; ++phase) -+ for (int i = aarch64_num_wp_regs - 1; i >= 0; --i) -+ { -+ if (!(state->dr_ref_count_wp[i] -+ && DR_CONTROL_ENABLED (state->dr_ctrl_wp[i]))) -+ { -+ /* Watchpoint disabled. */ -+ continue; -+ } -+ -+ const enum target_hw_bp_type type -+ = aarch64_watchpoint_type (state->dr_ctrl_wp[i]); -+ if (type == hw_execute) -+ { -+ /* Watchpoint disabled. */ -+ continue; -+ } -+ -+ if (phase == 0) -+ { -+ /* Phase 0: No hw_write. */ -+ if (type == hw_write) -+ continue; -+ } -+ else -+ { -+ /* Phase 1: Only hw_write. */ -+ if (type != hw_write) -+ continue; -+ } -+ -+ const unsigned int offset -+ = aarch64_watchpoint_offset (state->dr_ctrl_wp[i]); -+ const unsigned int len -+ = aarch64_watchpoint_length (state->dr_ctrl_wp[i]); -+ const CORE_ADDR addr_watch = state->dr_addr_wp[i] + offset; -+ const CORE_ADDR addr_watch_aligned -+ = align_down (state->dr_addr_wp[i], AARCH64_HWP_MAX_LEN_PER_REG); -+ const CORE_ADDR addr_orig = state->dr_addr_orig_wp[i]; -+ -+ /* ADDR_TRAP reports the first address of the memory range -+ accessed by the CPU, regardless of what was the memory -+ range watched. Thus, a large CPU access that straddles -+ the ADDR_WATCH..ADDR_WATCH+LEN range may result in an -+ ADDR_TRAP that is lower than the -+ ADDR_WATCH..ADDR_WATCH+LEN range. E.g.: -+ -+ addr: | 4 | 5 | 6 | 7 | 8 | -+ |---- range watched ----| -+ |----------- range accessed ------------| -+ -+ In this case, ADDR_TRAP will be 4. -+ -+ The access size also can be larger than that of the watchpoint -+ itself. For instance, the access size of an stp instruction is 16. -+ So, if we use stp to store to address p, and set a watchpoint on -+ address p + 8, the reported ADDR_TRAP can be p + 8 (observed on -+ RK3399 SOC). But it also can be p (observed on M1 SOC). Checking -+ for this situation introduces the possibility of false positives, -+ so we only do this for hw_write watchpoints. */ -+ const CORE_ADDR max_access_size = type == hw_write ? 16 : 8; -+ const CORE_ADDR addr_watch_base = addr_watch_aligned - -+ (max_access_size - AARCH64_HWP_MAX_LEN_PER_REG); -+ if (!(addr_trap >= addr_watch_base -+ && addr_trap < addr_watch + len)) -+ { -+ /* Not a match. */ -+ continue; -+ } -+ -+ /* To match a watchpoint known to GDB core, we must never -+ report *ADDR_P outside of any ADDR_WATCH..ADDR_WATCH+LEN -+ range. ADDR_WATCH <= ADDR_TRAP < ADDR_ORIG is a false -+ positive on kernels older than 4.10. See PR -+ external/20207. */ -+ if (addr_p != nullptr) -+ *addr_p = addr_orig; -+ -+ if (phase == 0) -+ { -+ /* Phase 0: Return first match. */ -+ return true; -+ } -+ -+ /* Phase 1. */ -+ if (addr_p == nullptr) -+ { -+ /* First match, and we don't need to report an address. No need -+ to look for other matches. */ -+ return true; -+ } -+ -+ if (!found) -+ { -+ /* First match, and we need to report an address. Look for other -+ matches. */ -+ found = true; -+ continue; -+ } -+ -+ /* More than one match, and we need to return an address. No need to -+ look for further matches. */ -+ return false; -+ } -+ -+ return found; -+} -diff --git a/gdb/nat/aarch64-hw-point.h b/gdb/nat/aarch64-hw-point.h -index 71ae2864927..2386cf60f90 100644 ---- a/gdb/nat/aarch64-hw-point.h -+++ b/gdb/nat/aarch64-hw-point.h -@@ -110,6 +110,14 @@ unsigned int aarch64_watchpoint_offset (unsigned int ctrl); - unsigned int aarch64_watchpoint_length (unsigned int ctrl); - enum target_hw_bp_type aarch64_watchpoint_type (unsigned int ctrl); - -+/* Helper for the "stopped_data_address" target method. Returns TRUE -+ if a hardware watchpoint trap at ADDR_TRAP matches a set -+ watchpoint. The address of the matched watchpoint is returned in -+ *ADDR_P. */ -+ -+bool aarch64_stopped_data_address (const struct aarch64_debug_reg_state *state, -+ CORE_ADDR addr_trap, CORE_ADDR *addr_p); -+ - int aarch64_handle_breakpoint (enum target_hw_bp_type type, CORE_ADDR addr, - int len, int is_insert, ptid_t ptid, - struct aarch64_debug_reg_state *state); -diff --git a/gdbserver/linux-aarch64-low.cc b/gdbserver/linux-aarch64-low.cc -index fcbe7bb64d7..14346b89822 100644 ---- a/gdbserver/linux-aarch64-low.cc -+++ b/gdbserver/linux-aarch64-low.cc -@@ -577,41 +577,9 @@ aarch64_target::low_stopped_data_address () - - /* Check if the address matches any watched address. */ - state = aarch64_get_debug_reg_state (pid_of (current_thread)); -- for (i = aarch64_num_wp_regs - 1; i >= 0; --i) -- { -- const unsigned int offset -- = aarch64_watchpoint_offset (state->dr_ctrl_wp[i]); -- const unsigned int len = aarch64_watchpoint_length (state->dr_ctrl_wp[i]); -- const CORE_ADDR addr_watch = state->dr_addr_wp[i] + offset; -- const CORE_ADDR addr_watch_aligned = align_down (state->dr_addr_wp[i], 8); -- const CORE_ADDR addr_orig = state->dr_addr_orig_wp[i]; -- -- if (state->dr_ref_count_wp[i] -- && DR_CONTROL_ENABLED (state->dr_ctrl_wp[i]) -- && addr_trap >= addr_watch_aligned -- && addr_trap < addr_watch + len) -- { -- /* ADDR_TRAP reports the first address of the memory range -- accessed by the CPU, regardless of what was the memory -- range watched. Thus, a large CPU access that straddles -- the ADDR_WATCH..ADDR_WATCH+LEN range may result in an -- ADDR_TRAP that is lower than the -- ADDR_WATCH..ADDR_WATCH+LEN range. E.g.: -- -- addr: | 4 | 5 | 6 | 7 | 8 | -- |---- range watched ----| -- |----------- range accessed ------------| -- -- In this case, ADDR_TRAP will be 4. -- -- To match a watchpoint known to GDB core, we must never -- report *ADDR_P outside of any ADDR_WATCH..ADDR_WATCH+LEN -- range. ADDR_WATCH <= ADDR_TRAP < ADDR_ORIG is a false -- positive on kernels older than 4.10. See PR -- external/20207. */ -- return addr_orig; -- } -- } -+ CORE_ADDR result; -+ if (aarch64_stopped_data_address (state, addr_trap, &result)) -+ return result; - - return (CORE_ADDR) 0; - } --- -2.35.3 - diff --git a/fix-the-gdb.ada-inline-section-gc.exp-test.patch b/fix-the-gdb.ada-inline-section-gc.exp-test.patch deleted file mode 100644 index e72835c..0000000 --- a/fix-the-gdb.ada-inline-section-gc.exp-test.patch +++ /dev/null @@ -1,80 +0,0 @@ -From c21fd9f7d5911fce0c17af7094d8861d1195dfda Mon Sep 17 00:00:00 2001 -From: Carl Love -Date: Mon, 13 Nov 2023 14:14:08 -0500 -Subject: [PATCH 01/48] Fix the gdb.ada/inline-section-gc.exp test - -The original intention of the test appears to be checking to make sure -setting a breakpoint in an inlined function didn't set multiple -breakpoints where one of them was at address 0. - -The gdb.ada/inline-section-gc.exp test may pass or fail depending on the -version of gnat. Per the discussion on IRC, the ada inlining appears to -have some target dependencies. In this test there are two functions, -callee and caller. Function calee is inlined into caller. The test sets -a breakpoint in function callee. The reported location where the -breakpoint is set may be at the requested location in callee or the -location in caller after callee has been inlined. The test needs to -accept either location as correct provided the breakpoint address is not -zero. - -This patch checks to see if the reported breakpoint is in function callee -or function caller and fails if the breakpoint address is 0x0. The line -number where the breakpoint is set will match the requested line if the -breakpoint location is reported is callee.adb. If the breakpoint is -reported in caller.adb, the line number in caller is the breakpoint -location in callee where it is inlined into caller. - -This patch fixes the single regression failure for the test on PowerPC. -It does not introduce any failures on X86-64. ---- - gdb/testsuite/gdb.ada/inline-section-gc.exp | 21 ++++++++++++++++--- - .../gdb.ada/inline-section-gc/caller.adb | 3 ++- - 2 files changed, 20 insertions(+), 4 deletions(-) - -diff --git a/gdb/testsuite/gdb.ada/inline-section-gc.exp b/gdb/testsuite/gdb.ada/inline-section-gc.exp -index b707335eb04..4f8b8c95395 100644 ---- a/gdb/testsuite/gdb.ada/inline-section-gc.exp -+++ b/gdb/testsuite/gdb.ada/inline-section-gc.exp -@@ -34,8 +34,23 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable $options] != ""} { - - clean_restart ${testfile} - --set bp_location [gdb_get_line_number "BREAK" ${testdir}/callee.adb] -+ -+# Depending on the version of gnat, the location of the set breakpoint may -+# be reported as being at the requested location in file callee.adb or in -+# file caller.adb where the callee function was inlined. Either way, only -+# one breakpoint should be reported and its address should not be at 0x0. -+set bp_location1 [gdb_get_line_number "BREAK" ${testdir}/callee.adb] -+set bp_location2 [gdb_get_line_number "CALLEE_LOC" ${testdir}/caller.adb] -+set test "break callee.adb:$bp_location1" -+set message "Breakpoint set" -+ - # The bug here was that gdb would set a breakpoint with two locations, - # one of them at 0x0. --gdb_test "break callee.adb:$bp_location" \ -- "Breakpoint $decimal at $hex: file .*callee.adb, line $bp_location." -+gdb_test_multiple $test $message { -+ -re "Breakpoint $decimal at $hex: file .*callee.adb, line $bp_location1." { -+ pass $test -+ } -+ -re "Breakpoint $decimal at $hex: file .*caller.adb, line $bp_location2." { -+ pass $test -+ } -+} -diff --git a/gdb/testsuite/gdb.ada/inline-section-gc/caller.adb b/gdb/testsuite/gdb.ada/inline-section-gc/caller.adb -index 66eb2d9a910..161f3e85542 100644 ---- a/gdb/testsuite/gdb.ada/inline-section-gc/caller.adb -+++ b/gdb/testsuite/gdb.ada/inline-section-gc/caller.adb -@@ -18,4 +18,5 @@ with Callee; - procedure Caller is - begin - Callee; --end Caller; -+end Caller; -- CALLEE_LOC, this is where the inlined callee breakpoint -+ -- is located. - -base-commit: 582fc35843fdf71b82d645d83d2903e2546cc21a --- -2.35.3 - diff --git a/fixup-gdb-6.3-attach-see-vdso-test.patch b/fixup-gdb-6.3-attach-see-vdso-test.patch deleted file mode 100644 index 43ee239..0000000 --- a/fixup-gdb-6.3-attach-see-vdso-test.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 19dc95258888a9e110ad54fa25a613611956a13f Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Tue, 13 Jun 2023 15:04:32 +0200 -Subject: [PATCH 5/6] fixup gdb-6.3-attach-see-vdso-test.patch - ---- - gdb/testsuite/gdb.base/attach-see-vdso.exp | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/gdb/testsuite/gdb.base/attach-see-vdso.exp b/gdb/testsuite/gdb.base/attach-see-vdso.exp -index 5457ec4129d..35c49731f0b 100644 ---- a/gdb/testsuite/gdb.base/attach-see-vdso.exp -+++ b/gdb/testsuite/gdb.base/attach-see-vdso.exp -@@ -34,10 +34,11 @@ set escapedbinfile [string_to_regexp [standard_output_file ${testfile}]] - # The kernel VDSO is used for the syscalls returns only on i386 (not x86_64). - # - if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-m32}] != "" } { -- gdb_suppress_entire_file "Testcase nonthraded compile failed, so all tests in this file will automatically fail." -+ unsupported "Testcase nonthreaded compile failed, so all tests in this file will automatically fail." -+ return - } - --if [get_compiler_info ${binfile}] { -+if [get_compiler_info] { - return -1 - } - --- -2.35.3 - diff --git a/fixup-gdb-6.3-gstack-20050411.patch b/fixup-gdb-6.3-gstack-20050411.patch deleted file mode 100644 index 427b668..0000000 --- a/fixup-gdb-6.3-gstack-20050411.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 8c0ae8c3c6fa34f046131f76871db13bc392a440 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Tue, 13 Jun 2023 14:56:55 +0200 -Subject: [PATCH 4/6] fixup gdb-6.3-gstack-20050411.patch - ---- - gdb/testsuite/gdb.base/gstack.exp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gdb/testsuite/gdb.base/gstack.exp b/gdb/testsuite/gdb.base/gstack.exp -index 089407ec04a..a5dacd582ff 100644 ---- a/gdb/testsuite/gdb.base/gstack.exp -+++ b/gdb/testsuite/gdb.base/gstack.exp -@@ -52,7 +52,7 @@ gdb_expect { - # exiting the function. Still we could retry the gstack command if we fail. - - set test "spawn gstack" --set command "sh -c GDB=$GDB\\ GDBARGS=-data-directory\\\\\\ $BUILD_DATA_DIRECTORY\\ sh\\ ${srcdir}/../gstack.sh\\ $pid\\;echo\\ GSTACK-END" -+set command "sh -c GDB=$GDB\\ GDBARGS=-data-directory\\\\\\ $GDB_DATA_DIRECTORY\\ sh\\ ${srcdir}/../gstack.sh\\ $pid\\;echo\\ GSTACK-END" - set res [remote_spawn host $command]; - if { $res < 0 || $res == "" } { - perror "Spawning $command failed." --- -2.35.3 - diff --git a/fixup-gdb-6.5-bz243845-stale-testing-zombie-test.patch b/fixup-gdb-6.5-bz243845-stale-testing-zombie-test.patch deleted file mode 100644 index d15ce01..0000000 --- a/fixup-gdb-6.5-bz243845-stale-testing-zombie-test.patch +++ /dev/null @@ -1,35 +0,0 @@ -Fixup gdb.base/tracefork-zombie.exp - -Fix ERROR: -... -PASS: gdb.base/tracefork-zombie.exp: attach -ERROR: tcl error sourcing gdb/testsuite/gdb.base/tracefork-zombie.exp. -ERROR: tcl error code POSIX ESRCH {no such process} -ERROR: error reading "file12": no such process - while executing -"read $statusfi" - ("foreach" body line 5) - invoked from within -... - ---- - gdb/testsuite/gdb.base/tracefork-zombie.exp | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/gdb/testsuite/gdb.base/tracefork-zombie.exp b/gdb/testsuite/gdb.base/tracefork-zombie.exp -index 03f790d4c5d..3e2e5517d46 100644 ---- a/gdb/testsuite/gdb.base/tracefork-zombie.exp -+++ b/gdb/testsuite/gdb.base/tracefork-zombie.exp -@@ -58,8 +58,10 @@ foreach procpid [glob -directory /proc -type d {[0-9]*}] { - if {[catch {open $procpid/status} statusfi]} { - continue - } -- set status [read $statusfi] -- close $statusfi -+ if {[catch {read $statusfi} status]} { -+ continue -+ } -+ catch {close $statusfi} - if {1 - && [regexp -line {^Name:\tgdb$} $status] - && [regexp -line {^PPid:\t1$} $status] diff --git a/fixup-gdb-6.5-gcore-buffer-limit-test.patch b/fixup-gdb-6.5-gcore-buffer-limit-test.patch new file mode 100644 index 0000000..de15457 --- /dev/null +++ b/fixup-gdb-6.5-gcore-buffer-limit-test.patch @@ -0,0 +1,25 @@ +From 388654c78086e5240fec47260e47d1deff4af43d Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Thu, 6 Feb 2025 13:27:57 +0100 +Subject: [PATCH 43/46] fixup-gdb-6.5-gcore-buffer-limit-test.patch + +--- + gdb/testsuite/gdb.base/gcore-excessive-memory.exp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/gdb/testsuite/gdb.base/gcore-excessive-memory.exp b/gdb/testsuite/gdb.base/gcore-excessive-memory.exp +index 31cf88ce78a..1ef595923ad 100644 +--- a/gdb/testsuite/gdb.base/gcore-excessive-memory.exp ++++ b/gdb/testsuite/gdb.base/gcore-excessive-memory.exp +@@ -14,6 +14,8 @@ + # along with this program; if not, write to the Free Software + # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + ++require can_spawn_for_attach ++ + if {[use_gdb_stub]} { + untested "skipping test because of use_gdb_stub" + return -1 +-- +2.43.0 + diff --git a/fixup-gdb-add-rpm-suggestion-script.patch b/fixup-gdb-add-rpm-suggestion-script.patch new file mode 100644 index 0000000..a9dc436 --- /dev/null +++ b/fixup-gdb-add-rpm-suggestion-script.patch @@ -0,0 +1,26 @@ +From a7d9abecbc24e3d68746ea5b905eba11913980e1 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Tue, 25 Mar 2025 17:15:01 +0100 +Subject: [PATCH 2/2] fixup-gdb-add-rpm-suggestion-script.patch + +--- + gdb/python/lib/gdb/command/rpm-suggestions.py | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/gdb/python/lib/gdb/command/rpm-suggestions.py b/gdb/python/lib/gdb/command/rpm-suggestions.py +index bb049bc66e7..066ce98d947 100644 +--- a/gdb/python/lib/gdb/command/rpm-suggestions.py ++++ b/gdb/python/lib/gdb/command/rpm-suggestions.py +@@ -510,8 +510,7 @@ class rpm_suggestion_build_id_mode(gdb.Parameter): + + # The 'info rpm-suggestions' command. + class rpm_suggestion_info(gdb.Command): +- """Relist any RPM installation suggestions that have been made +- since the executable was last changed.""" ++ """Relist any RPM installation suggestions that have been made since the executable was last changed.""" + def __init__(self): + super().__init__("info rpm-suggestions", gdb.COMMAND_NONE, gdb.COMPLETE_NONE) + +-- +2.43.0 + diff --git a/fixup-gdb-bz634108-solib_address.patch b/fixup-gdb-bz634108-solib_address.patch deleted file mode 100644 index a18ae59..0000000 --- a/fixup-gdb-bz634108-solib_address.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 023314feb400836eb377a5bc9151850fcdd81b11 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Tue, 6 Jun 2023 09:43:36 +0200 -Subject: [PATCH 3/4] Fixup gdb-bz634108-solib_address.patch - ---- - gdb/testsuite/gdb.python/rh634108-solib_address.exp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gdb/testsuite/gdb.python/rh634108-solib_address.exp b/gdb/testsuite/gdb.python/rh634108-solib_address.exp -index 99e6aaba831..ebf00babc34 100644 ---- a/gdb/testsuite/gdb.python/rh634108-solib_address.exp -+++ b/gdb/testsuite/gdb.python/rh634108-solib_address.exp -@@ -21,4 +21,4 @@ gdb_start - # Skip all tests if Python scripting is not enabled. - if { [skip_python_tests] } { continue } - --gdb_test "python print (gdb.solib_name(-1))" "None" "gdb.solib_name exists" -+gdb_test "python print (gdb.solib_name(0))" "None" "gdb.solib_name exists" --- -2.35.3 - diff --git a/fixup-gdb-glibc-strstr-workaround.patch b/fixup-gdb-glibc-strstr-workaround.patch deleted file mode 100644 index b0037e0..0000000 --- a/fixup-gdb-glibc-strstr-workaround.patch +++ /dev/null @@ -1,19 +0,0 @@ -fixup-gdb-glibc-strstr-workaround.patch - ---- - gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp b/gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp -index 889f8c6f584..052bd84d420 100644 ---- a/gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp -+++ b/gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp -@@ -68,7 +68,7 @@ gdb_test_multiple $test $test { - set addr $expect_out(1,string) - pass "$test (fixed glibc)" - } -- -re " = {char \\*\\(const char \\*, const char \\*\\)} 0x\[0-9a-f\]+ \r\n$gdb_prompt $" { -+ -re " = {char \\*\\(const char \\*, const char \\*\\)} 0x\[0-9a-f\]+ <(__GI_)?strstr>\r\n$gdb_prompt $" { - untested "$test (gnu-ifunc not in use by glibc)" - return 0 - } diff --git a/fixup-gdb-linux_perf-bundle.patch b/fixup-gdb-linux_perf-bundle.patch deleted file mode 100644 index c118deb..0000000 --- a/fixup-gdb-linux_perf-bundle.patch +++ /dev/null @@ -1,40 +0,0 @@ -From af4a87e2b3c2ac5acae1e6f4405fc59e1218de74 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Thu, 18 Apr 2024 14:26:58 +0200 -Subject: [PATCH] fixup-gdb-linux_perf-bundle - ---- - gdb/gdb.c | 8 -------- - 1 file changed, 8 deletions(-) - -diff --git a/gdb/gdb.c b/gdb/gdb.c -index 41a9b70c222..6e3ff0755ab 100644 ---- a/gdb/gdb.c -+++ b/gdb/gdb.c -@@ -21,10 +21,6 @@ - #include "interps.h" - #include "run-on-main-thread.h" - --#ifdef PERF_ATTR_SIZE_VER5_BUNDLE --extern "C" void __libipt_init(void); --#endif -- - int - main (int argc, char **argv) - { -@@ -36,10 +32,6 @@ main (int argc, char **argv) - - struct captured_main_args args; - --#ifdef PERF_ATTR_SIZE_VER5_BUNDLE -- __libipt_init(); --#endif -- - memset (&args, 0, sizeof args); - args.argc = argc; - args.argv = argv; - -base-commit: 254988c36fe592e89af5d92e1d35a6eb4b09cbb0 --- -2.35.3 - diff --git a/fixup-gdb-rhbz1261564-aarch64-hw-watchpoint-test.pat.patch b/fixup-gdb-rhbz1261564-aarch64-hw-watchpoint-test.pat.patch deleted file mode 100644 index 7ee17b2..0000000 --- a/fixup-gdb-rhbz1261564-aarch64-hw-watchpoint-test.pat.patch +++ /dev/null @@ -1,43 +0,0 @@ -From e452307ba07f5d798edad73631182e137265da7d Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Tue, 13 Jun 2023 17:58:42 +0200 -Subject: [PATCH 9/9] fixup gdb-rhbz1261564-aarch64-hw-watchpoint-test.patch - ---- - .../rhbz1261564-aarch64-watchpoint.exp | 18 ++++++++++++++---- - 1 file changed, 14 insertions(+), 4 deletions(-) - -diff --git a/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.exp b/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.exp -index b1cf7115663..42ebc25cc49 100644 ---- a/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.exp -+++ b/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.exp -@@ -20,12 +20,22 @@ if { [prepare_for_testing rhbz1261564-aarch64-watchpoint.exp "rhbz1261564-aarch6 - if { ! [ runto main ] } then { return 0 } - - set test "rwatch aligned.var4" --if [istarget "s390*-*-*"] { -- gdb_test $test {Target does not support this type of hardware watchpoint\.} -- untested "s390* does not support hw read watchpoint" -+ -+set supported 1 -+gdb_test_multiple $test "" { -+ -re -wrap "Hardware read watchpoint \[0-9\]+: aligned.var4" { -+ pass $gdb_test_name -+ } -+ -re -wrap "Target does not support this type of hardware watchpoint\\." { -+ set supported 0 -+ } -+} -+ -+if { !$supported } { -+ unsupported $test - return - } --gdb_test $test "Hardware read watchpoint \[0-9\]+: aligned.var4" -+ - - proc checkvar { address } { - global gdb_prompt --- -2.35.3 - diff --git a/fixup-gdb-test-bt-cfi-without-die.patch b/fixup-gdb-test-bt-cfi-without-die.patch deleted file mode 100644 index f68da30..0000000 --- a/fixup-gdb-test-bt-cfi-without-die.patch +++ /dev/null @@ -1,38 +0,0 @@ -fixup-gdb-test-bt-cfi-without-die.patch - ---- - gdb/testsuite/gdb.base/cfi-without-die.exp | 13 ++++++++----- - 1 file changed, 8 insertions(+), 5 deletions(-) - -diff --git a/gdb/testsuite/gdb.base/cfi-without-die.exp b/gdb/testsuite/gdb.base/cfi-without-die.exp -index 5880d46f6d2..db1726646f8 100644 ---- a/gdb/testsuite/gdb.base/cfi-without-die.exp -+++ b/gdb/testsuite/gdb.base/cfi-without-die.exp -@@ -37,19 +37,22 @@ if ![runto callback] then { - fail "verify unwinding: Can't run to callback" - return 0 - } --set test "verify unwinding breaks without CFI" --gdb_test_multiple "bt" $test { -+ -+set as_expected 1 -+gdb_test_multiple "bt" "" { - -re " in \[?\]\[?\] .*\r\n$gdb_prompt $" { - # It may backtrace through some random frames even to main(). -- pass $test - } - -re " in main .*\r\n$gdb_prompt $" { -- fail $test -+ set as_expected 0 - } - -re "\r\n$gdb_prompt $" { -- pass $test - } - } -+if { ! $as_expected } { -+ untested ${testfile}.exp -+ return -1 -+} - - if { [gdb_compile "${srcdir}/${subdir}/${srccallerfile}" ${objcallerfile} \ - object [list {additional_flags=-fomit-frame-pointer -funwind-tables -fasynchronous-unwind-tables}]] != "" diff --git a/fixup-gdb-test-dw2-aranges.patch b/fixup-gdb-test-dw2-aranges.patch deleted file mode 100644 index 6438276..0000000 --- a/fixup-gdb-test-dw2-aranges.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 81a7585502092b3c133534ac6ecb34fd56d05337 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Thu, 16 Feb 2023 12:56:41 +0100 -Subject: [PATCH 09/11] fixup gdb-test-dw2-aranges.patch - ---- - gdb/testsuite/gdb.dwarf2/dw2-aranges.S | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-aranges.S b/gdb/testsuite/gdb.dwarf2/dw2-aranges.S -index d5b9ca5a3c6..b811f6644cb 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-aranges.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-aranges.S -@@ -138,3 +138,4 @@ main: - .byte 0 /* aranges segment_size */ - - .Laranges_end: -+ .section .note.GNU-stack,"",@progbits --- -2.35.3 - diff --git a/fixup-powerpc-and-aarch64-fix-reverse-stepping-failu.patch b/fixup-powerpc-and-aarch64-fix-reverse-stepping-failu.patch deleted file mode 100644 index 5be4f5e..0000000 --- a/fixup-powerpc-and-aarch64-fix-reverse-stepping-failu.patch +++ /dev/null @@ -1,70 +0,0 @@ -From d60b57fe1a98094a7e4f19481193b2b5a9bb1e57 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Thu, 2 May 2024 12:02:50 +0200 -Subject: [PATCH 079/147] fixup PowerPC and aarch64: Fix reverse stepping - failure - ---- - gdb/infrun.c | 2 +- - gdb/symtab.c | 3 +-- - gdb/symtab.h | 3 +-- - 3 files changed, 3 insertions(+), 5 deletions(-) - -diff --git a/gdb/infrun.c b/gdb/infrun.c -index 069ef144a76..7be98cfc252 100644 ---- a/gdb/infrun.c -+++ b/gdb/infrun.c -@@ -6897,7 +6897,7 @@ update_line_range_start (CORE_ADDR pc, struct execution_control_state *ecs) - Given the PC, check the line table and return the PC that corresponds - to the line table entry for the source line that PC is in. */ - CORE_ADDR start_line_pc = ecs->event_thread->control.step_range_start; -- std::optional real_range_start; -+ gdb::optional real_range_start; - - /* Call find_line_range_start to get the smallest address in the - linetable for multiple Line X entries in the line table. */ -diff --git a/gdb/symtab.c b/gdb/symtab.c -index ef63ec93c5a..9a47796e5e0 100644 ---- a/gdb/symtab.c -+++ b/gdb/symtab.c -@@ -73,7 +73,6 @@ - #include "gdbsupport/gdb_string_view.h" - #include "gdbsupport/pathstuff.h" - #include "gdbsupport/common-utils.h" --#include - - /* Forward declarations for local functions. */ - -@@ -3328,7 +3327,7 @@ sal_line_symtab_matches_p (const symtab_and_line &sal1, - - /* See symtah.h. */ - --std::optional -+gdb::optional - find_line_range_start (CORE_ADDR pc) - { - struct symtab_and_line current_sal = find_pc_line (pc, 0); -diff --git a/gdb/symtab.h b/gdb/symtab.h -index e17d15c595b..6a611d42880 100644 ---- a/gdb/symtab.h -+++ b/gdb/symtab.h -@@ -38,7 +38,6 @@ - #include "gdb-demangle.h" - #include "split-name.h" - #include "frame.h" --#include - - /* Opaque declarations. */ - struct ui_file; -@@ -2377,7 +2376,7 @@ extern struct symtab_and_line find_pc_sect_line (CORE_ADDR, - the starting PC of line X, and the ranges are contiguous. - */ - --extern std::optional find_line_range_start (CORE_ADDR pc); -+extern gdb::optional find_line_range_start (CORE_ADDR pc); - - /* Wrapper around find_pc_line to just return the symtab. */ - --- -2.35.3 - diff --git a/fixup-skip-tests.patch b/fixup-skip-tests.patch deleted file mode 100644 index 550d1d0..0000000 --- a/fixup-skip-tests.patch +++ /dev/null @@ -1,101 +0,0 @@ -From c1da0d6449415cc1fe6f863526735e4325b0b3ac Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Wed, 1 May 2024 12:43:41 +0200 -Subject: [PATCH 1/2] fixup-skip-tests - ---- - gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp | 4 +--- - gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp | 4 +--- - gdb/testsuite/gdb.cp/cxxexec.exp | 2 +- - .../py-gdb-rhbz1007614-memleak-infpy_read_memory.exp | 4 ++-- - gdb/testsuite/gdb.python/rh634108-solib_address.exp | 6 +++--- - 5 files changed, 8 insertions(+), 12 deletions(-) - -diff --git a/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp -index 0c46489f315..5879319f27c 100644 ---- a/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp -+++ b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp -@@ -13,9 +13,7 @@ - # You should have received a copy of the GNU General Public License - # along with this program. If not, see . - --if {[skip_shlib_tests]} { -- return 0 --} -+require allow_shlib_tests - - set testfile "gcore-buildid-exec-but-not-solib" - set srcmainfile ${testfile}-main.c -diff --git a/gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp b/gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp -index 052bd84d420..73a9bb64903 100644 ---- a/gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp -+++ b/gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp -@@ -17,9 +17,7 @@ - # invalid IFUNC DW_AT_linkage_name: memmove strstr time - # http://sourceware.org/bugzilla/show_bug.cgi?id=14166 - --if {[skip_shlib_tests]} { -- return 0 --} -+require allow_shlib_tests - - set testfile "gnu-ifunc-strstr-workaround" - set executable ${testfile} -diff --git a/gdb/testsuite/gdb.cp/cxxexec.exp b/gdb/testsuite/gdb.cp/cxxexec.exp -index 77c85587407..089a679a1a9 100644 ---- a/gdb/testsuite/gdb.cp/cxxexec.exp -+++ b/gdb/testsuite/gdb.cp/cxxexec.exp -@@ -13,7 +13,7 @@ - # You should have received a copy of the GNU General Public License - # along with this program. If not, see . - --if { [skip_cplus_tests] } { continue } -+require allow_cplus_tests - - set testfile cxxexec - if { [prepare_for_testing ${testfile}.exp ${testfile} ${testfile}.cc {c++ debug}] } { -diff --git a/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.exp b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.exp -index 2e6786d499a..d2693cfef1d 100644 ---- a/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.exp -+++ b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.exp -@@ -13,6 +13,8 @@ - # You should have received a copy of the GNU General Public License - # along with this program. If not, see . - -+require allow_python_tests -+ - set testfile py-gdb-rhbz1007614-memleak-infpy_read_memory - set srcfile ${testfile}.c - set binfile [standard_output_file ${testfile}] -@@ -21,8 +23,6 @@ if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } { - return -1 - } - --if { [skip_python_tests] } { continue } -- - set pid_of_gdb [exp_pid -i [board_info host fileid]] - - proc memory_v_pages_get {} { -diff --git a/gdb/testsuite/gdb.python/rh634108-solib_address.exp b/gdb/testsuite/gdb.python/rh634108-solib_address.exp -index ebf00babc34..2d950b79951 100644 ---- a/gdb/testsuite/gdb.python/rh634108-solib_address.exp -+++ b/gdb/testsuite/gdb.python/rh634108-solib_address.exp -@@ -15,10 +15,10 @@ - - # https://bugzilla.redhat.com/show_bug.cgi?id=634108 - -+# Skip all tests if Python scripting is not enabled. -+require allow_python_tests -+ - gdb_exit - gdb_start - --# Skip all tests if Python scripting is not enabled. --if { [skip_python_tests] } { continue } -- - gdb_test "python print (gdb.solib_name(0))" "None" "gdb.solib_name exists" - -base-commit: 50ee7556c2430effed45ca542852f36368336dce --- -2.35.3 - diff --git a/gdb-14.2.tar.bz2 b/gdb-14.2.tar.bz2 deleted file mode 100644 index 793e37f..0000000 --- a/gdb-14.2.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8b47e772a5ab32185263ef36fc3c185df01e90deb63198d7deba550685864fa9 -size 32117643 diff --git a/gdb-15.2.tar.bz2 b/gdb-15.2.tar.bz2 new file mode 100644 index 0000000..6bcc2a0 --- /dev/null +++ b/gdb-15.2.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:843d09d5a24cbf7b75ee26016ba7f5428b35172e4479fcdbeb55f49e19443b5d +size 32259376 diff --git a/gdb-6.3-attach-see-vdso-test.patch b/gdb-6.3-attach-see-vdso-test.patch deleted file mode 100644 index 5321c5f..0000000 --- a/gdb-6.3-attach-see-vdso-test.patch +++ /dev/null @@ -1,120 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Fedora GDB patches -Date: Fri, 27 Oct 2017 21:07:50 +0200 -Subject: gdb-6.3-attach-see-vdso-test.patch - -;; Test kernel VDSO decoding while attaching to an i386 process. -;;=fedoratest - -diff --git a/gdb/testsuite/gdb.base/attach-see-vdso.c b/gdb/testsuite/gdb.base/attach-see-vdso.c -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.base/attach-see-vdso.c -@@ -0,0 +1,25 @@ -+/* This testcase is part of GDB, the GNU debugger. -+ -+ Copyright 2007 Free Software Foundation, Inc. -+ -+ 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 2 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -+ -+#include -+ -+int main () -+{ -+ pause (); -+ return 1; -+} -diff --git a/gdb/testsuite/gdb.base/attach-see-vdso.exp b/gdb/testsuite/gdb.base/attach-see-vdso.exp -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.base/attach-see-vdso.exp -@@ -0,0 +1,77 @@ -+# Copyright 2007 -+ -+# 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 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ -+# This file was created by Jan Kratochvil . -+ -+# This test only works on Linux -+if { ![istarget "*-*-linux-gnu*"] } { -+ return 0 -+} -+ -+if {[use_gdb_stub]} { -+ untested "skipping test because of use_gdb_stub" -+ return -1 -+} -+ -+set testfile "attach-see-vdso" -+set srcfile ${testfile}.c -+set binfile [standard_output_file ${testfile}] -+set escapedbinfile [string_to_regexp [standard_output_file ${testfile}]] -+ -+# The kernel VDSO is used for the syscalls returns only on i386 (not x86_64). -+# -+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-m32}] != "" } { -+ gdb_suppress_entire_file "Testcase nonthraded compile failed, so all tests in this file will automatically fail." -+} -+ -+if [get_compiler_info ${binfile}] { -+ return -1 -+} -+ -+# Start the program running and then wait for a bit, to be sure -+# that it can be attached to. -+ -+set testpid [eval exec $binfile &] -+ -+# Avoid some race: -+sleep 2 -+ -+# Start with clean gdb -+gdb_exit -+gdb_start -+gdb_reinitialize_dir $srcdir/$subdir -+# Never call: gdb_load ${binfile} -+# as the former problem would not reproduce otherwise. -+ -+set test "attach" -+gdb_test_multiple "attach $testpid" "$test" { -+ -re "Attaching to process $testpid\r?\n.*$gdb_prompt $" { -+ pass "$test" -+ } -+} -+ -+gdb_test "bt" "#0 *0x\[0-9a-f\]* in \[^?\].*" "backtrace decodes VDSO" -+ -+# Exit and detach the process. -+ -+gdb_exit -+ -+# Make sure we don't leave a process around to confuse -+# the next test run (and prevent the compile by keeping -+# the text file busy), in case the "set should_exit" didn't -+# work. -+ -+remote_exec build "kill -9 ${testpid}" diff --git a/gdb-6.3-gstack-20050411.patch b/gdb-6.3-gstack-20050411.patch index c2e49ec..667aef1 100644 --- a/gdb-6.3-gstack-20050411.patch +++ b/gdb-6.3-gstack-20050411.patch @@ -16,7 +16,7 @@ Subject: gdb-6.3-gstack-20050411.patch diff --git a/gdb/Makefile.in b/gdb/Makefile.in --- a/gdb/Makefile.in +++ b/gdb/Makefile.in -@@ -2035,7 +2035,7 @@ info install-info clean-info dvi pdf install-pdf html install-html: force +@@ -2071,7 +2071,7 @@ info install-info clean-info dvi install-dvi pdf install-pdf html install-html: install: all @$(MAKE) $(FLAGS_TO_PASS) install-only @@ -25,7 +25,7 @@ diff --git a/gdb/Makefile.in b/gdb/Makefile.in transformed_name=`t='$(program_transform_name)'; \ echo gdb | sed -e "$$t"` ; \ if test "x$$transformed_name" = x; then \ -@@ -2085,7 +2085,25 @@ install-guile: +@@ -2121,7 +2121,25 @@ install-guile: install-python: $(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(GDB_DATADIR)/python/gdb @@ -52,7 +52,7 @@ diff --git a/gdb/Makefile.in b/gdb/Makefile.in transformed_name=`t='$(program_transform_name)'; \ echo gdb | sed -e $$t` ; \ if test "x$$transformed_name" = x; then \ -@@ -2116,6 +2134,18 @@ uninstall: force $(CONFIG_UNINSTALL) +@@ -2152,6 +2170,28 @@ uninstall: force $(CONFIG_UNINSTALL) rm -f $(DESTDIR)$(bindir)/$$transformed_name @$(MAKE) DO=uninstall "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) subdir_do @@ -68,9 +68,19 @@ diff --git a/gdb/Makefile.in b/gdb/Makefile.in + rm -f $(DESTDIR)$(bindir)/$$transformed_name$(EXEEXT) \ + $(DESTDIR)$(man1dir)/$$transformed_name.1 + - # The C++ name parser can be built standalone for testing. - test-cp-name-parser.o: cp-name-parser.c - $(COMPILE) -DTEST_CPNAMES cp-name-parser.c ++# The C++ name parser can be built standalone for testing. ++test-cp-name-parser.o: cp-name-parser.c ++ $(COMPILE) -DTEST_CPNAMES cp-name-parser.c ++ $(POSTCOMPILE) ++ ++test-cp-name-parser$(EXEEXT): test-cp-name-parser.o $(LIBIBERTY) ++ $(ECHO_CXXLD) $(CC_LD) $(INTERNAL_LDFLAGS) \ ++ -o test-cp-name-parser$(EXEEXT) test-cp-name-parser.o \ ++ $(LIBIBERTY) ++ + # We do this by grepping through sources. If that turns out to be too slow, + # maybe we could just require every .o file to have an initialization routine + # of a given name (top.o -> _initialize_top, etc.). diff --git a/gdb/gstack.sh b/gdb/gstack.sh new file mode 100644 --- /dev/null @@ -226,7 +236,7 @@ new file mode 100644 +# exiting the function. Still we could retry the gstack command if we fail. + +set test "spawn gstack" -+set command "sh -c GDB=$GDB\\ GDBARGS=-data-directory\\\\\\ $BUILD_DATA_DIRECTORY\\ sh\\ ${srcdir}/../gstack.sh\\ $pid\\;echo\\ GSTACK-END" ++set command "sh -c GDB=$GDB\\ GDBARGS=-data-directory\\\\\\ $GDB_DATA_DIRECTORY\\ sh\\ ${srcdir}/../gstack.sh\\ $pid\\;echo\\ GSTACK-END" +set res [remote_spawn host $command]; +if { $res < 0 || $res == "" } { + perror "Spawning $command failed." diff --git a/gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch b/gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch deleted file mode 100644 index e5b6da9..0000000 --- a/gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch +++ /dev/null @@ -1,265 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Jan Kratochvil -Date: Fri, 27 Oct 2017 21:07:50 +0200 -Subject: gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch - -;; Support TLS symbols (+`errno' suggestion if no pthread is found) (BZ 185337). -;;=push+jan: It should be replaced by Infinity project. - -https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=185337 - -2008-02-24 Jan Kratochvil - - Port to GDB-6.8pre. - -currently for trivial nonthreaded helloworld with no debug info up to -ggdb2 you -will get: - (gdb) p errno - [some error] - -* with -ggdb2 and less "errno" in fact does not exist anywhere as it was - compiled to "(*__errno_location ())" and the macro definition is not present. - Unfortunately gdb will find the TLS symbol and it will try to access it but - as the program has been compiled without -lpthread the TLS base register - (%gs on i386) is not setup and it will result in: - Cannot access memory at address 0x8 - -Attached suggestion patch how to deal with the most common "errno" symbol -for the most common under-ggdb3 compiled programs. - -Original patch hooked into target_translate_tls_address. But its inferior -call invalidates `struct frame *' in the callers - RH BZ 690908. - -https://bugzilla.redhat.com/show_bug.cgi?id=1166549 - -2007-11-03 Jan Kratochvil - - * ./gdb/dwarf2read.c (read_partial_die, dwarf2_linkage_name): Prefer - DW_AT_MIPS_linkage_name over DW_AT_name now only for non-C. - -glibc-debuginfo-2.7-2.x86_64: /usr/lib/debug/lib64/libc.so.6.debug: - <81a2> DW_AT_name : (indirect string, offset: 0x280e): __errno_location - <81a8> DW_AT_MIPS_linkage_name: (indirect string, offset: 0x2808): *__GI___errno_location - -diff --git a/gdb/printcmd.c b/gdb/printcmd.c ---- a/gdb/printcmd.c -+++ b/gdb/printcmd.c -@@ -1308,6 +1308,11 @@ process_print_command_args (const char *args, value_print_options *print_opts, - - if (exp != nullptr && *exp) - { -+ /* '*((int *(*) (void)) __errno_location) ()' is incompatible with -+ function descriptors. */ -+ if (target_has_execution () && strcmp (exp, "errno") == 0) -+ exp = "*(*(int *(*)(void)) __errno_location) ()"; -+ - /* This setting allows large arrays to be printed by limiting the - number of elements that are loaded into GDB's memory; we only - need to load as many array elements as we plan to print. */ -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-errno.c b/gdb/testsuite/gdb.dwarf2/dw2-errno.c -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.dwarf2/dw2-errno.c -@@ -0,0 +1,28 @@ -+/* This testcase is part of GDB, the GNU debugger. -+ -+ Copyright 2005, 2007 Free Software Foundation, Inc. -+ -+ 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 . -+ -+ Please email any bugs, comments, and/or additions to this file to: -+ bug-gdb@prep.ai.mit.edu */ -+ -+#include -+ -+int main() -+{ -+ errno = 42; -+ -+ return 0; /* breakpoint */ -+} -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-errno.exp b/gdb/testsuite/gdb.dwarf2/dw2-errno.exp -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.dwarf2/dw2-errno.exp -@@ -0,0 +1,60 @@ -+# Copyright 2007 Free Software Foundation, Inc. -+ -+# 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 . -+ -+set testfile dw2-errno -+set srcfile ${testfile}.c -+set binfile [standard_output_file ${testfile}] -+ -+proc prep {} { -+ global srcdir subdir binfile -+ gdb_exit -+ gdb_start -+ gdb_reinitialize_dir $srcdir/$subdir -+ gdb_load ${binfile} -+ -+ runto_main -+ -+ gdb_breakpoint [gdb_get_line_number "breakpoint"] -+ gdb_continue_to_breakpoint "breakpoint" -+} -+ -+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "additional_flags=-g2"] != "" } { -+ untested "Couldn't compile test program" -+ return -1 -+} -+prep -+gdb_test "print errno" ".* = 42" "errno with macros=N threads=N" -+ -+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "additional_flags=-g3"] != "" } { -+ untested "Couldn't compile test program" -+ return -1 -+} -+prep -+gdb_test "print errno" ".* = 42" "errno with macros=Y threads=N" -+ -+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "additional_flags=-g2"] != "" } { -+ return -1 -+} -+prep -+gdb_test "print errno" ".* = 42" "errno with macros=N threads=Y" -+ -+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "additional_flags=-g3"] != "" } { -+ return -1 -+} -+prep -+gdb_test "print errno" ".* = 42" "errno with macros=Y threads=Y" -+ -+# TODO: Test the error on resolving ERRNO with only libc loaded. -+# Just how to find the current libc filename? -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-errno2.c b/gdb/testsuite/gdb.dwarf2/dw2-errno2.c -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.dwarf2/dw2-errno2.c -@@ -0,0 +1,28 @@ -+/* This testcase is part of GDB, the GNU debugger. -+ -+ Copyright 2005, 2007 Free Software Foundation, Inc. -+ -+ 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 . -+ -+ Please email any bugs, comments, and/or additions to this file to: -+ bug-gdb@prep.ai.mit.edu */ -+ -+#include -+ -+int main() -+{ -+ errno = 42; -+ -+ return 0; /* breakpoint */ -+} -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-errno2.exp b/gdb/testsuite/gdb.dwarf2/dw2-errno2.exp -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.dwarf2/dw2-errno2.exp -@@ -0,0 +1,71 @@ -+# Copyright 2007 Free Software Foundation, Inc. -+ -+# 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 . -+ -+set testfile dw2-errno2 -+set srcfile ${testfile}.c -+set binfile [standard_output_file ${testfile}] -+ -+proc prep { message {do_xfail 0} } { with_test_prefix $message { -+ global srcdir subdir binfile variant -+ gdb_exit -+ gdb_start -+ gdb_reinitialize_dir $srcdir/$subdir -+ gdb_load ${binfile}${variant} -+ -+ runto_main -+ -+ gdb_breakpoint [gdb_get_line_number "breakpoint"] -+ gdb_continue_to_breakpoint "breakpoint" -+ -+ gdb_test "gcore ${binfile}${variant}.core" "\r\nSaved corefile .*" "gcore $variant" -+ -+ gdb_test "print errno" ".* = 42" -+ -+ gdb_test "kill" ".*" "kill" {Kill the program being debugged\? \(y or n\) } "y" -+ gdb_test "core-file ${binfile}${variant}.core" "\r\nCore was generated by .*" "core-file" -+ if $do_xfail { -+ setup_xfail "*-*-*" -+ } -+ gdb_test "print (int) errno" ".* = 42" "print errno for core" -+}} -+ -+set variant g2thrN -+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}${variant}" executable "additional_flags=-g2"] != "" } { -+ untested "Couldn't compile test program" -+ return -1 -+} -+prep "macros=N threads=N" 1 -+ -+set variant g3thrN -+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}${variant}" executable "additional_flags=-g3"] != "" } { -+ untested "Couldn't compile test program" -+ return -1 -+} -+prep "macros=Y threads=N" 1 -+ -+set variant g2thrY -+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}${variant}" executable "additional_flags=-g2"] != "" } { -+ return -1 -+} -+prep "macros=N threads=Y" -+ -+set variant g3thrY -+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}${variant}" executable "additional_flags=-g3"] != "" } { -+ return -1 -+} -+prep "macros=Y threads=Y" 1 -+ -+# TODO: Test the error on resolving ERRNO with only libc loaded. -+# Just how to find the current libc filename? diff --git a/gdb-6.5-bz243845-stale-testing-zombie-test.patch b/gdb-6.5-bz243845-stale-testing-zombie-test.patch deleted file mode 100644 index 77d274a..0000000 --- a/gdb-6.5-bz243845-stale-testing-zombie-test.patch +++ /dev/null @@ -1,89 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Fedora GDB patches -Date: Fri, 27 Oct 2017 21:07:50 +0200 -Subject: gdb-6.5-bz243845-stale-testing-zombie-test.patch - -;; Test leftover zombie process (BZ 243845). -;;=fedoratest - -diff --git a/gdb/testsuite/gdb.base/tracefork-zombie.exp b/gdb/testsuite/gdb.base/tracefork-zombie.exp -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.base/tracefork-zombie.exp -@@ -0,0 +1,76 @@ -+# Copyright 2007 Free Software Foundation, Inc. -+ -+# 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 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -+ -+# are we on a target board -+if {[use_gdb_stub]} { -+ untested "skipping test because of use_gdb_stub" -+ return -1 -+} -+ -+# Start the program running and then wait for a bit, to be sure -+# that it can be attached to. -+ -+gdb_exit -+gdb_start -+gdb_load sleep -+ -+set gdb_pid [exp_pid -i [board_info host fileid]] -+set test "identified the child GDB" -+if {$gdb_pid != "" && $gdb_pid > 0} { -+ pass $test -+ verbose -log "Child GDB PID $gdb_pid" -+} else { -+ fail $test -+} -+ -+set testpid [eval exec sleep 10 &] -+exec sleep 2 -+ -+set test "attach" -+gdb_test_multiple "attach $testpid" "$test" { -+ -re "Attaching to program.*`?.*'?, process $testpid..*$gdb_prompt $" { -+ pass "$test" -+ } -+ -re "Attaching to program.*`?.*\.exe'?, process $testpid.*\[Switching to thread $testpid\..*\].*$gdb_prompt $" { -+ # Response expected on Cygwin -+ pass "$test" -+ } -+} -+ -+# Some time to let GDB spawn its testing child. -+exec sleep 2 -+ -+set found none -+foreach procpid [glob -directory /proc -type d {[0-9]*}] { -+ if {[catch {open $procpid/status} statusfi]} { -+ continue -+ } -+ set status [read $statusfi] -+ close $statusfi -+ if {1 -+ && [regexp -line {^Name:\tgdb$} $status] -+ && [regexp -line {^PPid:\t1$} $status] -+ && [regexp -line "^TracerPid:\t$gdb_pid$" $status]} { -+ set found $procpid -+ verbose -log "Found linux_test_for_tracefork zombie PID $procpid" -+ } -+} -+set test "linux_test_for_tracefork leaves no zombie" -+if {$found eq {none}} { -+ pass $test -+} else { -+ fail $test -+} diff --git a/gdb-6.5-section-num-fixup-test.patch b/gdb-6.5-section-num-fixup-test.patch deleted file mode 100644 index 3382769..0000000 --- a/gdb-6.5-section-num-fixup-test.patch +++ /dev/null @@ -1,127 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Fedora GDB patches -Date: Fri, 27 Oct 2017 21:07:50 +0200 -Subject: gdb-6.5-section-num-fixup-test.patch - -;; Test a crash on libraries missing the .text section. -;;=fedoratest - -diff --git a/gdb/testsuite/gdb.base/datalib-lib.c b/gdb/testsuite/gdb.base/datalib-lib.c -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.base/datalib-lib.c -@@ -0,0 +1,22 @@ -+/* This testcase is part of GDB, the GNU debugger. -+ -+ Copyright 2008 Free Software Foundation, Inc. -+ -+ 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 2 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ -+ Please email any bugs, comments, and/or additions to this file to: -+ bug-gdb@prep.ai.mit.edu */ -+ -+int var; -diff --git a/gdb/testsuite/gdb.base/datalib-main.c b/gdb/testsuite/gdb.base/datalib-main.c -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.base/datalib-main.c -@@ -0,0 +1,26 @@ -+/* This testcase is part of GDB, the GNU debugger. -+ -+ Copyright 2008 Free Software Foundation, Inc. -+ -+ 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 2 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ -+ Please email any bugs, comments, and/or additions to this file to: -+ bug-gdb@prep.ai.mit.edu */ -+ -+int -+main (void) -+{ -+ return 0; -+} -diff --git a/gdb/testsuite/gdb.base/datalib.exp b/gdb/testsuite/gdb.base/datalib.exp -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.base/datalib.exp -@@ -0,0 +1,56 @@ -+# Copyright 2008 Free Software Foundation, Inc. -+ -+# 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 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ -+if {[use_gdb_stub]} { -+ untested "skipping test because of use_gdb_stub" -+ return -1 -+} -+ -+set testfile datalib -+set srcfilemain ${testfile}-main.c -+set srcfilelib ${testfile}-lib.c -+set libfile [standard_output_file ${testfile}-lib.so] -+set binfile [standard_output_file ${testfile}-main] -+if { [gdb_compile "${srcdir}/${subdir}/${srcfilelib}" "${libfile}" executable [list debug {additional_flags=-shared -nostdlib}]] != "" } { -+ untested "Couldn't compile test program" -+ return -1 -+} -+if { [gdb_compile "${srcdir}/${subdir}/${srcfilemain}" "${binfile} ${libfile}" executable {debug}] != "" } { -+ untested "Couldn't compile test program" -+ return -1 -+} -+ -+# Get things started. -+ -+gdb_exit -+gdb_start -+gdb_reinitialize_dir $srcdir/$subdir -+gdb_load ${binfile} -+ -+# We must use a separate library as the main executable is compiled to the -+# address 0 by default and it would get fixed up already at the end of -+# INIT_OBJFILE_SECT_INDICES. We also cannot PRELINK it as PRELINK is missing -+# on ia64. The library must be NOSTDLIB as otherwise some stub code would -+# create the `.text' section there. Also DEBUG option is useful as some of -+# the crashes occur in dwarf2read.c. -+ -+# FAIL case: -+# ../../gdb/ia64-tdep.c:2838: internal-error: sect_index_text not initialized -+# A problem internal to GDB has been detected, -+ -+gdb_test "start" \ -+ "main \\(\\) at .*${srcfilemain}.*" \ -+ "start" diff --git a/gdb-6.6-buildid-locate-rpm-librpm-workaround.patch b/gdb-6.6-buildid-locate-rpm-librpm-workaround.patch deleted file mode 100644 index 52bf236..0000000 --- a/gdb-6.6-buildid-locate-rpm-librpm-workaround.patch +++ /dev/null @@ -1,19 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Fedora GDB patches -Date: Fri, 27 Oct 2017 21:07:50 +0200 -Subject: gdb-6.6-buildid-locate-rpm-librpm-workaround.patch - -;; Workaround librpm BZ 643031 due to its unexpected exit() calls (BZ 642879). -;;=push+jan - -diff --git a/gdb/proc-service.list b/gdb/proc-service.list ---- a/gdb/proc-service.list -+++ b/gdb/proc-service.list -@@ -37,4 +37,7 @@ - ps_pstop; - ps_ptread; - ps_ptwrite; -+ -+ /* gdb-6.6-buildid-locate-rpm.patch */ -+ rpmsqEnable; - }; diff --git a/gdb-6.6-buildid-locate-rpm-suse.patch b/gdb-6.6-buildid-locate-rpm-suse.patch deleted file mode 100644 index 5b9cf7f..0000000 --- a/gdb-6.6-buildid-locate-rpm-suse.patch +++ /dev/null @@ -1,123 +0,0 @@ -diff --git a/gdb/build-id.c b/gdb/build-id.c -index 059a72fc050..58d73e70bad 100644 ---- a/gdb/build-id.c -+++ b/gdb/build-id.c -@@ -863,10 +863,8 @@ missing_rpm_enlist_1 (const char *filename, int verify_vendor) - #endif - { - Header h; -- char *debuginfo, **slot, *s, *s2; -+ char *debuginfo, **slot; - errmsg_t err; -- size_t srcrpmlen = sizeof (".src.rpm") - 1; -- size_t debuginfolen = sizeof ("-debuginfo") - 1; - rpmdbMatchIterator mi_debuginfo; - - h = rpmdbNextIterator_p (mi); -@@ -875,7 +873,9 @@ missing_rpm_enlist_1 (const char *filename, int verify_vendor) - - /* Verify the debuginfo file is not already installed. */ - -- debuginfo = headerFormat_p (h, "%{sourcerpm}-debuginfo.%{arch}", -+ /* The allocated memory gets utilized below for MISSING_RPM_HASH. */ -+ debuginfo = headerFormat_p (h, -+ "%{name}-debuginfo-%{version}-%{release}.%{arch}", - &err); - if (!debuginfo) - { -@@ -883,60 +883,19 @@ missing_rpm_enlist_1 (const char *filename, int verify_vendor) - err); - continue; - } -- /* s = `.src.rpm-debuginfo.%{arch}' */ -- s = strrchr (debuginfo, '-') - srcrpmlen; -- s2 = NULL; -- if (s > debuginfo && memcmp (s, ".src.rpm", srcrpmlen) == 0) -- { -- /* s2 = `-%{release}.src.rpm-debuginfo.%{arch}' */ -- s2 = (char *) memrchr (debuginfo, '-', s - debuginfo); -- } -- if (s2) -- { -- /* s2 = `-%{version}-%{release}.src.rpm-debuginfo.%{arch}' */ -- s2 = (char *) memrchr (debuginfo, '-', s2 - debuginfo); -- } -- if (!s2) -- { -- warning (_("Error querying the rpm file `%s': %s"), filename, -- debuginfo); -- xfree (debuginfo); -- continue; -- } -- /* s = `.src.rpm-debuginfo.%{arch}' */ -- /* s2 = `-%{version}-%{release}.src.rpm-debuginfo.%{arch}' */ -- memmove (s2 + debuginfolen, s2, s - s2); -- memcpy (s2, "-debuginfo", debuginfolen); -- /* s = `XXXX.%{arch}' */ -- /* strlen ("XXXX") == srcrpmlen + debuginfolen */ -- /* s2 = `-debuginfo-%{version}-%{release}XX.%{arch}' */ -- /* strlen ("XX") == srcrpmlen */ -- memmove (s + debuginfolen, s + srcrpmlen + debuginfolen, -- strlen (s + srcrpmlen + debuginfolen) + 1); -- /* s = `-debuginfo-%{version}-%{release}.%{arch}' */ - -+ /* Verify the debuginfo file is not already installed. */ - /* RPMDBI_PACKAGES requires keylen == sizeof (int). */ - /* RPMDBI_LABEL is an interface for NVR-based dbiFindByLabel(). */ - mi_debuginfo = rpmtsInitIterator_p (ts, (rpmDbiTagVal) RPMDBI_LABEL, debuginfo, 0); -- xfree (debuginfo); - if (mi_debuginfo) - { -+ xfree (debuginfo); - rpmdbFreeIterator_p (mi_debuginfo); - count = 0; - break; - } - -- /* The allocated memory gets utilized below for MISSING_RPM_HASH. */ -- debuginfo = headerFormat_p (h, -- "%{name}-%{version}-%{release}.%{arch}", -- &err); -- if (!debuginfo) -- { -- warning (_("Error querying the rpm file `%s': %s"), filename, -- err); -- continue; -- } -- - /* Base package name for `debuginfo-install'. We do not use the - `yum' command directly as the line - yum --enablerepo='*debug*' install NAME-debuginfo.ARCH -@@ -1085,10 +1044,7 @@ missing_rpm_list_print (void) - missing_rpm_list_entries = 0; - - gdb_printf (_("Missing separate debuginfos, use: %s"), --#ifdef DNF_DEBUGINFO_INSTALL -- "dnf " --#endif -- "debuginfo-install"); -+ "zypper install"); - for (const char *el : array) - { - gdb_printf (" %s", el); -@@ -1296,14 +1252,15 @@ debug_print_missing (const char *binary, const char *debug) - _("Missing separate debuginfo for %s.\n"), binary); - if (debug != NULL) - { -+#ifdef HAVE_LIBRPM - if (access (debug, F_OK) == 0) { -- gdb_printf (gdb_stdlog, _("Try: %s %s\n"), --#ifdef DNF_DEBUGINFO_INSTALL -- "dnf" - #else -- "yum" -+ if (1) { - #endif -- " --enablerepo='*debug*' install", debug); -+ const char *p = strrchr (debug, '/'); -+ gdb_printf (gdb_stdlog, _("Try: %s%.2s%.38s\"\n"), -+ "zypper install -C \"debuginfo(build-id)=", -+ p - 2, p + 1); - } else - gdb_printf (gdb_stdlog, _("The debuginfo package for this file is probably broken.\n")); - } diff --git a/gdb-6.6-buildid-locate-rpm.patch b/gdb-6.6-buildid-locate-rpm.patch deleted file mode 100644 index b38b945..0000000 --- a/gdb-6.6-buildid-locate-rpm.patch +++ /dev/null @@ -1,1084 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Kevin Buettner -Date: Wed, 22 Feb 2023 22:30:40 -0700 -Subject: gdb-6.6-buildid-locate-rpm.patch - -;;=push+jan - -diff --git a/gdb/aclocal.m4 b/gdb/aclocal.m4 ---- a/gdb/aclocal.m4 -+++ b/gdb/aclocal.m4 -@@ -11,7 +11,223 @@ - # even the implied warranty of MERCHANTABILITY or FITNESS FOR A - # PARTICULAR PURPOSE. - -+# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -+# serial 1 (pkg-config-0.24) -+# -+# Copyright © 2004 Scott James Remnant . -+# -+# 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 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, but -+# WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+# General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+# -+# As a special exception to the GNU General Public License, if you -+# distribute this file as part of a program that contains a -+# configuration script generated by Autoconf, you may include it under -+# the same distribution terms that you use for the rest of that program. -+ -+# PKG_PROG_PKG_CONFIG([MIN-VERSION]) -+# ---------------------------------- -+AC_DEFUN([PKG_PROG_PKG_CONFIG], -+[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) -+m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) -+m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) -+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) -+AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) -+AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) -+ -+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then -+ AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) -+fi -+if test -n "$PKG_CONFIG"; then -+ _pkg_min_version=m4_default([$1], [0.9.0]) -+ AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) -+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then -+ AC_MSG_RESULT([yes]) -+ else -+ AC_MSG_RESULT([no]) -+ PKG_CONFIG="" -+ fi -+fi[]dnl -+])# PKG_PROG_PKG_CONFIG -+ -+# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -+# -+# Check to see whether a particular set of modules exists. Similar -+# to PKG_CHECK_MODULES(), but does not set variables or print errors. -+# -+# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -+# only at the first occurence in configure.ac, so if the first place -+# it's called might be skipped (such as if it is within an "if", you -+# have to call PKG_CHECK_EXISTS manually -+# -------------------------------------------------------------- -+AC_DEFUN([PKG_CHECK_EXISTS], -+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -+if test -n "$PKG_CONFIG" && \ -+ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then -+ m4_default([$2], [:]) -+m4_ifvaln([$3], [else -+ $3])dnl -+fi]) -+ -+# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) -+# --------------------------------------------- -+m4_define([_PKG_CONFIG], -+[if test -n "$$1"; then -+ pkg_cv_[]$1="$$1" -+ elif test -n "$PKG_CONFIG"; then -+ PKG_CHECK_EXISTS([$3], -+ [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` -+ test "x$?" != "x0" && pkg_failed=yes ], -+ [pkg_failed=yes]) -+ else -+ pkg_failed=untried -+fi[]dnl -+])# _PKG_CONFIG -+ -+# _PKG_SHORT_ERRORS_SUPPORTED -+# ----------------------------- -+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], -+[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then -+ _pkg_short_errors_supported=yes -+else -+ _pkg_short_errors_supported=no -+fi[]dnl -+])# _PKG_SHORT_ERRORS_SUPPORTED -+ -+ -+# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], -+# [ACTION-IF-NOT-FOUND]) -+# -+# -+# Note that if there is a possibility the first call to -+# PKG_CHECK_MODULES might not happen, you should be sure to include an -+# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac -+# -+# -+# -------------------------------------------------------------- -+AC_DEFUN([PKG_CHECK_MODULES], -+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl -+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl -+ -+pkg_failed=no -+AC_MSG_CHECKING([for $1]) -+ -+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) -+_PKG_CONFIG([$1][_LIBS], [libs], [$2]) -+ -+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS -+and $1[]_LIBS to avoid the need to call pkg-config. -+See the pkg-config man page for more details.]) -+ -+if test $pkg_failed = yes; then -+ AC_MSG_RESULT([no]) -+ _PKG_SHORT_ERRORS_SUPPORTED -+ if test $_pkg_short_errors_supported = yes; then -+ $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` -+ else -+ $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` -+ fi -+ # Put the nasty error message in config.log where it belongs -+ echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD -+ -+ m4_default([$4], [AC_MSG_ERROR( -+[Package requirements ($2) were not met: -+ -+$$1_PKG_ERRORS -+ -+Consider adjusting the PKG_CONFIG_PATH environment variable if you -+installed software in a non-standard prefix. -+ -+_PKG_TEXT])[]dnl -+ ]) -+elif test $pkg_failed = untried; then -+ AC_MSG_RESULT([no]) -+ m4_default([$4], [AC_MSG_FAILURE( -+[The pkg-config script could not be found or is too old. Make sure it -+is in your PATH or set the PKG_CONFIG environment variable to the full -+path to pkg-config. -+ -+_PKG_TEXT -+ -+To get pkg-config, see .])[]dnl -+ ]) -+else -+ $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS -+ $1[]_LIBS=$pkg_cv_[]$1[]_LIBS -+ AC_MSG_RESULT([yes]) -+ $3 -+fi[]dnl -+])# PKG_CHECK_MODULES -+ -+ -+# PKG_INSTALLDIR(DIRECTORY) -+# ------------------------- -+# Substitutes the variable pkgconfigdir as the location where a module -+# should install pkg-config .pc files. By default the directory is -+# $libdir/pkgconfig, but the default can be changed by passing -+# DIRECTORY. The user can override through the --with-pkgconfigdir -+# parameter. -+AC_DEFUN([PKG_INSTALLDIR], -+[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) -+m4_pushdef([pkg_description], -+ [pkg-config installation directory @<:@]pkg_default[@:>@]) -+AC_ARG_WITH([pkgconfigdir], -+ [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, -+ [with_pkgconfigdir=]pkg_default) -+AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) -+m4_popdef([pkg_default]) -+m4_popdef([pkg_description]) -+]) dnl PKG_INSTALLDIR -+ -+ -+# PKG_NOARCH_INSTALLDIR(DIRECTORY) -+# ------------------------- -+# Substitutes the variable noarch_pkgconfigdir as the location where a -+# module should install arch-independent pkg-config .pc files. By -+# default the directory is $datadir/pkgconfig, but the default can be -+# changed by passing DIRECTORY. The user can override through the -+# --with-noarch-pkgconfigdir parameter. -+AC_DEFUN([PKG_NOARCH_INSTALLDIR], -+[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) -+m4_pushdef([pkg_description], -+ [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) -+AC_ARG_WITH([noarch-pkgconfigdir], -+ [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, -+ [with_noarch_pkgconfigdir=]pkg_default) -+AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) -+m4_popdef([pkg_default]) -+m4_popdef([pkg_description]) -+]) dnl PKG_NOARCH_INSTALLDIR -+ -+ -+# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, -+# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -+# ------------------------------------------- -+# Retrieves the value of the pkg-config variable for the given module. -+AC_DEFUN([PKG_CHECK_VAR], -+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -+AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl -+ -+_PKG_CONFIG([$1], [variable="][$3]["], [$2]) -+AS_VAR_COPY([$1], [pkg_cv_][$1]) -+ -+AS_VAR_IF([$1], [""], [$5], [$4])dnl -+])# PKG_CHECK_VAR -+ - m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) -+ - # AM_AUX_DIR_EXPAND -*- Autoconf -*- - - # Copyright (C) 2001-2017 Free Software Foundation, Inc. -diff --git a/gdb/build-id.c b/gdb/build-id.c ---- a/gdb/build-id.c -+++ b/gdb/build-id.c -@@ -780,10 +780,10 @@ missing_rpm_enlist_1 (const char *filename, int verify_vendor) - static rpmts (*rpmtsCreate_p) (void); - extern rpmts rpmtsFree(rpmts ts); - static rpmts (*rpmtsFree_p) (rpmts ts); -- extern rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmTag rpmtag, -+ extern rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmDbiTagVal rpmtag, - const void * keyp, size_t keylen); - static rpmdbMatchIterator (*rpmtsInitIterator_p) (const rpmts ts, -- rpmTag rpmtag, -+ rpmDbiTagVal rpmtag, - const void *keyp, - size_t keylen); - #else /* !DLOPEN_LIBRPM */ -@@ -838,7 +838,7 @@ missing_rpm_enlist_1 (const char *filename, int verify_vendor) - && (rpmdbNextIterator_p = (Header (*) (rpmdbMatchIterator mi)) dlsym (h, "rpmdbNextIterator")) - && (rpmtsCreate_p = (rpmts (*) (void)) dlsym (h, "rpmtsCreate")) - && (rpmtsFree_p = (rpmts (*) (rpmts ts)) dlsym (h, "rpmtsFree")) -- && (rpmtsInitIterator_p = (rpmdbMatchIterator (*) (const rpmts ts, rpmTag rpmtag, const void *keyp, size_t keylen)) dlsym (h, "rpmtsInitIterator")))) -+ && (rpmtsInitIterator_p = (rpmdbMatchIterator (*) (const rpmts ts, rpmDbiTagVal rpmtag, const void *keyp, size_t keylen)) dlsym (h, "rpmtsInitIterator")))) - { - warning (_("Opened library \"%s\" is incompatible (%s), " - "missing debuginfos notifications will not be displayed"), -@@ -926,7 +926,7 @@ missing_rpm_enlist_1 (const char *filename, int verify_vendor) - - /* RPMDBI_PACKAGES requires keylen == sizeof (int). */ - /* RPMDBI_LABEL is an interface for NVR-based dbiFindByLabel(). */ -- mi_debuginfo = rpmtsInitIterator_p (ts, (rpmTag) RPMDBI_LABEL, debuginfo, 0); -+ mi_debuginfo = rpmtsInitIterator_p (ts, (rpmDbiTagVal) RPMDBI_LABEL, debuginfo, 0); - xfree (debuginfo); - if (mi_debuginfo) - { -diff --git a/gdb/config.in b/gdb/config.in ---- a/gdb/config.in -+++ b/gdb/config.in -@@ -42,6 +42,9 @@ - /* Handle .ctf type-info sections */ - #undef ENABLE_LIBCTF - -+/* librpm version specific library name to dlopen. */ -+#undef DLOPEN_LIBRPM -+ - /* Define to 1 if translation of program messages to the user's native - language is requested. */ - #undef ENABLE_NLS -@@ -265,6 +268,9 @@ - /* Define to 1 if you have the `m' library (-lm). */ - #undef HAVE_LIBM - -+/* Define if librpm library is being used. */ -+#undef HAVE_LIBRPM -+ - /* Define to 1 if you have the header file. */ - #undef HAVE_LIBUNWIND_IA64_H - -diff --git a/gdb/configure b/gdb/configure ---- a/gdb/configure -+++ b/gdb/configure -@@ -778,6 +778,11 @@ AMD_DBGAPI_CFLAGS - ENABLE_BFD_64_BIT_FALSE - ENABLE_BFD_64_BIT_TRUE - subdirs -+RPM_LIBS -+RPM_CFLAGS -+PKG_CONFIG_LIBDIR -+PKG_CONFIG_PATH -+PKG_CONFIG - GDB_DATADIR - DEBUGDIR - MAKEINFO_EXTRA_FLAGS -@@ -911,6 +916,7 @@ with_gdb_datadir - with_relocated_sources - with_auto_load_dir - with_auto_load_safe_path -+with_rpm - enable_targets - enable_64_bit_bfd - with_amd_dbgapi -@@ -988,6 +994,8 @@ AMD_DBGAPI_CFLAGS - AMD_DBGAPI_LIBS - DEBUGINFOD_CFLAGS - DEBUGINFOD_LIBS -+RPM_CFLAGS -+RPM_LIBS - YACC - YFLAGS - ZSTD_CFLAGS -@@ -1679,6 +1687,8 @@ Optional Packages: - --with-amd-dbgapi support for the amd-dbgapi target (yes / no / auto) - --with-debuginfod Enable debuginfo lookups with debuginfod - (auto/yes/no) -+ --with-rpm query rpm database for missing debuginfos (yes/no, -+ def. auto=librpm.so) - --with-libunwind-ia64 use libunwind frame unwinding for ia64 targets - --with-curses use the curses library instead of the termcap - library -@@ -1759,6 +1769,8 @@ Some influential environment variables: - C compiler flags for DEBUGINFOD, overriding pkg-config - DEBUGINFOD_LIBS - linker flags for DEBUGINFOD, overriding pkg-config -+ RPM_CFLAGS C compiler flags for RPM, overriding pkg-config -+ RPM_LIBS linker flags for RPM, overriding pkg-config - YACC The `Yet Another Compiler Compiler' implementation to use. - Defaults to the first program found out of: `bison -y', `byacc', - `yacc'. -@@ -18039,6 +18051,495 @@ _ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_auto_load_safe_path" >&5 - $as_echo "$with_auto_load_safe_path" >&6; } - -+# Integration with rpm library to support missing debuginfo suggestions. -+# --without-rpm: Disable any rpm support. -+# --with-rpm=libname.so: Try to dynamically open `libname.so' during runtime. -+# Even with runtime missing `libname.so' GDB will still other run correctly. -+# Missing `libname.so' during ./configure will abort the configuration. -+# --with-rpm=librpm.so: Like `--with-rpm=libname.so' but try to find specific -+# minor version first such as `librpm-4.6.so' as minor version differences -+# mean API+ABI incompatibility. If the specific match versioned library name -+# could not be found still open dynamically at least `librpm.so'. -+# --with-rpm: Like `--with-rpm=librpm.so' but if any of its detection fails try -+# to find librpm for compilation-time linking by pkg-config. GDB binary will -+# be probably linked with the version specific library (as `librpm-4.6.so'). -+# Failure to find librpm by pkg-config will abort the configuration. -+# (default) --with-rpm=auto: Like `--with-rpm=librpm.so' but if even pkg-config -+# cannot find librpm use to the rpmless compilation (like `--without-rpm'). -+ -+ -+# Check whether --with-rpm was given. -+if test "${with_rpm+set}" = set; then : -+ withval=$with_rpm; -+else -+ with_rpm="auto" -+fi -+ -+ -+ -+ -+if test "x$with_rpm" != "xno"; then -+ if test "x$with_rpm" = "xyes"; then -+ LIBRPM="librpm.so" -+ RPM_REQUIRE=true -+ DLOPEN_REQUIRE=false -+ elif test "x$with_rpm" = "xauto"; then -+ LIBRPM="librpm.so" -+ RPM_REQUIRE=false -+ DLOPEN_REQUIRE=false -+ else -+ LIBRPM="$with_rpm" -+ RPM_REQUIRE=true -+ DLOPEN_REQUIRE=true -+ fi -+ LIBRPM_STRING='"'"$LIBRPM"'"' -+ -+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking specific librpm version" >&5 -+$as_echo_n "checking specific librpm version... " >&6; } -+ HAVE_DLOPEN_LIBRPM=false -+ save_LIBS="$LIBS" -+ LIBS="$LIBS -ldl" -+ if test "$cross_compiling" = 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 "cannot run test program while cross compiling -+See \`config.log' for more details." "$LINENO" 5; } -+else -+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+ -+#include -+#include -+#include -+#include -+ -+int -+main () -+{ -+ -+ void *h; -+ const char *const *rpmverp; -+ FILE *f; -+ -+ f = fopen ("conftest.out", "w"); -+ if (!f) -+ { -+ fprintf (stderr, "Cannot write \"%s\": %s\n", "conftest.out", -+ strerror (errno)); -+ return 1; -+ } -+ h = dlopen ($LIBRPM_STRING, RTLD_LAZY); -+ if (!h) -+ { -+ fprintf (stderr, "dlopen (\"%s\"): %s\n", $LIBRPM_STRING, dlerror ()); -+ return 1; -+ } -+ rpmverp = dlsym (h, "RPMVERSION"); -+ if (!rpmverp) -+ { -+ fprintf (stderr, "dlsym (\"RPMVERSION\"): %s\n", dlerror ()); -+ return 1; -+ } -+ fprintf (stderr, "RPMVERSION is: \""); -+ fprintf (stderr, "%s\"\n", *rpmverp); -+ -+ /* Try to find the specific librpm version only for "librpm.so" as we do -+ not know how to assemble the version string otherwise. */ -+ -+ if (strcmp ("librpm.so", $LIBRPM_STRING) != 0) -+ { -+ fprintf (f, "%s\n", $LIBRPM_STRING); -+ return 0; -+ } -+ else -+ { -+ char *h2_name; -+ void *h2; -+ int major, minor; -+ -+ if (sscanf (*rpmverp, "%d.%d", &major, &minor) != 2) -+ { -+ fprintf (stderr, "Unable to parse RPMVERSION.\n"); -+ fprintf (f, "%s\n", $LIBRPM_STRING); -+ return 0; -+ } -+ /* Avoid the square brackets by malloc. */ -+ h2_name = malloc (64); -+ sprintf (h2_name, "librpm-%d.%d.so", major, minor); -+ h2 = dlopen (h2_name, RTLD_LAZY); -+ if (!h2) -+ { -+ fprintf (stderr, "dlopen (\"%s\"): %s\n", h2_name, dlerror ()); -+ fprintf (f, "%s\n", $LIBRPM_STRING); -+ return 0; -+ } -+ if (h2 != h) -+ { -+ fprintf (stderr, "dlopen of \"%s\" and \"%s\" are different.\n", -+ $LIBRPM_STRING, h2_name); -+ fprintf (f, "%s\n", $LIBRPM_STRING); -+ return 0; -+ } -+ /* Found the valid .so name with a specific version. */ -+ fprintf (f, "%s\n", h2_name); -+ return 0; -+ } -+ -+ ; -+ return 0; -+} -+_ACEOF -+if ac_fn_c_try_run "$LINENO"; then : -+ -+ DLOPEN_LIBRPM="`cat conftest.out`" -+ if test "x$DLOPEN_LIBRPM" != "x"; then -+ HAVE_DLOPEN_LIBRPM=true -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLOPEN_LIBRPM" >&5 -+$as_echo "$DLOPEN_LIBRPM" >&6; } -+ fi -+ -+fi -+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ -+ conftest.$ac_objext conftest.beam conftest.$ac_ext -+fi -+ -+ rm -f conftest.out -+ -+ -+ -+ if $HAVE_DLOPEN_LIBRPM; then -+ -+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking rpm library API compatibility" >&5 -+$as_echo_n "checking rpm library API compatibility... " >&6; } -+ # The compilation requires -Werror to verify anything. -+ save_CFLAGS="$CFLAGS" -+ CFLAGS="$CFLAGS -Werror" -+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+ -+/* Duplicate here the declarations to verify they match "elfread.c". */ -+#include -+#include -+#include -+#include -+extern char * headerFormat(Header h, const char * fmt, errmsg_t * errmsg); -+extern int rpmReadConfigFiles(const char * file, const char * target); -+extern rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi); -+extern Header rpmdbNextIterator(rpmdbMatchIterator mi); -+extern rpmts rpmtsCreate(void); -+extern rpmts rpmtsFree(rpmts ts); -+extern rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmDbiTagVal rpmtag, -+ const void * keyp, size_t keylen); -+ -+int -+main () -+{ -+ -+ ; -+ return 0; -+} -+_ACEOF -+if ac_fn_c_try_compile "$LINENO"; then : -+ -+ LIBRPM_COMPAT=true -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -+$as_echo "yes" >&6; } -+ -+else -+ -+ LIBRPM_COMPAT=false -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+ -+fi -+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -+ CFLAGS="$save_CFLAGS" -+ -+ if ! $LIBRPM_COMPAT; then -+ HAVE_DLOPEN_LIBRPM=false -+ fi -+ fi -+ -+ if $HAVE_DLOPEN_LIBRPM; then -+ DLOPEN_LIBRPM_STRING='"'"$DLOPEN_LIBRPM"'"' -+ -+cat >>confdefs.h <<_ACEOF -+#define DLOPEN_LIBRPM $DLOPEN_LIBRPM_STRING -+_ACEOF -+ -+ -+$as_echo "#define HAVE_LIBRPM 1" >>confdefs.h -+ -+ else -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+ LIBS="$save_LIBS" -+ if $DLOPEN_REQUIRE; then -+ as_fn_error "Specific name $LIBRPM was requested but it could not be opened." "$LINENO" 5 -+ fi -+ -+ -+ -+ -+ -+ -+ -+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then -+ if test -n "$ac_tool_prefix"; then -+ # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. -+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -+$as_echo_n "checking for $ac_word... " >&6; } -+if test "${ac_cv_path_PKG_CONFIG+set}" = set; then : -+ $as_echo_n "(cached) " >&6 -+else -+ case $PKG_CONFIG in -+ [\\/]* | ?:[\\/]*) -+ ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. -+ ;; -+ *) -+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then -+ ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" -+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done -+ done -+IFS=$as_save_IFS -+ -+ ;; -+esac -+fi -+PKG_CONFIG=$ac_cv_path_PKG_CONFIG -+if test -n "$PKG_CONFIG"; then -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 -+$as_echo "$PKG_CONFIG" >&6; } -+else -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+fi -+ -+ -+fi -+if test -z "$ac_cv_path_PKG_CONFIG"; then -+ ac_pt_PKG_CONFIG=$PKG_CONFIG -+ # Extract the first word of "pkg-config", so it can be a program name with args. -+set dummy pkg-config; ac_word=$2 -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -+$as_echo_n "checking for $ac_word... " >&6; } -+if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then : -+ $as_echo_n "(cached) " >&6 -+else -+ case $ac_pt_PKG_CONFIG in -+ [\\/]* | ?:[\\/]*) -+ ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. -+ ;; -+ *) -+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then -+ ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" -+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done -+ done -+IFS=$as_save_IFS -+ -+ ;; -+esac -+fi -+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG -+if test -n "$ac_pt_PKG_CONFIG"; then -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 -+$as_echo "$ac_pt_PKG_CONFIG" >&6; } -+else -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+fi -+ -+ if test "x$ac_pt_PKG_CONFIG" = x; then -+ PKG_CONFIG="" -+ else -+ case $cross_compiling:$ac_tool_warned in -+yes:) -+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -+ac_tool_warned=yes ;; -+esac -+ PKG_CONFIG=$ac_pt_PKG_CONFIG -+ fi -+else -+ PKG_CONFIG="$ac_cv_path_PKG_CONFIG" -+fi -+ -+fi -+if test -n "$PKG_CONFIG"; then -+ _pkg_min_version=0.9.0 -+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 -+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } -+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -+$as_echo "yes" >&6; } -+ else -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+ PKG_CONFIG="" -+ fi -+fi -+ -+pkg_failed=no -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for RPM" >&5 -+$as_echo_n "checking for RPM... " >&6; } -+ -+if test -n "$RPM_CFLAGS"; then -+ pkg_cv_RPM_CFLAGS="$RPM_CFLAGS" -+ elif test -n "$PKG_CONFIG"; then -+ if test -n "$PKG_CONFIG" && \ -+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"rpm\""; } >&5 -+ ($PKG_CONFIG --exists --print-errors "rpm") 2>&5 -+ ac_status=$? -+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+ test $ac_status = 0; }; then -+ pkg_cv_RPM_CFLAGS=`$PKG_CONFIG --cflags "rpm" 2>/dev/null` -+ test "x$?" != "x0" && pkg_failed=yes -+else -+ pkg_failed=yes -+fi -+ else -+ pkg_failed=untried -+fi -+if test -n "$RPM_LIBS"; then -+ pkg_cv_RPM_LIBS="$RPM_LIBS" -+ elif test -n "$PKG_CONFIG"; then -+ if test -n "$PKG_CONFIG" && \ -+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"rpm\""; } >&5 -+ ($PKG_CONFIG --exists --print-errors "rpm") 2>&5 -+ ac_status=$? -+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 -+ test $ac_status = 0; }; then -+ pkg_cv_RPM_LIBS=`$PKG_CONFIG --libs "rpm" 2>/dev/null` -+ test "x$?" != "x0" && pkg_failed=yes -+else -+ pkg_failed=yes -+fi -+ else -+ pkg_failed=untried -+fi -+ -+ -+ -+if test $pkg_failed = yes; then -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+ -+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then -+ _pkg_short_errors_supported=yes -+else -+ _pkg_short_errors_supported=no -+fi -+ if test $_pkg_short_errors_supported = yes; then -+ RPM_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "rpm" 2>&1` -+ else -+ RPM_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "rpm" 2>&1` -+ fi -+ # Put the nasty error message in config.log where it belongs -+ echo "$RPM_PKG_ERRORS" >&5 -+ -+ HAVE_LIBRPM=false -+elif test $pkg_failed = untried; then -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+ HAVE_LIBRPM=false -+else -+ RPM_CFLAGS=$pkg_cv_RPM_CFLAGS -+ RPM_LIBS=$pkg_cv_RPM_LIBS -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -+$as_echo "yes" >&6; } -+ HAVE_LIBRPM=true -+fi -+ -+ if $HAVE_LIBRPM; then -+ -+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking rpm library API compatibility" >&5 -+$as_echo_n "checking rpm library API compatibility... " >&6; } -+ # The compilation requires -Werror to verify anything. -+ save_CFLAGS="$CFLAGS" -+ CFLAGS="$CFLAGS -Werror" -+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+ -+/* Duplicate here the declarations to verify they match "elfread.c". */ -+#include -+#include -+#include -+#include -+extern char * headerFormat(Header h, const char * fmt, errmsg_t * errmsg); -+extern int rpmReadConfigFiles(const char * file, const char * target); -+extern rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi); -+extern Header rpmdbNextIterator(rpmdbMatchIterator mi); -+extern rpmts rpmtsCreate(void); -+extern rpmts rpmtsFree(rpmts ts); -+extern rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmDbiTagVal rpmtag, -+ const void * keyp, size_t keylen); -+ -+int -+main () -+{ -+ -+ ; -+ return 0; -+} -+_ACEOF -+if ac_fn_c_try_compile "$LINENO"; then : -+ -+ LIBRPM_COMPAT=true -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -+$as_echo "yes" >&6; } -+ -+else -+ -+ LIBRPM_COMPAT=false -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+ -+fi -+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -+ CFLAGS="$save_CFLAGS" -+ -+ if ! $LIBRPM_COMPAT; then -+ HAVE_LIBRPM=false -+ RPM_PKG_ERRORS="Found $LIBRPM API is incompatibile with this GDB" -+ fi -+ fi -+ -+ if $HAVE_LIBRPM; then -+ -+$as_echo "#define HAVE_LIBRPM 1" >>confdefs.h -+ -+ CFLAGS="$CFLAGS $RPM_CFLAGS" -+ LIBS="$LIBS $RPM_LIBS" -+ else -+ if $RPM_REQUIRE; then -+ as_fn_error "$RPM_PKG_ERRORS" "$LINENO" 5 -+ else -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $RPM_PKG_ERRORS" >&5 -+$as_echo "$as_me: WARNING: $RPM_PKG_ERRORS" >&2;} -+ fi -+ fi -+ fi -+fi -+ - - - subdirs="$subdirs testsuite" -diff --git a/gdb/configure.ac b/gdb/configure.ac ---- a/gdb/configure.ac -+++ b/gdb/configure.ac -@@ -173,6 +173,200 @@ AC_DEFINE_DIR(AUTO_LOAD_SAFE_PATH, escape_dir, - [Directories safe to hold auto-loaded files.]) - AC_MSG_RESULT([$with_auto_load_safe_path]) - -+# Integration with rpm library to support missing debuginfo suggestions. -+# --without-rpm: Disable any rpm support. -+# --with-rpm=libname.so: Try to dynamically open `libname.so' during runtime. -+# Even with runtime missing `libname.so' GDB will still other run correctly. -+# Missing `libname.so' during ./configure will abort the configuration. -+# --with-rpm=librpm.so: Like `--with-rpm=libname.so' but try to find specific -+# minor version first such as `librpm-4.6.so' as minor version differences -+# mean API+ABI incompatibility. If the specific match versioned library name -+# could not be found still open dynamically at least `librpm.so'. -+# --with-rpm: Like `--with-rpm=librpm.so' but if any of its detection fails try -+# to find librpm for compilation-time linking by pkg-config. GDB binary will -+# be probably linked with the version specific library (as `librpm-4.6.so'). -+# Failure to find librpm by pkg-config will abort the configuration. -+# (default) --with-rpm=auto: Like `--with-rpm=librpm.so' but if even pkg-config -+# cannot find librpm use to the rpmless compilation (like `--without-rpm'). -+ -+AC_ARG_WITH([rpm], -+ [AS_HELP_STRING([--with-rpm], -+ [query rpm database for missing debuginfos (yes/no, def. auto=librpm.so)])], [], [with_rpm="auto"]) -+ -+m4_pattern_allow([^AC_MSG_ERROR$]) -+m4_pattern_allow([^AC_MSG_WARN$]) -+if test "x$with_rpm" != "xno"; then -+ if test "x$with_rpm" = "xyes"; then -+ LIBRPM="librpm.so" -+ RPM_REQUIRE=true -+ DLOPEN_REQUIRE=false -+ elif test "x$with_rpm" = "xauto"; then -+ LIBRPM="librpm.so" -+ RPM_REQUIRE=false -+ DLOPEN_REQUIRE=false -+ else -+ LIBRPM="$with_rpm" -+ RPM_REQUIRE=true -+ DLOPEN_REQUIRE=true -+ fi -+ LIBRPM_STRING='"'"$LIBRPM"'"' -+ -+ AC_MSG_CHECKING([specific librpm version]) -+ HAVE_DLOPEN_LIBRPM=false -+ save_LIBS="$LIBS" -+ LIBS="$LIBS -ldl" -+ AC_RUN_IFELSE(AC_LANG_PROGRAM([[ -+#include -+#include -+#include -+#include -+ ]], [[ -+ void *h; -+ const char *const *rpmverp; -+ FILE *f; -+ -+ f = fopen ("conftest.out", "w"); -+ if (!f) -+ { -+ fprintf (stderr, "Cannot write \"%s\": %s\n", "conftest.out", -+ strerror (errno)); -+ return 1; -+ } -+ h = dlopen ($LIBRPM_STRING, RTLD_LAZY); -+ if (!h) -+ { -+ fprintf (stderr, "dlopen (\"%s\"): %s\n", $LIBRPM_STRING, dlerror ()); -+ return 1; -+ } -+ rpmverp = dlsym (h, "RPMVERSION"); -+ if (!rpmverp) -+ { -+ fprintf (stderr, "dlsym (\"RPMVERSION\"): %s\n", dlerror ()); -+ return 1; -+ } -+ fprintf (stderr, "RPMVERSION is: \""); -+ fprintf (stderr, "%s\"\n", *rpmverp); -+ -+ /* Try to find the specific librpm version only for "librpm.so" as we do -+ not know how to assemble the version string otherwise. */ -+ -+ if (strcmp ("librpm.so", $LIBRPM_STRING) != 0) -+ { -+ fprintf (f, "%s\n", $LIBRPM_STRING); -+ return 0; -+ } -+ else -+ { -+ char *h2_name; -+ void *h2; -+ int major, minor; -+ -+ if (sscanf (*rpmverp, "%d.%d", &major, &minor) != 2) -+ { -+ fprintf (stderr, "Unable to parse RPMVERSION.\n"); -+ fprintf (f, "%s\n", $LIBRPM_STRING); -+ return 0; -+ } -+ /* Avoid the square brackets by malloc. */ -+ h2_name = malloc (64); -+ sprintf (h2_name, "librpm-%d.%d.so", major, minor); -+ h2 = dlopen (h2_name, RTLD_LAZY); -+ if (!h2) -+ { -+ fprintf (stderr, "dlopen (\"%s\"): %s\n", h2_name, dlerror ()); -+ fprintf (f, "%s\n", $LIBRPM_STRING); -+ return 0; -+ } -+ if (h2 != h) -+ { -+ fprintf (stderr, "dlopen of \"%s\" and \"%s\" are different.\n", -+ $LIBRPM_STRING, h2_name); -+ fprintf (f, "%s\n", $LIBRPM_STRING); -+ return 0; -+ } -+ /* Found the valid .so name with a specific version. */ -+ fprintf (f, "%s\n", h2_name); -+ return 0; -+ } -+ ]]), [ -+ DLOPEN_LIBRPM="`cat conftest.out`" -+ if test "x$DLOPEN_LIBRPM" != "x"; then -+ HAVE_DLOPEN_LIBRPM=true -+ AC_MSG_RESULT($DLOPEN_LIBRPM) -+ fi -+ ]) -+ rm -f conftest.out -+ -+ m4_define([CHECK_LIBRPM_COMPAT], [ -+ AC_MSG_CHECKING([rpm library API compatibility]) -+ # The compilation requires -Werror to verify anything. -+ save_CFLAGS="$CFLAGS" -+ CFLAGS="$CFLAGS -Werror" -+ AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[ -+/* Duplicate here the declarations to verify they match "elfread.c". */ -+#include -+#include -+#include -+#include -+extern char * headerFormat(Header h, const char * fmt, errmsg_t * errmsg); -+extern int rpmReadConfigFiles(const char * file, const char * target); -+extern rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi); -+extern Header rpmdbNextIterator(rpmdbMatchIterator mi); -+extern rpmts rpmtsCreate(void); -+extern rpmts rpmtsFree(rpmts ts); -+extern rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmDbiTagVal rpmtag, -+ const void * keyp, size_t keylen); -+ ]]), [ -+ LIBRPM_COMPAT=true -+ AC_MSG_RESULT(yes) -+ ], [ -+ LIBRPM_COMPAT=false -+ AC_MSG_RESULT(no) -+ ]) -+ CFLAGS="$save_CFLAGS" -+ ]) -+ -+ if $HAVE_DLOPEN_LIBRPM; then -+ CHECK_LIBRPM_COMPAT -+ if ! $LIBRPM_COMPAT; then -+ HAVE_DLOPEN_LIBRPM=false -+ fi -+ fi -+ -+ if $HAVE_DLOPEN_LIBRPM; then -+ DLOPEN_LIBRPM_STRING='"'"$DLOPEN_LIBRPM"'"' -+ AC_DEFINE_UNQUOTED(DLOPEN_LIBRPM, $DLOPEN_LIBRPM_STRING, [librpm version specific library name to dlopen.]) -+ AC_DEFINE(HAVE_LIBRPM, 1, [Define if librpm library is being used.]) -+ else -+ AC_MSG_RESULT(no) -+ LIBS="$save_LIBS" -+ if $DLOPEN_REQUIRE; then -+ AC_MSG_ERROR([Specific name $LIBRPM was requested but it could not be opened.]) -+ fi -+ PKG_CHECK_MODULES(RPM, rpm, [HAVE_LIBRPM=true], [HAVE_LIBRPM=false]) -+ -+ if $HAVE_LIBRPM; then -+ CHECK_LIBRPM_COMPAT -+ if ! $LIBRPM_COMPAT; then -+ HAVE_LIBRPM=false -+ RPM_PKG_ERRORS="Found $LIBRPM API is incompatibile with this GDB" -+ fi -+ fi -+ -+ if $HAVE_LIBRPM; then -+ AC_DEFINE(HAVE_LIBRPM, 1, [Define if librpm library is being used.]) -+ CFLAGS="$CFLAGS $RPM_CFLAGS" -+ LIBS="$LIBS $RPM_LIBS" -+ else -+ if $RPM_REQUIRE; then -+ AC_MSG_ERROR($RPM_PKG_ERRORS) -+ else -+ AC_MSG_WARN($RPM_PKG_ERRORS) -+ fi -+ fi -+ fi -+fi -+ - AC_CONFIG_SUBDIRS(testsuite) - - # Check whether to support alternative target configurations -diff --git a/gdb/event-top.c b/gdb/event-top.c ---- a/gdb/event-top.c -+++ b/gdb/event-top.c -@@ -43,6 +43,7 @@ - #include "async-event.h" - #include "bt-utils.h" - #include "pager.h" -+#include "symfile.h" - - /* readline include files. */ - #include "readline/readline.h" -@@ -404,6 +405,8 @@ display_gdb_prompt (const char *new_prompt) - /* Reset the nesting depth used when trace-commands is set. */ - reset_command_nest_depth (); - -+ debug_flush_missing (); -+ - /* Do not call the python hook on an explicit prompt change as - passed to this function, as this forms a secondary/local prompt, - IE, displayed but not set. */ -@@ -788,7 +791,10 @@ command_line_handler (gdb::unique_xmalloc_ptr &&rl) - command_handler (cmd); - - if (ui->prompt_state != PROMPTED) -- display_gdb_prompt (0); -+ { -+ debug_flush_missing (); -+ display_gdb_prompt (0); -+ } - } - } - -diff --git a/gdb/symfile.h b/gdb/symfile.h ---- a/gdb/symfile.h -+++ b/gdb/symfile.h -@@ -367,6 +367,7 @@ extern void generic_load (const char *args, int from_tty); - /* build-id support. */ - extern struct bfd_build_id *build_id_addr_get (CORE_ADDR addr); - extern void debug_print_missing (const char *binary, const char *debug); -+extern void debug_flush_missing (void); - #define BUILD_ID_MAIN_EXECUTABLE_FILENAME _("the main executable file") - - /* From minidebug.c. */ diff --git a/gdb-6.6-buildid-locate-tests-suse.patch b/gdb-6.6-buildid-locate-tests-suse.patch new file mode 100644 index 0000000..2d502cb --- /dev/null +++ b/gdb-6.6-buildid-locate-tests-suse.patch @@ -0,0 +1,40 @@ +From 4aaa960916b069dd82a293bf0e876dbc8710801e Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Wed, 26 Mar 2025 10:25:38 +0100 +Subject: [PATCH 4/4] gdb-6.6-buildid-locate-tests-suse.patch + +--- + ...z981154-misleading-yum-install-warning.exp | 20 ++++++++++++++++--- + 1 file changed, 17 insertions(+), 3 deletions(-) + +diff --git a/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp b/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp +index 991ffef474d..ab5f1667f31 100644 +--- a/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp ++++ b/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp +@@ -55,6 +55,20 @@ gdb_test "set build-id-verbose 1" "" \ + gdb_test "set debug-file-directory /usr/lib/" "" \ + "set debug-file-directory" + +-gdb_test "core-file [standard_output_file gcore.test]" \ +- "Missing file\\(s\\), try: dnf --enablerepo='\\*debug\\*' install [string_to_regexp /usr/lib/$build_id_without_debug] [string_to_regexp /usr/lib/debug/$build_id_debug_file]" \ +- "test first yum/dnf warning" ++# Supporting this for SUSE/openSUSE requires a gdb.missing_objfile handler, ++# but that's not enabled. Zypper doesn't support finding packages based on ++# build-id, unless the package's installed. ++# So, instead of testing for the SUSE/openSUSE-specific solution, check that ++# the fedora solution doesn't appear. ++ ++set cmd "core-file [standard_output_file gcore.test]" ++set test "test first yum/dnf warning" ++set fail_re [string_to_regexp "Missing file(s), try: dnf "].* ++gdb_test_multiple $cmd $test { ++ -re -wrap $fail_re { ++ fail $gdb_test_name ++ } ++ -re -wrap "" { ++ pass $gdb_test_name ++ } ++} +-- +2.43.0 + diff --git a/gdb-6.6-buildid-locate-solib-missing-ids.patch b/gdb-6.6-buildid-locate-tests.patch similarity index 67% rename from gdb-6.6-buildid-locate-solib-missing-ids.patch rename to gdb-6.6-buildid-locate-tests.patch index f52fbd9..44e1977 100644 --- a/gdb-6.6-buildid-locate-solib-missing-ids.patch +++ b/gdb-6.6-buildid-locate-tests.patch @@ -1,75 +1,10 @@ From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 From: Fedora GDB patches Date: Fri, 27 Oct 2017 21:07:50 +0200 -Subject: gdb-6.6-buildid-locate-solib-missing-ids.patch +Subject: gdb-6.6-buildid-locate-tests.patch -;; Fix loading of core files without build-ids but with build-ids in executables. -;; Load strictly build-id-checked core files only if no executable is specified -;; (Jan Kratochvil, RH BZ 1339862). -;;=push+jan +;; Tests and test updates related to the rpm suggestion feature. -gdb returns an incorrect back trace when applying a debuginfo -https://bugzilla.redhat.com/show_bug.cgi?id=1339862 - -diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c ---- a/gdb/solib-svr4.c -+++ b/gdb/solib-svr4.c -@@ -1320,14 +1320,28 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm, - } - - { -- struct bfd_build_id *build_id; -+ struct bfd_build_id *build_id = NULL; - - strncpy (newobj->so_original_name, buffer.get (), SO_NAME_MAX_PATH_SIZE - 1); - newobj->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; - /* May get overwritten below. */ - strcpy (newobj->so_name, newobj->so_original_name); - -- build_id = build_id_addr_get (((lm_info_svr4 *) newobj->lm_info)->l_ld); -+ /* In the case the main executable was found according to its build-id -+ (from a core file) prevent loading a different build of a library -+ with accidentally the same SO_NAME. -+ -+ It suppresses bogus backtraces (and prints "??" there instead) if -+ the on-disk files no longer match the running program version. -+ -+ If the main executable was not loaded according to its build-id do -+ not do any build-id checking of the libraries. There may be missing -+ build-ids dumped in the core file and we would map all the libraries -+ to the only existing file loaded that time - the executable. */ -+ if (current_program_space->symfile_object_file != NULL -+ && (current_program_space->symfile_object_file->flags -+ & OBJF_BUILD_ID_CORE_LOADED) != 0) -+ build_id = build_id_addr_get (li->l_ld); - if (build_id != NULL) - { - char *name, *build_id_filename; -@@ -1342,23 +1356,7 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm, - xfree (name); - } - else -- { -- debug_print_missing (newobj->so_name, build_id_filename); -- -- /* In the case the main executable was found according to -- its build-id (from a core file) prevent loading -- a different build of a library with accidentally the -- same SO_NAME. -- -- It suppresses bogus backtraces (and prints "??" there -- instead) if the on-disk files no longer match the -- running program version. */ -- -- if (current_program_space->symfile_object_file != NULL -- && (current_program_space->symfile_object_file->flags -- & OBJF_BUILD_ID_CORE_LOADED) != 0) -- newobj->so_name[0] = 0; -- } -+ debug_print_missing (newobj->so_name, build_id_filename); - - xfree (build_id_filename); - xfree (build_id); diff --git a/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-lib.c b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-lib.c new file mode 100644 --- /dev/null @@ -130,7 +65,7 @@ diff --git a/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp b/gdb/t new file mode 100644 --- /dev/null +++ b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp -@@ -0,0 +1,105 @@ +@@ -0,0 +1,104 @@ +# Copyright 2016 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify @@ -146,9 +81,7 @@ new file mode 100644 +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + -+if {[skip_shlib_tests]} { -+ return 0 -+} ++require allow_shlib_tests + +set testfile "gcore-buildid-exec-but-not-solib" +set srcmainfile ${testfile}-main.c @@ -226,7 +159,8 @@ new file mode 100644 +remote_exec build "ln -s /lib64 ${debugdir}/" +# /usr is not needed, all the libs are in /lib64: libm.so.6 libc.so.6 ld-linux-x86-64.so.2 + -+gdb_test "set solib-absolute-prefix $debugdir" ++gdb_test_no_output "set solib-absolute-prefix $debugdir" \ ++ "set solib-absolute-prefix" + +gdb_test_no_output "set debug-file-directory $debugdir" "set debug-file-directory" + @@ -236,3 +170,68 @@ new file mode 100644 + +gdb_test "bt" +gdb_test "info shared" +diff --git a/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp b/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp +@@ -0,0 +1,60 @@ ++# Copyright (C) 2014 Free Software Foundation, Inc. ++ ++# 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 . ++ ++# Create a core file, then hide the executable. Restart GDB and load ++# the core file. Check GDB gives a message suggesting a 'dnf' command ++# to try and install the executable based on its build-id. ++ ++standard_testfile "normal.c" ++ ++if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } { ++ return -1 ++} ++ ++# Get the build-id of the file. ++set build_id_debug_file [build_id_debug_filename_get $binfile] ++regsub -all ".debug$" $build_id_debug_file "" build_id_without_debug ++ ++# Run to main. ++if { ![runto_main] } { ++ return -1 ++} ++ ++# We first need to generate a corefile. ++set corefilename "[standard_output_file gcore.test]" ++if { ![gdb_gcore_cmd "$corefilename" "save corefile"] } { ++ untested "could not generate a corefile" ++ return -1 ++} ++ ++# Move the binfile to a temporary name. ++remote_exec build "mv $binfile ${binfile}.old" ++ ++# Reinitialize GDB and see if we get a dnf suggestion. ++clean_restart ++ ++gdb_test "set build-id-verbose 1" "" \ ++ "set build-id-verbose" ++ ++# GDB only makes build-id based RPM suggestions if /usr/lib is in ++# the debug-file-directory list, the reason being that system RPMs ++# will always install under this location. If GDB is not looking ++# here then there's no point making suggestions. ++gdb_test "set debug-file-directory /usr/lib/" "" \ ++ "set debug-file-directory" ++ ++gdb_test "core-file [standard_output_file gcore.test]" \ ++ "Missing file\\(s\\), try: dnf --enablerepo='\\*debug\\*' install [string_to_regexp /usr/lib/$build_id_without_debug] [string_to_regexp /usr/lib/debug/$build_id_debug_file]" \ ++ "test first yum/dnf warning" diff --git a/gdb-6.6-buildid-locate.patch b/gdb-6.6-buildid-locate.patch deleted file mode 100644 index c2d7077..0000000 --- a/gdb-6.6-buildid-locate.patch +++ /dev/null @@ -1,1925 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Fedora GDB patches -Date: Fri, 27 Oct 2017 21:07:50 +0200 -Subject: gdb-6.6-buildid-locate.patch - -;; New locating of the matching binaries from the pure core file (build-id). -;;=push+jan - -diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h ---- a/bfd/libbfd-in.h -+++ b/bfd/libbfd-in.h -@@ -110,7 +110,7 @@ static inline char * - bfd_strdup (const char *str) - { - size_t len = strlen (str) + 1; -- char *buf = bfd_malloc (len); -+ char *buf = (char *) bfd_malloc (len); - if (buf != NULL) - memcpy (buf, str, len); - return buf; -diff --git a/bfd/libbfd.h b/bfd/libbfd.h ---- a/bfd/libbfd.h -+++ b/bfd/libbfd.h -@@ -116,7 +116,7 @@ static inline char * - bfd_strdup (const char *str) - { - size_t len = strlen (str) + 1; -- char *buf = bfd_malloc (len); -+ char *buf = (char *) bfd_malloc (len); - if (buf != NULL) - memcpy (buf, str, len); - return buf; -diff --git a/gdb/build-id.c b/gdb/build-id.c ---- a/gdb/build-id.c -+++ b/gdb/build-id.c -@@ -24,14 +24,72 @@ - #include "gdbsupport/gdb_vecs.h" - #include "symfile.h" - #include "objfiles.h" -+#include -+#include "elf-bfd.h" -+#include "elf/common.h" -+#include "elf/external.h" -+#include "elf/internal.h" - #include "filenames.h" -+#include "gdb_bfd.h" -+#include "gdbcmd.h" - #include "gdbcore.h" - #include "cli/cli-style.h" -+#include "inferior.h" -+#include "objfiles.h" -+#include "observable.h" -+#include "symfile.h" -+ -+#define BUILD_ID_VERBOSE_NONE 0 -+#define BUILD_ID_VERBOSE_FILENAMES 1 -+#define BUILD_ID_VERBOSE_BINARY_PARSE 2 -+static int build_id_verbose = BUILD_ID_VERBOSE_FILENAMES; -+static void -+show_build_id_verbose (struct ui_file *file, int from_tty, -+ struct cmd_list_element *c, const char *value) -+{ -+ gdb_printf (file, _("Verbosity level of the build-id locator is %s.\n"), -+ value); -+} -+/* Locate NT_GNU_BUILD_ID and return its matching debug filename. -+ FIXME: NOTE decoding should be unified with the BFD core notes decoding. */ -+ -+static struct bfd_build_id * -+build_id_buf_get (bfd *templ, gdb_byte *buf, bfd_size_type size) -+{ -+ bfd_byte *p; -+ -+ p = buf; -+ while (p < buf + size) -+ { -+ /* FIXME: bad alignment assumption. */ -+ Elf_External_Note *xnp = (Elf_External_Note *) p; -+ size_t namesz = H_GET_32 (templ, xnp->namesz); -+ size_t descsz = H_GET_32 (templ, xnp->descsz); -+ bfd_byte *descdata = (gdb_byte *) xnp->name + BFD_ALIGN (namesz, 4); -+ -+ if (H_GET_32 (templ, xnp->type) == NT_GNU_BUILD_ID -+ && namesz == sizeof "GNU" -+ && memcmp (xnp->name, "GNU", sizeof "GNU") == 0) -+ { -+ size_t sz = descsz; -+ gdb_byte *data = (gdb_byte *) descdata; -+ struct bfd_build_id *retval; -+ -+ retval = (struct bfd_build_id *) xmalloc (sizeof *retval - 1 + sz); -+ retval->size = sz; -+ memcpy (retval->data, data, sz); -+ -+ return retval; -+ } -+ p = descdata + BFD_ALIGN (descsz, 4); -+ } -+ return NULL; -+} - - /* See build-id.h. */ - - const struct bfd_build_id * --build_id_bfd_get (bfd *abfd) -+build_id_bfd_shdr_get (bfd *abfd) - { - /* Dynamic objfiles such as ones created by JIT reader API - have no underlying bfd structure (that is, objfile->obfd -@@ -50,6 +108,348 @@ build_id_bfd_get (bfd *abfd) - return NULL; - } - -+/* Core files may have missing (corrupt) SHDR but PDHR is correct there. -+ bfd_elf_bfd_from_remote_memory () has too much overhead by -+ allocating/reading all the available ELF PT_LOADs. */ -+ -+static struct bfd_build_id * -+build_id_phdr_get (bfd *templ, bfd_vma loadbase, unsigned e_phnum, -+ Elf_Internal_Phdr *i_phdr) -+{ -+ int i; -+ struct bfd_build_id *retval = NULL; -+ -+ for (i = 0; i < e_phnum; i++) -+ if (i_phdr[i].p_type == PT_NOTE && i_phdr[i].p_filesz > 0) -+ { -+ Elf_Internal_Phdr *hdr = &i_phdr[i]; -+ gdb_byte *buf; -+ int err; -+ -+ buf = (gdb_byte *) xmalloc (hdr->p_filesz); -+ err = target_read_memory (loadbase + i_phdr[i].p_vaddr, buf, -+ hdr->p_filesz); -+ if (err == 0) -+ retval = build_id_buf_get (templ, buf, hdr->p_filesz); -+ else -+ retval = NULL; -+ xfree (buf); -+ if (retval != NULL) -+ break; -+ } -+ return retval; -+} -+ -+/* First we validate the file by reading in the ELF header and checking -+ the magic number. */ -+ -+static inline bfd_boolean -+elf_file_p (Elf64_External_Ehdr *x_ehdrp64) -+{ -+ gdb_assert (sizeof (Elf64_External_Ehdr) >= sizeof (Elf32_External_Ehdr)); -+ gdb_assert (offsetof (Elf64_External_Ehdr, e_ident) -+ == offsetof (Elf32_External_Ehdr, e_ident)); -+ gdb_assert (sizeof (((Elf64_External_Ehdr *) 0)->e_ident) -+ == sizeof (((Elf32_External_Ehdr *) 0)->e_ident)); -+ -+ return ((x_ehdrp64->e_ident[EI_MAG0] == ELFMAG0) -+ && (x_ehdrp64->e_ident[EI_MAG1] == ELFMAG1) -+ && (x_ehdrp64->e_ident[EI_MAG2] == ELFMAG2) -+ && (x_ehdrp64->e_ident[EI_MAG3] == ELFMAG3)); -+} -+ -+/* Translate an ELF file header in external format into an ELF file header in -+ internal format. */ -+ -+#define H_GET_WORD(bfd, ptr) (is64 ? H_GET_64 (bfd, (ptr)) \ -+ : H_GET_32 (bfd, (ptr))) -+#define H_GET_SIGNED_WORD(bfd, ptr) (is64 ? H_GET_S64 (bfd, (ptr)) \ -+ : H_GET_S32 (bfd, (ptr))) -+ -+static void -+elf_swap_ehdr_in (bfd *abfd, -+ const Elf64_External_Ehdr *src64, -+ Elf_Internal_Ehdr *dst) -+{ -+ int is64 = bfd_get_arch_size (abfd) == 64; -+#define SRC(field) (is64 ? src64->field \ -+ : ((const Elf32_External_Ehdr *) src64)->field) -+ -+ int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma; -+ memcpy (dst->e_ident, SRC (e_ident), EI_NIDENT); -+ dst->e_type = H_GET_16 (abfd, SRC (e_type)); -+ dst->e_machine = H_GET_16 (abfd, SRC (e_machine)); -+ dst->e_version = H_GET_32 (abfd, SRC (e_version)); -+ if (signed_vma) -+ dst->e_entry = H_GET_SIGNED_WORD (abfd, SRC (e_entry)); -+ else -+ dst->e_entry = H_GET_WORD (abfd, SRC (e_entry)); -+ dst->e_phoff = H_GET_WORD (abfd, SRC (e_phoff)); -+ dst->e_shoff = H_GET_WORD (abfd, SRC (e_shoff)); -+ dst->e_flags = H_GET_32 (abfd, SRC (e_flags)); -+ dst->e_ehsize = H_GET_16 (abfd, SRC (e_ehsize)); -+ dst->e_phentsize = H_GET_16 (abfd, SRC (e_phentsize)); -+ dst->e_phnum = H_GET_16 (abfd, SRC (e_phnum)); -+ dst->e_shentsize = H_GET_16 (abfd, SRC (e_shentsize)); -+ dst->e_shnum = H_GET_16 (abfd, SRC (e_shnum)); -+ dst->e_shstrndx = H_GET_16 (abfd, SRC (e_shstrndx)); -+ -+#undef SRC -+} -+ -+/* Translate an ELF program header table entry in external format into an -+ ELF program header table entry in internal format. */ -+ -+static void -+elf_swap_phdr_in (bfd *abfd, -+ const Elf64_External_Phdr *src64, -+ Elf_Internal_Phdr *dst) -+{ -+ int is64 = bfd_get_arch_size (abfd) == 64; -+#define SRC(field) (is64 ? src64->field \ -+ : ((const Elf32_External_Phdr *) src64)->field) -+ -+ int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma; -+ -+ dst->p_type = H_GET_32 (abfd, SRC (p_type)); -+ dst->p_flags = H_GET_32 (abfd, SRC (p_flags)); -+ dst->p_offset = H_GET_WORD (abfd, SRC (p_offset)); -+ if (signed_vma) -+ { -+ dst->p_vaddr = H_GET_SIGNED_WORD (abfd, SRC (p_vaddr)); -+ dst->p_paddr = H_GET_SIGNED_WORD (abfd, SRC (p_paddr)); -+ } -+ else -+ { -+ dst->p_vaddr = H_GET_WORD (abfd, SRC (p_vaddr)); -+ dst->p_paddr = H_GET_WORD (abfd, SRC (p_paddr)); -+ } -+ dst->p_filesz = H_GET_WORD (abfd, SRC (p_filesz)); -+ dst->p_memsz = H_GET_WORD (abfd, SRC (p_memsz)); -+ dst->p_align = H_GET_WORD (abfd, SRC (p_align)); -+ -+#undef SRC -+} -+ -+#undef H_GET_SIGNED_WORD -+#undef H_GET_WORD -+ -+static Elf_Internal_Phdr * -+elf_get_phdr (bfd *templ, bfd_vma ehdr_vma, unsigned *e_phnum_pointer, -+ bfd_vma *loadbase_pointer) -+{ -+ /* sizeof (Elf64_External_Ehdr) >= sizeof (Elf32_External_Ehdr) */ -+ Elf64_External_Ehdr x_ehdr64; /* Elf file header, external form */ -+ Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */ -+ bfd_size_type x_phdrs_size; -+ gdb_byte *x_phdrs_ptr; -+ Elf_Internal_Phdr *i_phdrs; -+ int err; -+ unsigned int i; -+ bfd_vma loadbase; -+ int loadbase_set; -+ -+ gdb_assert (templ != NULL); -+ gdb_assert (sizeof (Elf64_External_Ehdr) >= sizeof (Elf32_External_Ehdr)); -+ -+ /* Read in the ELF header in external format. */ -+ err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr64, sizeof x_ehdr64); -+ if (err) -+ { -+ if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) -+ warning (_("build-id: Error reading ELF header at address 0x%lx"), -+ (unsigned long) ehdr_vma); -+ return NULL; -+ } -+ -+ /* Now check to see if we have a valid ELF file, and one that BFD can -+ make use of. The magic number must match, the address size ('class') -+ and byte-swapping must match our XVEC entry. */ -+ -+ if (! elf_file_p (&x_ehdr64) -+ || x_ehdr64.e_ident[EI_VERSION] != EV_CURRENT -+ || !((bfd_get_arch_size (templ) == 64 -+ && x_ehdr64.e_ident[EI_CLASS] == ELFCLASS64) -+ || (bfd_get_arch_size (templ) == 32 -+ && x_ehdr64.e_ident[EI_CLASS] == ELFCLASS32))) -+ { -+ if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) -+ warning (_("build-id: Unrecognized ELF header at address 0x%lx"), -+ (unsigned long) ehdr_vma); -+ return NULL; -+ } -+ -+ /* Check that file's byte order matches xvec's */ -+ switch (x_ehdr64.e_ident[EI_DATA]) -+ { -+ case ELFDATA2MSB: /* Big-endian */ -+ if (! bfd_header_big_endian (templ)) -+ { -+ if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) -+ warning (_("build-id: Unrecognized " -+ "big-endian ELF header at address 0x%lx"), -+ (unsigned long) ehdr_vma); -+ return NULL; -+ } -+ break; -+ case ELFDATA2LSB: /* Little-endian */ -+ if (! bfd_header_little_endian (templ)) -+ { -+ if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) -+ warning (_("build-id: Unrecognized " -+ "little-endian ELF header at address 0x%lx"), -+ (unsigned long) ehdr_vma); -+ return NULL; -+ } -+ break; -+ case ELFDATANONE: /* No data encoding specified */ -+ default: /* Unknown data encoding specified */ -+ if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) -+ warning (_("build-id: Unrecognized " -+ "ELF header endianity at address 0x%lx"), -+ (unsigned long) ehdr_vma); -+ return NULL; -+ } -+ -+ elf_swap_ehdr_in (templ, &x_ehdr64, &i_ehdr); -+ -+ /* The file header tells where to find the program headers. -+ These are what we use to actually choose what to read. */ -+ -+ if (i_ehdr.e_phentsize != (bfd_get_arch_size (templ) == 64 -+ ? sizeof (Elf64_External_Phdr) -+ : sizeof (Elf32_External_Phdr)) -+ || i_ehdr.e_phnum == 0) -+ { -+ if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) -+ warning (_("build-id: Invalid ELF program headers from the ELF header " -+ "at address 0x%lx"), (unsigned long) ehdr_vma); -+ return NULL; -+ } -+ -+ x_phdrs_size = (bfd_get_arch_size (templ) == 64 ? sizeof (Elf64_External_Phdr) -+ : sizeof (Elf32_External_Phdr)); -+ -+ i_phdrs = (Elf_Internal_Phdr *) xmalloc (i_ehdr.e_phnum * (sizeof *i_phdrs + x_phdrs_size)); -+ x_phdrs_ptr = (gdb_byte *) &i_phdrs[i_ehdr.e_phnum]; -+ err = target_read_memory (ehdr_vma + i_ehdr.e_phoff, (bfd_byte *) x_phdrs_ptr, -+ i_ehdr.e_phnum * x_phdrs_size); -+ if (err) -+ { -+ free (i_phdrs); -+ if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) -+ warning (_("build-id: Error reading " -+ "ELF program headers at address 0x%lx"), -+ (unsigned long) (ehdr_vma + i_ehdr.e_phoff)); -+ return NULL; -+ } -+ -+ loadbase = ehdr_vma; -+ loadbase_set = 0; -+ for (i = 0; i < i_ehdr.e_phnum; ++i) -+ { -+ elf_swap_phdr_in (templ, (Elf64_External_Phdr *) -+ (x_phdrs_ptr + i * x_phdrs_size), &i_phdrs[i]); -+ /* IA-64 vDSO may have two mappings for one segment, where one mapping -+ is executable only, and one is read only. We must not use the -+ executable one (PF_R is the first one, PF_X the second one). */ -+ if (i_phdrs[i].p_type == PT_LOAD && (i_phdrs[i].p_flags & PF_R)) -+ { -+ /* Only the first PT_LOAD segment indicates the file bias. -+ Next segments may have P_VADDR arbitrarily higher. -+ If the first segment has P_VADDR zero any next segment must not -+ confuse us, the first one sets LOADBASE certainly enough. */ -+ if (!loadbase_set && i_phdrs[i].p_offset == 0) -+ { -+ loadbase = ehdr_vma - i_phdrs[i].p_vaddr; -+ loadbase_set = 1; -+ } -+ } -+ } -+ -+ if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) -+ warning (_("build-id: Found ELF header at address 0x%lx, loadbase 0x%lx"), -+ (unsigned long) ehdr_vma, (unsigned long) loadbase); -+ -+ *e_phnum_pointer = i_ehdr.e_phnum; -+ *loadbase_pointer = loadbase; -+ return i_phdrs; -+} -+ -+/* BUILD_ID_ADDR_GET gets ADDR located somewhere in the object. -+ Find the first section before ADDR containing an ELF header. -+ We rely on the fact the sections from multiple files do not mix. -+ FIXME: We should check ADDR is contained _inside_ the section with possibly -+ missing content (P_FILESZ < P_MEMSZ). These omitted sections are currently -+ hidden by _BFD_ELF_MAKE_SECTION_FROM_PHDR. */ -+ -+static CORE_ADDR build_id_addr; -+struct build_id_addr_sect -+ { -+ struct build_id_addr_sect *next; -+ asection *sect; -+ }; -+static struct build_id_addr_sect *build_id_addr_sect; -+ -+static void build_id_addr_candidate (bfd *abfd, asection *sect, void *obj) -+{ -+ if (build_id_addr >= bfd_section_vma (sect)) -+ { -+ struct build_id_addr_sect *candidate; -+ -+ candidate = (struct build_id_addr_sect *) xmalloc (sizeof *candidate); -+ candidate->next = build_id_addr_sect; -+ build_id_addr_sect = candidate; -+ candidate->sect = sect; -+ } -+} -+ -+struct bfd_build_id * -+build_id_addr_get (CORE_ADDR addr) -+{ -+ struct build_id_addr_sect *candidate; -+ struct bfd_build_id *retval = NULL; -+ Elf_Internal_Phdr *i_phdr = NULL; -+ bfd_vma loadbase = 0; -+ unsigned e_phnum = 0; -+ -+ if (core_bfd == NULL) -+ return NULL; -+ -+ build_id_addr = addr; -+ gdb_assert (build_id_addr_sect == NULL); -+ bfd_map_over_sections (core_bfd, build_id_addr_candidate, NULL); -+ -+ /* Sections are sorted in the high-to-low VMAs order. -+ Stop the search on the first ELF header we find. -+ Do not continue the search even if it does not contain NT_GNU_BUILD_ID. */ -+ -+ for (candidate = build_id_addr_sect; candidate != NULL; -+ candidate = candidate->next) -+ { -+ i_phdr = elf_get_phdr (core_bfd, -+ bfd_section_vma (candidate->sect), -+ &e_phnum, &loadbase); -+ if (i_phdr != NULL) -+ break; -+ } -+ -+ if (i_phdr != NULL) -+ { -+ retval = build_id_phdr_get (core_bfd, loadbase, e_phnum, i_phdr); -+ xfree (i_phdr); -+ } -+ -+ while (build_id_addr_sect != NULL) -+ { -+ candidate = build_id_addr_sect; -+ build_id_addr_sect = candidate->next; -+ xfree (candidate); -+ } -+ -+ return retval; -+} -+ - /* See build-id.h. */ - - int -@@ -58,7 +458,7 @@ build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check) - const struct bfd_build_id *found; - int retval = 0; - -- found = build_id_bfd_get (abfd); -+ found = build_id_bfd_shdr_get (abfd); - - if (found == NULL) - warning (_("File \"%s\" has no build-id, file skipped"), -@@ -73,63 +473,166 @@ build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check) - return retval; - } - -+static char * -+link_resolve (const char *symlink, int level) -+{ -+ char buf[PATH_MAX + 1], *retval; -+ gdb::unique_xmalloc_ptr target; -+ ssize_t got; -+ -+ if (level > 10) -+ return xstrdup (symlink); -+ -+ got = readlink (symlink, buf, sizeof (buf)); -+ if (got < 0 || got >= sizeof (buf)) -+ return xstrdup (symlink); -+ buf[got] = '\0'; -+ -+ if (IS_ABSOLUTE_PATH (buf)) -+ target = make_unique_xstrdup (buf); -+ else -+ { -+ const std::string dir (ldirname (symlink)); -+ -+ target = xstrprintf ("%s" -+#ifndef HAVE_DOS_BASED_FILE_SYSTEM -+ "/" -+#else /* HAVE_DOS_BASED_FILE_SYSTEM */ -+ "\\" -+#endif /* HAVE_DOS_BASED_FILE_SYSTEM */ -+ "%s", dir.c_str(), buf); -+ } -+ -+ retval = link_resolve (target.get (), level + 1); -+ return retval; -+} -+ - /* Helper for build_id_to_debug_bfd. LINK is a path to a potential - build-id-based separate debug file, potentially a symlink to the real file. - If the file exists and matches BUILD_ID, return a BFD reference to it. */ - - static gdb_bfd_ref_ptr --build_id_to_debug_bfd_1 (const std::string &link, size_t build_id_len, -- const bfd_byte *build_id) -+build_id_to_debug_bfd_1 (const std::string &orig_link, size_t build_id_len, -+ const bfd_byte *build_id, char **link_return) - { -+ gdb_bfd_ref_ptr ret_bfd = {}; -+ std::string ret_link; -+ - if (separate_debug_file_debug) - { -- gdb_printf (gdb_stdlog, _(" Trying %s..."), link.c_str ()); -- gdb_flush (gdb_stdlog); -+ gdb_printf (gdb_stdlog, _(" Trying %s..."), orig_link.c_str ()); -+ gdb_flush (gdb_stdout); - } - -- /* lrealpath() is expensive even for the usually non-existent files. */ -- gdb::unique_xmalloc_ptr filename_holder; -- const char *filename = nullptr; -- if (startswith (link, TARGET_SYSROOT_PREFIX)) -- filename = link.c_str (); -- else if (access (link.c_str (), F_OK) == 0) -+ for (unsigned seqno = 0;; seqno++) - { -- filename_holder.reset (lrealpath (link.c_str ())); -- filename = filename_holder.get (); -- } -+ std::string link = orig_link; - -- if (filename == NULL) -- { -- if (separate_debug_file_debug) -- gdb_printf (gdb_stdlog, -- _(" no, unable to compute real path\n")); -+ if (seqno > 0) -+ { -+ /* There can be multiple build-id symlinks pointing to real files -+ with the same build-id (such as hard links). Some of the real -+ files may not be installed. */ - -- return {}; -- } -+ string_appendf (link, ".%u", seqno); -+ } - -- /* We expect to be silent on the non-existing files. */ -- gdb_bfd_ref_ptr debug_bfd = gdb_bfd_open (filename, gnutarget); -+ ret_link = link; - -- if (debug_bfd == NULL) -- { -- if (separate_debug_file_debug) -- gdb_printf (gdb_stdlog, _(" no, unable to open.\n")); -+ struct stat statbuf_trash; -+ -+ /* `access' automatically dereferences LINK. */ -+ if (lstat (link.c_str (), &statbuf_trash) != 0) -+ { -+ /* Stop increasing SEQNO. */ -+ break; -+ } -+ -+ /* lrealpath() is expensive even for the usually non-existent files. */ -+ gdb::unique_xmalloc_ptr filename_holder; -+ const char *filename = nullptr; -+ if (startswith (link, TARGET_SYSROOT_PREFIX)) -+ filename = link.c_str (); -+ else if (access (link.c_str (), F_OK) == 0) -+ { -+ filename_holder.reset (lrealpath (link.c_str ())); -+ filename = filename_holder.get (); -+ } -+ -+ if (filename == NULL) -+ { -+ if (separate_debug_file_debug) -+ gdb_printf (gdb_stdlog, -+ _(" no, unable to compute real path\n")); -+ -+ continue; -+ } -+ -+ /* We expect to be silent on the non-existing files. */ -+ gdb_bfd_ref_ptr debug_bfd = gdb_bfd_open (filename, gnutarget); -+ -+ if (debug_bfd == NULL) -+ { -+ if (separate_debug_file_debug) -+ gdb_printf (gdb_stdlog, _(" no, unable to open.\n")); - -- return {}; -+ continue; -+ } -+ -+ if (!build_id_verify (debug_bfd.get(), build_id_len, build_id)) -+ { -+ if (separate_debug_file_debug) -+ gdb_printf (gdb_stdlog, -+ _(" no, build-id does not match.\n")); -+ -+ continue; -+ } -+ -+ ret_bfd = debug_bfd; -+ break; - } - -- if (!build_id_verify (debug_bfd.get(), build_id_len, build_id)) -+ std::string link_all; -+ -+ if (ret_bfd != NULL) - { - if (separate_debug_file_debug) -- gdb_printf (gdb_stdlog, _(" no, build-id does not match.\n")); -+ gdb_printf (gdb_stdlog, _(" yes!\n")); -+ } -+ else -+ { -+ /* If none of the real files is found report as missing file -+ always the non-.%u-suffixed file. */ -+ std::string link0 = orig_link; - -- return {}; -+ /* If the symlink has target request to install the target. -+ BASE-debuginfo.rpm contains the symlink but BASE.rpm may be missing. -+ https://bugzilla.redhat.com/show_bug.cgi?id=981154 */ -+ std::string link0_resolved (link_resolve (link0.c_str (), 0)); -+ -+ if (link_all.empty ()) -+ link_all = link0_resolved; -+ else -+ { -+ /* Use whitespace instead of DIRNAME_SEPARATOR to be compatible with -+ its possible use as an argument for installation command. */ -+ link_all += " " + link0_resolved; -+ } - } - -- if (separate_debug_file_debug) -- gdb_printf (gdb_stdlog, _(" yes!\n")); -+ if (link_return != NULL) -+ { -+ if (ret_bfd != NULL) -+ { -+ *link_return = xstrdup (ret_link.c_str ()); -+ } -+ else -+ { -+ *link_return = xstrdup (link_all.c_str ()); -+ } -+ } - -- return debug_bfd; -+ return ret_bfd; - } - - /* Common code for finding BFDs of a given build-id. This function -@@ -138,7 +641,7 @@ build_id_to_debug_bfd_1 (const std::string &link, size_t build_id_len, - - static gdb_bfd_ref_ptr - build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id, -- const char *suffix) -+ const char *suffix, char **link_return) - { - /* Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will - cause "/.build-id/..." lookups. */ -@@ -161,16 +664,17 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id, - if (size > 0) - { - size--; -- string_appendf (link, "%02x/", (unsigned) *data++); -+ string_appendf (link, "%02x", (unsigned) *data++); - } -- -+ if (size > 0) -+ link += "/"; - while (size-- > 0) - string_appendf (link, "%02x", (unsigned) *data++); - - link += suffix; - - gdb_bfd_ref_ptr debug_bfd -- = build_id_to_debug_bfd_1 (link, build_id_len, build_id); -+ = build_id_to_debug_bfd_1 (link, build_id_len, build_id, link_return); - if (debug_bfd != NULL) - return debug_bfd; - -@@ -181,7 +685,7 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id, - if (!gdb_sysroot.empty ()) - { - link = gdb_sysroot + link; -- debug_bfd = build_id_to_debug_bfd_1 (link, build_id_len, build_id); -+ debug_bfd = build_id_to_debug_bfd_1 (link, build_id_len, build_id, NULL); - if (debug_bfd != NULL) - return debug_bfd; - } -@@ -190,31 +694,663 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id, - return {}; - } - -+char * -+build_id_to_filename (const struct bfd_build_id *build_id, char **link_return) -+{ -+ gdb_bfd_ref_ptr abfd; -+ char *result; -+ -+ abfd = build_id_to_exec_bfd (build_id->size, build_id->data, link_return); -+ if (abfd == NULL) -+ return NULL; -+ -+ result = xstrdup (bfd_get_filename (abfd.get ())); -+ return result; -+} -+ -+void debug_flush_missing (void); -+ -+#ifdef HAVE_LIBRPM -+ -+#include -+#include -+#include -+#include -+#ifdef DLOPEN_LIBRPM -+#include -+#endif -+ -+/* Workarodun https://bugzilla.redhat.com/show_bug.cgi?id=643031 -+ librpm must not exit() an application on SIGINT -+ -+ Enable or disable a signal handler. SIGNUM: signal to enable (or disable -+ if negative). HANDLER: sa_sigaction handler (or NULL to use -+ rpmsqHandler()). Returns: no. of refs, -1 on error. */ -+extern int rpmsqEnable (int signum, /* rpmsqAction_t handler */ void *handler); -+int -+rpmsqEnable (int signum, /* rpmsqAction_t handler */ void *handler) -+{ -+ return 0; -+} -+ -+/* This MISSING_RPM_HASH tracker is used to collect all the missing rpm files -+ and avoid their duplicities during a single inferior run. */ -+ -+static struct htab *missing_rpm_hash; -+ -+/* This MISSING_RPM_LIST tracker is used to collect and print as a single line -+ all the rpms right before the nearest GDB prompt. It gets cleared after -+ each such print (it is questionable if we should clear it after the print). -+ */ -+ -+struct missing_rpm -+ { -+ struct missing_rpm *next; -+ char rpm[1]; -+ }; -+static struct missing_rpm *missing_rpm_list; -+static int missing_rpm_list_entries; -+ -+/* Returns the count of newly added rpms. */ -+ -+static int -+#ifndef GDB_INDEX_VERIFY_VENDOR -+missing_rpm_enlist (const char *filename) -+#else -+missing_rpm_enlist_1 (const char *filename, int verify_vendor) -+#endif -+{ -+ static int rpm_init_done = 0; -+ rpmts ts; -+ rpmdbMatchIterator mi; -+ int count = 0; -+ -+#ifdef DLOPEN_LIBRPM -+ /* Duplicate here the declarations to verify they match. The same sanity -+ check is present also in `configure.ac'. */ -+ extern char * headerFormat(Header h, const char * fmt, errmsg_t * errmsg); -+ static char *(*headerFormat_p) (Header h, const char * fmt, errmsg_t *errmsg); -+ extern int rpmReadConfigFiles(const char * file, const char * target); -+ static int (*rpmReadConfigFiles_p) (const char * file, const char * target); -+ extern rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi); -+ static rpmdbMatchIterator (*rpmdbFreeIterator_p) (rpmdbMatchIterator mi); -+ extern Header rpmdbNextIterator(rpmdbMatchIterator mi); -+ static Header (*rpmdbNextIterator_p) (rpmdbMatchIterator mi); -+ extern rpmts rpmtsCreate(void); -+ static rpmts (*rpmtsCreate_p) (void); -+ extern rpmts rpmtsFree(rpmts ts); -+ static rpmts (*rpmtsFree_p) (rpmts ts); -+ extern rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmTag rpmtag, -+ const void * keyp, size_t keylen); -+ static rpmdbMatchIterator (*rpmtsInitIterator_p) (const rpmts ts, -+ rpmTag rpmtag, -+ const void *keyp, -+ size_t keylen); -+#else /* !DLOPEN_LIBRPM */ -+# define headerFormat_p headerFormat -+# define rpmReadConfigFiles_p rpmReadConfigFiles -+# define rpmdbFreeIterator_p rpmdbFreeIterator -+# define rpmdbNextIterator_p rpmdbNextIterator -+# define rpmtsCreate_p rpmtsCreate -+# define rpmtsFree_p rpmtsFree -+# define rpmtsInitIterator_p rpmtsInitIterator -+#endif /* !DLOPEN_LIBRPM */ -+ -+ gdb_assert (filename != NULL); -+ -+ if (strcmp (filename, BUILD_ID_MAIN_EXECUTABLE_FILENAME) == 0) -+ return 0; -+ -+ if (is_target_filename (filename)) -+ return 0; -+ -+ if (filename[0] != '/') -+ { -+ warning (_("Ignoring non-absolute filename: <%s>"), filename); -+ return 0; -+ } -+ -+ if (!rpm_init_done) -+ { -+ static int init_tried; -+ -+ /* Already failed the initialization before? */ -+ if (init_tried) -+ return 0; -+ init_tried = 1; -+ -+#ifdef DLOPEN_LIBRPM -+ { -+ void *h; -+ -+ h = dlopen (DLOPEN_LIBRPM, RTLD_LAZY); -+ if (!h) -+ { -+ warning (_("Unable to open \"%s\" (%s), " -+ "missing debuginfos notifications will not be displayed"), -+ DLOPEN_LIBRPM, dlerror ()); -+ return 0; -+ } -+ -+ if (!((headerFormat_p = (char *(*) (Header h, const char * fmt, errmsg_t *errmsg)) dlsym (h, "headerFormat")) -+ && (rpmReadConfigFiles_p = (int (*) (const char * file, const char * target)) dlsym (h, "rpmReadConfigFiles")) -+ && (rpmdbFreeIterator_p = (rpmdbMatchIterator (*) (rpmdbMatchIterator mi)) dlsym (h, "rpmdbFreeIterator")) -+ && (rpmdbNextIterator_p = (Header (*) (rpmdbMatchIterator mi)) dlsym (h, "rpmdbNextIterator")) -+ && (rpmtsCreate_p = (rpmts (*) (void)) dlsym (h, "rpmtsCreate")) -+ && (rpmtsFree_p = (rpmts (*) (rpmts ts)) dlsym (h, "rpmtsFree")) -+ && (rpmtsInitIterator_p = (rpmdbMatchIterator (*) (const rpmts ts, rpmTag rpmtag, const void *keyp, size_t keylen)) dlsym (h, "rpmtsInitIterator")))) -+ { -+ warning (_("Opened library \"%s\" is incompatible (%s), " -+ "missing debuginfos notifications will not be displayed"), -+ DLOPEN_LIBRPM, dlerror ()); -+ if (dlclose (h)) -+ warning (_("Error closing library \"%s\": %s\n"), DLOPEN_LIBRPM, -+ dlerror ()); -+ return 0; -+ } -+ } -+#endif /* DLOPEN_LIBRPM */ -+ -+ if (rpmReadConfigFiles_p (NULL, NULL) != 0) -+ { -+ warning (_("Error reading the rpm configuration files")); -+ return 0; -+ } -+ -+ rpm_init_done = 1; -+ } -+ -+ ts = rpmtsCreate_p (); -+ -+ mi = rpmtsInitIterator_p (ts, RPMTAG_BASENAMES, filename, 0); -+ if (mi != NULL) -+ { -+#ifndef GDB_INDEX_VERIFY_VENDOR -+ for (;;) -+#else -+ if (!verify_vendor) for (;;) -+#endif -+ { -+ Header h; -+ char *debuginfo, **slot, *s, *s2; -+ errmsg_t err; -+ size_t srcrpmlen = sizeof (".src.rpm") - 1; -+ size_t debuginfolen = sizeof ("-debuginfo") - 1; -+ rpmdbMatchIterator mi_debuginfo; -+ -+ h = rpmdbNextIterator_p (mi); -+ if (h == NULL) -+ break; -+ -+ /* Verify the debuginfo file is not already installed. */ -+ -+ debuginfo = headerFormat_p (h, "%{sourcerpm}-debuginfo.%{arch}", -+ &err); -+ if (!debuginfo) -+ { -+ warning (_("Error querying the rpm file `%s': %s"), filename, -+ err); -+ continue; -+ } -+ /* s = `.src.rpm-debuginfo.%{arch}' */ -+ s = strrchr (debuginfo, '-') - srcrpmlen; -+ s2 = NULL; -+ if (s > debuginfo && memcmp (s, ".src.rpm", srcrpmlen) == 0) -+ { -+ /* s2 = `-%{release}.src.rpm-debuginfo.%{arch}' */ -+ s2 = (char *) memrchr (debuginfo, '-', s - debuginfo); -+ } -+ if (s2) -+ { -+ /* s2 = `-%{version}-%{release}.src.rpm-debuginfo.%{arch}' */ -+ s2 = (char *) memrchr (debuginfo, '-', s2 - debuginfo); -+ } -+ if (!s2) -+ { -+ warning (_("Error querying the rpm file `%s': %s"), filename, -+ debuginfo); -+ xfree (debuginfo); -+ continue; -+ } -+ /* s = `.src.rpm-debuginfo.%{arch}' */ -+ /* s2 = `-%{version}-%{release}.src.rpm-debuginfo.%{arch}' */ -+ memmove (s2 + debuginfolen, s2, s - s2); -+ memcpy (s2, "-debuginfo", debuginfolen); -+ /* s = `XXXX.%{arch}' */ -+ /* strlen ("XXXX") == srcrpmlen + debuginfolen */ -+ /* s2 = `-debuginfo-%{version}-%{release}XX.%{arch}' */ -+ /* strlen ("XX") == srcrpmlen */ -+ memmove (s + debuginfolen, s + srcrpmlen + debuginfolen, -+ strlen (s + srcrpmlen + debuginfolen) + 1); -+ /* s = `-debuginfo-%{version}-%{release}.%{arch}' */ -+ -+ /* RPMDBI_PACKAGES requires keylen == sizeof (int). */ -+ /* RPMDBI_LABEL is an interface for NVR-based dbiFindByLabel(). */ -+ mi_debuginfo = rpmtsInitIterator_p (ts, (rpmTag) RPMDBI_LABEL, debuginfo, 0); -+ xfree (debuginfo); -+ if (mi_debuginfo) -+ { -+ rpmdbFreeIterator_p (mi_debuginfo); -+ count = 0; -+ break; -+ } -+ -+ /* The allocated memory gets utilized below for MISSING_RPM_HASH. */ -+ debuginfo = headerFormat_p (h, -+ "%{name}-%{version}-%{release}.%{arch}", -+ &err); -+ if (!debuginfo) -+ { -+ warning (_("Error querying the rpm file `%s': %s"), filename, -+ err); -+ continue; -+ } -+ -+ /* Base package name for `debuginfo-install'. We do not use the -+ `yum' command directly as the line -+ yum --enablerepo='*debug*' install NAME-debuginfo.ARCH -+ would be more complicated than just: -+ debuginfo-install NAME-VERSION-RELEASE.ARCH -+ Do not supply the rpm base name (derived from .src.rpm name) as -+ debuginfo-install is unable to install the debuginfo package if -+ the base name PKG binary rpm is not installed while for example -+ PKG-libs would be installed (RH Bug 467901). -+ FUTURE: After multiple debuginfo versions simultaneously installed -+ get supported the support for the VERSION-RELEASE tags handling -+ may need an update. */ -+ -+ if (missing_rpm_hash == NULL) -+ { -+ /* DEL_F is passed NULL as MISSING_RPM_LIST's HTAB_DELETE -+ should not deallocate the entries. */ -+ -+ missing_rpm_hash = htab_create_alloc (64, htab_hash_string, -+ (int (*) (const void *, const void *)) streq, -+ NULL, xcalloc, xfree); -+ } -+ slot = (char **) htab_find_slot (missing_rpm_hash, debuginfo, INSERT); -+ /* XCALLOC never returns NULL. */ -+ gdb_assert (slot != NULL); -+ if (*slot == NULL) -+ { -+ struct missing_rpm *missing_rpm; -+ -+ *slot = debuginfo; -+ -+ missing_rpm = (struct missing_rpm *) xmalloc (sizeof (*missing_rpm) + strlen (debuginfo)); -+ strcpy (missing_rpm->rpm, debuginfo); -+ missing_rpm->next = missing_rpm_list; -+ missing_rpm_list = missing_rpm; -+ missing_rpm_list_entries++; -+ } -+ else -+ xfree (debuginfo); -+ count++; -+ } -+#ifdef GDB_INDEX_VERIFY_VENDOR -+ else /* verify_vendor */ -+ { -+ int vendor_pass = 0, vendor_fail = 0; -+ -+ for (;;) -+ { -+ Header h; -+ errmsg_t err; -+ char *vendor; -+ -+ h = rpmdbNextIterator_p (mi); -+ if (h == NULL) -+ break; -+ -+ vendor = headerFormat_p (h, "%{vendor}", &err); -+ if (!vendor) -+ { -+ warning (_("Error querying the rpm file `%s': %s"), filename, -+ err); -+ continue; -+ } -+ if (strcmp (vendor, "Red Hat, Inc.") == 0) -+ vendor_pass = 1; -+ else -+ vendor_fail = 1; -+ xfree (vendor); -+ } -+ count = vendor_pass != 0 && vendor_fail == 0; -+ } -+#endif -+ -+ rpmdbFreeIterator_p (mi); -+ } -+ -+ rpmtsFree_p (ts); -+ -+ return count; -+} -+ -+#ifdef GDB_INDEX_VERIFY_VENDOR -+missing_rpm_enlist (const char *filename) -+{ -+ return missing_rpm_enlist_1 (filename, 0); -+} -+ -+extern int rpm_verify_vendor (const char *filename); -+int -+rpm_verify_vendor (const char *filename) -+{ -+ return missing_rpm_enlist_1 (filename, 1); -+} -+#endif -+ -+static bool -+missing_rpm_list_compar (const char *ap, const char *bp) -+{ -+ return strcoll (ap, bp) < 0; -+} -+ -+/* It returns a NULL-terminated array of strings needing to be FREEd. It may -+ also return only NULL. */ -+ -+static void -+missing_rpm_list_print (void) -+{ -+ struct missing_rpm *list_iter; -+ -+ if (missing_rpm_list_entries == 0) -+ return; -+ -+ std::vector array (missing_rpm_list_entries); -+ size_t idx = 0; -+ -+ for (list_iter = missing_rpm_list; list_iter != NULL; -+ list_iter = list_iter->next) -+ { -+ array[idx++] = list_iter->rpm; -+ } -+ gdb_assert (idx == missing_rpm_list_entries); -+ -+ std::sort (array.begin (), array.end (), missing_rpm_list_compar); -+ -+ /* We zero out the number of missing RPMs here because of a nasty -+ bug (see RHBZ 1801974). -+ -+ When we call 'puts_unfiltered' below, if pagination is on and if -+ the number of missing RPMs is big enough to trigger pagination, -+ we will end up in an infinite recursion. The call chain looks -+ like this: -+ -+ missing_rpm_list_print -> puts_unfiltered -> fputs_maybe_filtered -+ -> prompt_for_continue -> display_gdb_prompt -> -+ debug_flush_missing -> missing_rpm_list_print ... -+ -+ For this reason, we make sure MISSING_RPM_LIST_ENTRIES is zero -+ *before* calling any print function. -+ -+ Note: kevinb/2023-02-22: The code below used to call -+ puts_unfiltered() and printf_unfiltered(), but calls to these -+ functions have been replaced by calls to gdb_printf(). The call -+ chain shown above (probably) used to be the case at one time and -+ hopefully something similar is still the case now that -+ gdb_printf() is being used instead. */ -+ missing_rpm_list_entries = 0; -+ -+ gdb_printf (_("Missing separate debuginfos, use: %s"), -+#ifdef DNF_DEBUGINFO_INSTALL -+ "dnf " -+#endif -+ "debuginfo-install"); -+ for (const char *el : array) -+ { -+ gdb_printf (" %s", el); -+ } -+ gdb_printf ("\n"); -+ -+ while (missing_rpm_list != NULL) -+ { -+ list_iter = missing_rpm_list; -+ missing_rpm_list = list_iter->next; -+ xfree (list_iter); -+ } -+} -+ -+static void -+missing_rpm_change (void) -+{ -+ debug_flush_missing (); -+ -+ gdb_assert (missing_rpm_list == NULL); -+ if (missing_rpm_hash != NULL) -+ { -+ htab_delete (missing_rpm_hash); -+ missing_rpm_hash = NULL; -+ } -+} -+ -+enum missing_exec -+ { -+ /* Init state. EXEC_BFD also still could be NULL. */ -+ MISSING_EXEC_NOT_TRIED, -+ /* We saw a non-NULL EXEC_BFD but RPM has no info about it. */ -+ MISSING_EXEC_NOT_FOUND, -+ /* We found EXEC_BFD by RPM and we either have its symbols (either embedded -+ or separate) or the main executable's RPM is now contained in -+ MISSING_RPM_HASH. */ -+ MISSING_EXEC_ENLISTED -+ }; -+static enum missing_exec missing_exec = MISSING_EXEC_NOT_TRIED; -+ -+#endif /* HAVE_LIBRPM */ -+ -+void -+debug_flush_missing (void) -+{ -+#ifdef HAVE_LIBRPM -+ missing_rpm_list_print (); -+#endif -+} -+ -+/* This MISSING_FILEPAIR_HASH tracker is used only for the duplicite messages -+ yum --enablerepo='*debug*' install ... -+ avoidance. */ -+ -+struct missing_filepair -+ { -+ char *binary; -+ char *debug; -+ char data[1]; -+ }; -+ -+static struct htab *missing_filepair_hash; -+static struct obstack missing_filepair_obstack; -+ -+static void * -+missing_filepair_xcalloc (size_t nmemb, size_t nmemb_size) -+{ -+ void *retval; -+ size_t size = nmemb * nmemb_size; -+ -+ retval = obstack_alloc (&missing_filepair_obstack, size); -+ memset (retval, 0, size); -+ return retval; -+} -+ -+static hashval_t -+missing_filepair_hash_func (const struct missing_filepair *elem) -+{ -+ hashval_t retval = 0; -+ -+ retval ^= htab_hash_string (elem->binary); -+ if (elem->debug != NULL) -+ retval ^= htab_hash_string (elem->debug); -+ -+ return retval; -+} -+ -+static int -+missing_filepair_eq (const struct missing_filepair *elem1, -+ const struct missing_filepair *elem2) -+{ -+ return strcmp (elem1->binary, elem2->binary) == 0 -+ && ((elem1->debug == NULL) == (elem2->debug == NULL)) -+ && (elem1->debug == NULL || strcmp (elem1->debug, elem2->debug) == 0); -+} -+ -+static void -+missing_filepair_change (void) -+{ -+ if (missing_filepair_hash != NULL) -+ { -+ obstack_free (&missing_filepair_obstack, NULL); -+ /* All their memory came just from missing_filepair_OBSTACK. */ -+ missing_filepair_hash = NULL; -+ } -+#ifdef HAVE_LIBRPM -+ missing_exec = MISSING_EXEC_NOT_TRIED; -+#endif -+} -+ -+static void -+debug_print_executable_changed (struct program_space *pspace, bool reload_p) -+{ -+#ifdef HAVE_LIBRPM -+ missing_rpm_change (); -+#endif -+ missing_filepair_change (); -+} -+ -+/* Notify user the file BINARY with (possibly NULL) associated separate debug -+ information file DEBUG is missing. DEBUG may or may not be the build-id -+ file such as would be: -+ /usr/lib/debug/.build-id/dd/b1d2ce632721c47bb9e8679f369e2295ce71be.debug -+ */ -+ -+void -+debug_print_missing (const char *binary, const char *debug) -+{ -+ size_t binary_len0 = strlen (binary) + 1; -+ size_t debug_len0 = debug ? strlen (debug) + 1 : 0; -+ struct missing_filepair missing_filepair_find; -+ struct missing_filepair *missing_filepair; -+ struct missing_filepair **slot; -+ -+ if (build_id_verbose < BUILD_ID_VERBOSE_FILENAMES) -+ return; -+ -+ if (missing_filepair_hash == NULL) -+ { -+ obstack_init (&missing_filepair_obstack); -+ missing_filepair_hash = htab_create_alloc (64, -+ (hashval_t (*) (const void *)) missing_filepair_hash_func, -+ (int (*) (const void *, const void *)) missing_filepair_eq, NULL, -+ missing_filepair_xcalloc, NULL); -+ } -+ -+ /* Use MISSING_FILEPAIR_FIND first instead of calling obstack_alloc with -+ obstack_free in the case of a (rare) match. The problem is ALLOC_F for -+ MISSING_FILEPAIR_HASH allocates from MISSING_FILEPAIR_OBSTACK maintenance -+ structures for MISSING_FILEPAIR_HASH. Calling obstack_free would possibly -+ not to free only MISSING_FILEPAIR but also some such structures (allocated -+ during the htab_find_slot call). */ -+ -+ missing_filepair_find.binary = (char *) binary; -+ missing_filepair_find.debug = (char *) debug; -+ slot = (struct missing_filepair **) htab_find_slot (missing_filepair_hash, -+ &missing_filepair_find, -+ INSERT); -+ -+ /* While it may be still printed duplicitely with the missing debuginfo file -+ * it is due to once printing about the binary file build-id link and once -+ * about the .debug file build-id link as both the build-id symlinks are -+ * located in the debuginfo package. */ -+ -+ if (*slot != NULL) -+ return; -+ -+ missing_filepair = (struct missing_filepair *) obstack_alloc (&missing_filepair_obstack, -+ sizeof (*missing_filepair) - 1 -+ + binary_len0 + debug_len0); -+ missing_filepair->binary = missing_filepair->data; -+ memcpy (missing_filepair->binary, binary, binary_len0); -+ if (debug != NULL) -+ { -+ missing_filepair->debug = missing_filepair->binary + binary_len0; -+ memcpy (missing_filepair->debug, debug, debug_len0); -+ } -+ else -+ missing_filepair->debug = NULL; -+ -+ *slot = missing_filepair; -+ -+#ifdef HAVE_LIBRPM -+ if (missing_exec == MISSING_EXEC_NOT_TRIED) -+ { -+ const char *execfilename = get_exec_file (0); -+ -+ if (execfilename != NULL) -+ { -+ if (missing_rpm_enlist (execfilename) == 0) -+ missing_exec = MISSING_EXEC_NOT_FOUND; -+ else -+ missing_exec = MISSING_EXEC_ENLISTED; -+ } -+ } -+ if (missing_exec != MISSING_EXEC_ENLISTED) -+ if ((binary[0] == 0 || missing_rpm_enlist (binary) == 0) -+ && (debug == NULL || missing_rpm_enlist (debug) == 0)) -+#endif /* HAVE_LIBRPM */ -+ { -+ /* We do not collect and flush these messages as each such message -+ already requires its own separate lines. */ -+ -+ gdb_printf (gdb_stdlog, -+ _("Missing separate debuginfo for %s.\n"), binary); -+ if (debug != NULL) -+ { -+ if (access (debug, F_OK) == 0) { -+ gdb_printf (gdb_stdlog, _("Try: %s %s\n"), -+#ifdef DNF_DEBUGINFO_INSTALL -+ "dnf" -+#else -+ "yum" -+#endif -+ " --enablerepo='*debug*' install", debug); -+ } else -+ gdb_printf (gdb_stdlog, _("The debuginfo package for this file is probably broken.\n")); -+ } -+ } -+} -+ - /* See build-id.h. */ - - gdb_bfd_ref_ptr --build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id) -+build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id, -+ char **link_return) - { -- return build_id_to_bfd_suffix (build_id_len, build_id, ".debug"); -+ return build_id_to_bfd_suffix (build_id_len, build_id, ".debug", -+ link_return); - } - - /* See build-id.h. */ - - gdb_bfd_ref_ptr --build_id_to_exec_bfd (size_t build_id_len, const bfd_byte *build_id) -+build_id_to_exec_bfd (size_t build_id_len, const bfd_byte *build_id, -+ char **link_return) - { -- return build_id_to_bfd_suffix (build_id_len, build_id, ""); -+ return build_id_to_bfd_suffix (build_id_len, build_id, "", link_return); - } - - /* See build-id.h. */ - - std::string - find_separate_debug_file_by_buildid (struct objfile *objfile, -- deferred_warnings *warnings) -+ deferred_warnings *warnings, -+ gdb::unique_xmalloc_ptr *build_id_filename_return) - { - const struct bfd_build_id *build_id; - -- build_id = build_id_bfd_get (objfile->obfd.get ()); -+ if (build_id_filename_return) -+ *build_id_filename_return = NULL; -+ -+ build_id = build_id_bfd_shdr_get (objfile->obfd.get ()); - if (build_id != NULL) - { - if (separate_debug_file_debug) -@@ -222,8 +1358,21 @@ find_separate_debug_file_by_buildid (struct objfile *objfile, - _("\nLooking for separate debug info (build-id) for " - "%s\n"), objfile_name (objfile)); - -+ char *build_id_filename_cstr = NULL; - gdb_bfd_ref_ptr abfd (build_id_to_debug_bfd (build_id->size, -- build_id->data)); -+ build_id->data, -+ (!build_id_filename_return ? NULL : &build_id_filename_cstr))); -+ if (build_id_filename_return) -+ { -+ if (!build_id_filename_cstr) -+ gdb_assert (!*build_id_filename_return); -+ else -+ { -+ *build_id_filename_return = gdb::unique_xmalloc_ptr (build_id_filename_cstr); -+ build_id_filename_cstr = NULL; -+ } -+ } -+ - /* Prevent looping on a stripped .debug file. */ - if (abfd != NULL - && filename_cmp (bfd_get_filename (abfd.get ()), -@@ -243,3 +1392,22 @@ find_separate_debug_file_by_buildid (struct objfile *objfile, - - return std::string (); - } -+ -+void _initialize_build_id (); -+ -+void -+_initialize_build_id () -+{ -+ add_setshow_zinteger_cmd ("build-id-verbose", no_class, &build_id_verbose, -+ _("\ -+Set debugging level of the build-id locator."), _("\ -+Show debugging level of the build-id locator."), _("\ -+Level 1 (default) enables printing the missing debug filenames,\n\ -+level 2 also prints the parsing of binaries to find the identificators."), -+ NULL, -+ show_build_id_verbose, -+ &setlist, &showlist); -+ -+ gdb::observers::executable_changed.attach (debug_print_executable_changed, -+ "build-id"); -+} -diff --git a/gdb/build-id.h b/gdb/build-id.h ---- a/gdb/build-id.h -+++ b/gdb/build-id.h -@@ -23,9 +23,10 @@ - #include "gdb_bfd.h" - #include "gdbsupport/rsp-low.h" - --/* Locate NT_GNU_BUILD_ID from ABFD and return its content. */ -+/* Separate debuginfo files have corrupted PHDR but SHDR is correct there. -+ Locate NT_GNU_BUILD_ID from ABFD and return its content. */ - --extern const struct bfd_build_id *build_id_bfd_get (bfd *abfd); -+extern const struct bfd_build_id *build_id_bfd_shdr_get (bfd *abfd); - - /* Return true if ABFD has NT_GNU_BUILD_ID matching the CHECK value. - Otherwise, issue a warning and return false. */ -@@ -38,14 +39,19 @@ extern int build_id_verify (bfd *abfd, - can be found, return NULL. */ - - extern gdb_bfd_ref_ptr build_id_to_debug_bfd (size_t build_id_len, -- const bfd_byte *build_id); -+ const bfd_byte *build_id, -+ char **link_return = NULL); -+ -+extern char *build_id_to_filename (const struct bfd_build_id *build_id, -+ char **link_return); - - /* Find and open a BFD for an executable file given a build-id. If no BFD - can be found, return NULL. The returned reference to the BFD must be - released by the caller. */ - - extern gdb_bfd_ref_ptr build_id_to_exec_bfd (size_t build_id_len, -- const bfd_byte *build_id); -+ const bfd_byte *build_id, -+ char **link_return); - - /* Find the separate debug file for OBJFILE, by using the build-id - associated with OBJFILE's BFD. If successful, returns the file name for the -@@ -58,7 +64,8 @@ extern gdb_bfd_ref_ptr build_id_to_exec_bfd (size_t build_id_len, - will be printed. */ - - extern std::string find_separate_debug_file_by_buildid -- (struct objfile *objfile, deferred_warnings *warnings); -+ (struct objfile *objfile, deferred_warnings *warnings, -+ gdb::unique_xmalloc_ptr *build_id_filename_return); - - /* Return an hex-string representation of BUILD_ID. */ - -diff --git a/gdb/coffread.c b/gdb/coffread.c ---- a/gdb/coffread.c -+++ b/gdb/coffread.c -@@ -729,7 +729,7 @@ coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) - { - deferred_warnings warnings; - std::string debugfile -- = find_separate_debug_file_by_buildid (objfile, &warnings); -+ = find_separate_debug_file_by_buildid (objfile, &warnings, NULL); - - if (debugfile.empty ()) - debugfile -diff --git a/gdb/corelow.c b/gdb/corelow.c ---- a/gdb/corelow.c -+++ b/gdb/corelow.c -@@ -22,6 +22,10 @@ - #include - #include - #include "frame.h" -+#include "auxv.h" -+#include "build-id.h" -+#include "elf/common.h" -+#include "gdbcmd.h" - #include "inferior.h" - #include "infrun.h" - #include "symtab.h" -@@ -380,6 +384,8 @@ add_to_thread_list (asection *asect, asection *reg_sect, inferior *inf) - switch_to_thread (thr); /* Yes, make it current. */ - } - -+static bool build_id_core_loads = true; -+ - /* Issue a message saying we have no core to debug, if FROM_TTY. */ - - static void -@@ -563,12 +569,14 @@ rename_vmcore_idle_reg_sections (bfd *abfd, inferior *inf) - static void - locate_exec_from_corefile_build_id (bfd *abfd, int from_tty) - { -- const bfd_build_id *build_id = build_id_bfd_get (abfd); -+ const bfd_build_id *build_id = build_id_bfd_shdr_get (abfd); - if (build_id == nullptr) - return; - -+ char *build_id_filename; - gdb_bfd_ref_ptr execbfd -- = build_id_to_exec_bfd (build_id->size, build_id->data); -+ = build_id_to_exec_bfd (build_id->size, build_id->data, -+ &build_id_filename); - - if (execbfd == nullptr) - { -@@ -596,7 +604,12 @@ locate_exec_from_corefile_build_id (bfd *abfd, int from_tty) - exec_file_attach (bfd_get_filename (execbfd.get ()), from_tty); - symbol_file_add_main (bfd_get_filename (execbfd.get ()), - symfile_add_flag (from_tty ? SYMFILE_VERBOSE : 0)); -+ if (current_program_space->symfile_object_file != NULL) -+ current_program_space->symfile_object_file->flags |= -+ OBJF_BUILD_ID_CORE_LOADED; - } -+ else -+ debug_print_missing (BUILD_ID_MAIN_EXECUTABLE_FILENAME, build_id_filename); - } - - /* See gdbcore.h. */ -@@ -1506,4 +1519,11 @@ _initialize_corelow () - maintenance_print_core_file_backed_mappings, - _("Print core file's file-backed mappings."), - &maintenanceprintlist); -+ -+ add_setshow_boolean_cmd ("build-id-core-loads", class_files, -+ &build_id_core_loads, _("\ -+Set whether CORE-FILE loads the build-id associated files automatically."), _("\ -+Show whether CORE-FILE loads the build-id associated files automatically."), -+ NULL, NULL, NULL, -+ &setlist, &showlist); - } -diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo ---- a/gdb/doc/gdb.texinfo -+++ b/gdb/doc/gdb.texinfo -@@ -22296,6 +22296,27 @@ information files. - - @end table - -+You can also adjust the current verbosity of the @dfn{build id} locating. -+ -+@table @code -+ -+@kindex set build-id-verbose -+@item set build-id-verbose 0 -+No additional messages are printed. -+ -+@item set build-id-verbose 1 -+Missing separate debug filenames are printed. -+ -+@item set build-id-verbose 2 -+Missing separate debug filenames are printed and also all the parsing of the -+binaries to find their @dfn{build id} content is printed. -+ -+@kindex show build-id-verbose -+@item show build-id-verbose -+Show the current verbosity value for the @dfn{build id} content locating. -+ -+@end table -+ - @cindex @code{.gnu_debuglink} sections - @cindex debug link sections - A debug link is a special section of the executable file named -diff --git a/gdb/dwarf2/index-cache.c b/gdb/dwarf2/index-cache.c ---- a/gdb/dwarf2/index-cache.c -+++ b/gdb/dwarf2/index-cache.c -@@ -96,7 +96,7 @@ index_cache_store_context::index_cache_store_context (const index_cache &ic, - return; - - /* Get build id of objfile. */ -- const bfd_build_id *build_id = build_id_bfd_get (per_bfd->obfd); -+ const bfd_build_id *build_id = build_id_bfd_shdr_get (per_bfd->obfd); - if (build_id == nullptr) - { - index_cache_debug ("objfile %s has no build id", -@@ -111,7 +111,8 @@ index_cache_store_context::index_cache_store_context (const index_cache &ic, - - if (dwz != nullptr) - { -- const bfd_build_id *dwz_build_id = build_id_bfd_get (dwz->dwz_bfd.get ()); -+ const bfd_build_id *dwz_build_id -+ = build_id_bfd_shdr_get (dwz->dwz_bfd.get ()); - - if (dwz_build_id == nullptr) - { -diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c ---- a/gdb/dwarf2/read.c -+++ b/gdb/dwarf2/read.c -@@ -3355,7 +3355,7 @@ get_gdb_index_contents_from_section (objfile *obj, T *section_owner) - static gdb::array_view - get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_bfd *dwarf2_per_bfd) - { -- const bfd_build_id *build_id = build_id_bfd_get (obj->obfd.get ()); -+ const bfd_build_id *build_id = build_id_bfd_shdr_get (obj->obfd.get ()); - if (build_id == nullptr) - return {}; - -@@ -3368,7 +3368,7 @@ get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_bfd *dwarf2_per_bfd) - static gdb::array_view - get_gdb_index_contents_from_cache_dwz (objfile *obj, dwz_file *dwz) - { -- const bfd_build_id *build_id = build_id_bfd_get (dwz->dwz_bfd.get ()); -+ const bfd_build_id *build_id = build_id_bfd_shdr_get (dwz->dwz_bfd.get ()); - if (build_id == nullptr) - return {}; - -diff --git a/gdb/elfread.c b/gdb/elfread.c ---- a/gdb/elfread.c -+++ b/gdb/elfread.c -@@ -1220,8 +1220,10 @@ elf_symfile_read_dwarf2 (struct objfile *objfile, - { - deferred_warnings warnings; - -+ gdb::unique_xmalloc_ptr build_id_filename; - std::string debugfile -- = find_separate_debug_file_by_buildid (objfile, &warnings); -+ = find_separate_debug_file_by_buildid (objfile, &warnings, -+ &build_id_filename); - - if (debugfile.empty ()) - debugfile = find_separate_debug_file_by_debuglink (objfile, &warnings); -@@ -1239,7 +1241,7 @@ elf_symfile_read_dwarf2 (struct objfile *objfile, - { - has_dwarf2 = false; - const struct bfd_build_id *build_id -- = build_id_bfd_get (objfile->obfd.get ()); -+ = build_id_bfd_shdr_get (objfile->obfd.get ()); - const char *filename = bfd_get_filename (objfile->obfd.get ()); - - if (build_id != nullptr) -@@ -1265,6 +1267,11 @@ elf_symfile_read_dwarf2 (struct objfile *objfile, - has_dwarf2 = true; - } - } -+ /* Check if any separate debug info has been extracted out. */ -+ else if (bfd_get_section_by_name (objfile->obfd.get (), -+ ".gnu_debuglink") -+ != NULL) -+ debug_print_missing (objfile_name (objfile), build_id_filename.get ()); - } - } - /* If all the methods to collect the debuginfo failed, print the -diff --git a/gdb/exec.c b/gdb/exec.c ---- a/gdb/exec.c -+++ b/gdb/exec.c -@@ -237,7 +237,7 @@ validate_exec_file (int from_tty) - current_exec_file = get_exec_file (0); - - const bfd_build_id *exec_file_build_id -- = build_id_bfd_get (current_program_space->exec_bfd ()); -+ = build_id_bfd_shdr_get (current_program_space->exec_bfd ()); - if (exec_file_build_id != nullptr) - { - /* Prepend the target prefix, to force gdb_bfd_open to open the -@@ -250,7 +250,7 @@ validate_exec_file (int from_tty) - if (abfd != nullptr) - { - const bfd_build_id *target_exec_file_build_id -- = build_id_bfd_get (abfd.get ()); -+ = build_id_bfd_shdr_get (abfd.get ()); - - if (target_exec_file_build_id != nullptr) - { -diff --git a/gdb/objfiles.h b/gdb/objfiles.h ---- a/gdb/objfiles.h -+++ b/gdb/objfiles.h -@@ -884,6 +884,10 @@ struct objfile - bool object_format_has_copy_relocs = false; - }; - -+/* This file was loaded according to the BUILD_ID_CORE_LOADS rules. */ -+ -+#define OBJF_BUILD_ID_CORE_LOADED static_cast(1 << 12) -+ - /* A deleter for objfile. */ - - struct objfile_deleter -diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c ---- a/gdb/python/py-objfile.c -+++ b/gdb/python/py-objfile.c -@@ -158,7 +158,7 @@ objfpy_get_build_id (PyObject *self, void *closure) - - try - { -- build_id = build_id_bfd_get (objfile->obfd.get ()); -+ build_id = build_id_bfd_shdr_get (objfile->obfd.get ()); - } - catch (const gdb_exception &except) - { -@@ -629,7 +629,7 @@ gdbpy_lookup_objfile (PyObject *self, PyObject *args, PyObject *kw) - if (obfd == nullptr) - return 0; - -- const bfd_build_id *obfd_build_id = build_id_bfd_get (obfd); -+ const bfd_build_id *obfd_build_id = build_id_bfd_shdr_get (obfd); - if (obfd_build_id == nullptr) - return 0; - -diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c ---- a/gdb/solib-svr4.c -+++ b/gdb/solib-svr4.c -@@ -44,6 +44,7 @@ - #include "auxv.h" - #include "gdb_bfd.h" - #include "probe.h" -+#include "build-id.h" - - #include - -@@ -1318,9 +1319,51 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm, - continue; - } - -- strncpy (newobj->so_name, buffer.get (), SO_NAME_MAX_PATH_SIZE - 1); -- newobj->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; -- strcpy (newobj->so_original_name, newobj->so_name); -+ { -+ struct bfd_build_id *build_id; -+ -+ strncpy (newobj->so_original_name, buffer.get (), SO_NAME_MAX_PATH_SIZE - 1); -+ newobj->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; -+ /* May get overwritten below. */ -+ strcpy (newobj->so_name, newobj->so_original_name); -+ -+ build_id = build_id_addr_get (((lm_info_svr4 *) newobj->lm_info)->l_ld); -+ if (build_id != NULL) -+ { -+ char *name, *build_id_filename; -+ -+ /* Missing the build-id matching separate debug info file -+ would be handled while SO_NAME gets loaded. */ -+ name = build_id_to_filename (build_id, &build_id_filename); -+ if (name != NULL) -+ { -+ strncpy (newobj->so_name, name, SO_NAME_MAX_PATH_SIZE - 1); -+ newobj->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; -+ xfree (name); -+ } -+ else -+ { -+ debug_print_missing (newobj->so_name, build_id_filename); -+ -+ /* In the case the main executable was found according to -+ its build-id (from a core file) prevent loading -+ a different build of a library with accidentally the -+ same SO_NAME. -+ -+ It suppresses bogus backtraces (and prints "??" there -+ instead) if the on-disk files no longer match the -+ running program version. */ -+ -+ if (current_program_space->symfile_object_file != NULL -+ && (current_program_space->symfile_object_file->flags -+ & OBJF_BUILD_ID_CORE_LOADED) != 0) -+ newobj->so_name[0] = 0; -+ } -+ -+ xfree (build_id_filename); -+ xfree (build_id); -+ } -+ } - - /* If this entry has no name, or its name matches the name - for the main executable, don't include it in the list. */ -diff --git a/gdb/source.c b/gdb/source.c ---- a/gdb/source.c -+++ b/gdb/source.c -@@ -1167,7 +1167,7 @@ open_source_file (struct symtab *s) - } - - const struct bfd_build_id *build_id -- = build_id_bfd_get (ofp->obfd.get ()); -+ = build_id_bfd_shdr_get (ofp->obfd.get ()); - - /* Query debuginfod for the source file. */ - if (build_id != nullptr && !srcpath.empty ()) -diff --git a/gdb/symfile.h b/gdb/symfile.h ---- a/gdb/symfile.h -+++ b/gdb/symfile.h -@@ -357,12 +357,18 @@ bool expand_symtabs_matching - void map_symbol_filenames (gdb::function_view fun, - bool need_fullname); - -+ - /* Target-agnostic function to load the sections of an executable into memory. - - ARGS should be in the form "EXECUTABLE [OFFSET]", where OFFSET is an - optional offset to apply to each section. */ - extern void generic_load (const char *args, int from_tty); - -+/* build-id support. */ -+extern struct bfd_build_id *build_id_addr_get (CORE_ADDR addr); -+extern void debug_print_missing (const char *binary, const char *debug); -+#define BUILD_ID_MAIN_EXECUTABLE_FILENAME _("the main executable file") -+ - /* From minidebug.c. */ - - extern gdb_bfd_ref_ptr find_separate_debug_file_in_section (struct objfile *); -diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp ---- a/gdb/testsuite/gdb.base/corefile.exp -+++ b/gdb/testsuite/gdb.base/corefile.exp -@@ -347,3 +347,33 @@ gdb_test_multiple "core-file $corefile" $test { - pass $test - } - } -+ -+ -+# Test auto-loading of binary files through build-id from the core file. -+set buildid [build_id_debug_filename_get $binfile] -+set wholetest "binfile found by build-id" -+if {$buildid == ""} { -+ untested "$wholetest (binary has no build-id)" -+} else { -+ gdb_exit -+ gdb_start -+ -+ regsub {\.debug$} $buildid {} buildid -+ set debugdir [standard_output_file ${testfile}-debugdir] -+ file delete -force -- $debugdir -+ file mkdir $debugdir/[file dirname $buildid] -+ file copy $binfile $debugdir/$buildid -+ -+ set test "show debug-file-directory" -+ gdb_test_multiple $test $test { -+ -re "The directory where separate debug symbols are searched for is \"(.*)\"\\.\r\n$gdb_prompt $" { -+ set debugdir_orig $expect_out(1,string) -+ pass $test -+ } -+ } -+ gdb_test_no_output "set debug-file-directory $debugdir:$debugdir_orig" "set debug-file-directory" -+ gdb_test "show build-id-core-loads" {Whether CORE-FILE loads the build-id associated files automatically is on\.} -+ gdb_test "core-file $corefile" "\r\nProgram terminated with .*" "core-file without executable" -+ gdb_test "info files" "Local exec file:\r\n\[ \t\]*`[string_to_regexp $debugdir/$buildid]', file type .*" -+ pass $wholetest -+} -diff --git a/gdb/testsuite/gdb.base/gdbinit-history.exp b/gdb/testsuite/gdb.base/gdbinit-history.exp ---- a/gdb/testsuite/gdb.base/gdbinit-history.exp -+++ b/gdb/testsuite/gdb.base/gdbinit-history.exp -@@ -179,7 +179,8 @@ proc test_empty_history_filename { } { - global env - global gdb_prompt - -- set common_history [list "set height 0" "set width 0"] -+ set common_history [list "set height 0" "set width 0" \ -+ "set build-id-verbose 0"] - - set test_dir [standard_output_file history_test] - remote_exec host "mkdir -p $test_dir" -diff --git a/gdb/testsuite/gdb.base/new-ui-pending-input.exp b/gdb/testsuite/gdb.base/new-ui-pending-input.exp ---- a/gdb/testsuite/gdb.base/new-ui-pending-input.exp -+++ b/gdb/testsuite/gdb.base/new-ui-pending-input.exp -@@ -62,6 +62,7 @@ proc test_command_line_new_ui_pending_input {} { - set options "" - append options " -iex \"set height 0\"" - append options " -iex \"set width 0\"" -+ append options " -iex \"set build-id-verbose 0\"" - append options " -iex \"new-ui console $extra_tty_name\"" - append options " -ex \"b $bpline\"" - append options " -ex \"run\"" -diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp ---- a/gdb/testsuite/lib/gdb.exp -+++ b/gdb/testsuite/lib/gdb.exp -@@ -226,7 +226,8 @@ if ![info exists INTERNAL_GDBFLAGS] { - "-nx" \ - "-q" \ - {-iex "set height 0"} \ -- {-iex "set width 0"}]] -+ {-iex "set width 0"} \ -+ {-iex "set build-id-verbose 0"}]] - - # If DEBUGINFOD_URLS is set, gdb will try to download sources and - # debug info for f.i. system libraries. Prevent this. -@@ -2434,6 +2435,17 @@ proc default_gdb_start { } { - } - } - -+ # Turn off the missing warnings as the testsuite does not expect it. -+ send_gdb "set build-id-verbose 0\n" -+ gdb_expect 10 { -+ -re "$gdb_prompt $" { -+ verbose "Disabled the missing debug infos warnings." 2 -+ } -+ timeout { -+ warning "Could not disable the missing debug infos warnings.." -+ } -+ } -+ - gdb_debug_init - return 0 - } -diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp ---- a/gdb/testsuite/lib/mi-support.exp -+++ b/gdb/testsuite/lib/mi-support.exp -@@ -321,6 +321,16 @@ proc default_mi_gdb_start { { flags {} } } { - warning "Couldn't set the width to 0." - } - } -+ # Turn off the missing warnings as the testsuite does not expect it. -+ send_gdb "190-gdb-set build-id-verbose 0\n" -+ gdb_expect 10 { -+ -re ".*190-gdb-set build-id-verbose 0\r\n190\\\^done\r\n$mi_gdb_prompt$" { -+ verbose "Disabled the missing debug infos warnings." 2 -+ } -+ timeout { -+ warning "Could not disable the missing debug infos warnings.." -+ } -+ } - - if { $separate_inferior_pty } { - mi_create_inferior_pty diff --git a/gdb-6.6-bz229517-gcore-without-terminal.patch b/gdb-6.6-bz229517-gcore-without-terminal.patch deleted file mode 100644 index 863f615..0000000 --- a/gdb-6.6-bz229517-gcore-without-terminal.patch +++ /dev/null @@ -1,188 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Jan Kratochvil -Date: Fri, 27 Oct 2017 21:07:50 +0200 -Subject: gdb-6.6-bz229517-gcore-without-terminal.patch - -;; Allow running `/usr/bin/gcore' with provided but inaccessible tty (BZ 229517). -;;=fedoratest - -2007-04-22 Jan Kratochvil - - * gdb_gcore.sh: Redirect GDB from ` - - * gdb.base/gcorebg.exp, gdb.base/gcorebg.c: New files. - -diff --git a/gdb/testsuite/gdb.base/gcorebg.c b/gdb/testsuite/gdb.base/gcorebg.c -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.base/gcorebg.c -@@ -0,0 +1,49 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+int main (int argc, char **argv) -+{ -+ pid_t pid = 0; -+ pid_t ppid; -+ char buf[1024*2 + 500]; -+ int gotint; -+ -+ if (argc != 4) -+ { -+ fprintf (stderr, "Syntax: %s {standard|detached} \n", -+ argv[0]); -+ exit (1); -+ } -+ -+ pid = fork (); -+ -+ switch (pid) -+ { -+ case 0: -+ if (strcmp (argv[1], "detached") == 0) -+ setpgrp (); -+ ppid = getppid (); -+ gotint = snprintf (buf, sizeof (buf), "sh %s -o %s %d", argv[2], argv[3], (int) ppid); -+ assert (gotint < sizeof (buf)); -+ system (buf); -+ fprintf (stderr, "Killing parent PID %d\n", ppid); -+ kill (ppid, SIGTERM); -+ break; -+ -+ case -1: -+ perror ("fork err\n"); -+ exit (1); -+ break; -+ -+ default: -+ fprintf (stderr,"Sleeping as PID %d\n", getpid ()); -+ sleep (60); -+ } -+ -+ return 0; -+} -diff --git a/gdb/testsuite/gdb.base/gcorebg.exp b/gdb/testsuite/gdb.base/gcorebg.exp -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.base/gcorebg.exp -@@ -0,0 +1,113 @@ -+# Copyright 2007 Free Software Foundation, Inc. -+ -+# 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 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ -+# Please email any bugs, comments, and/or additions to this file to: -+# bug-gdb@prep.ai.mit.edu -+ -+# This file was written by Jan Kratochvil . -+# This is a test for `gdb_gcore.sh' functionality. -+# It also tests a regression with `gdb_gcore.sh' being run without its -+# accessible terminal. -+ -+if ![info exists GCORE] { -+ set GCORE "[standard_output_file ../../../../gcore]" -+} -+verbose "using GCORE = $GCORE" 2 -+ -+set testfile "gcorebg" -+set srcfile ${testfile}.c -+set binfile [standard_output_file ${testfile}] -+set corefile [standard_output_file ${testfile}.test] -+ -+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { -+ untested gcorebg.exp -+ return -1 -+} -+ -+# Cleanup. -+ -+proc core_clean {} { -+ global corefile -+ -+ foreach file [glob -nocomplain [join [list $corefile *] ""]] { -+ verbose "Delete file $file" 1 -+ remote_file target delete $file -+ } -+} -+core_clean -+remote_file target delete "./gdb" -+ -+# Generate the core file. -+ -+# Provide `./gdb' for `gdb_gcore.sh' running it as a bare `gdb' command. -+# Setup also `$PATH' appropriately. -+# If GDB was not found let `gdb_gcore.sh' to find the system GDB by `$PATH'. -+if {$GDB != "gdb"} { -+ file link ./gdb $GDB -+} -+global env -+set oldpath $env(PATH) -+set env(PATH) [join [list . $env(PATH)] ":"] -+verbose "PATH = $env(PATH)" 2 -+ -+# Test file body. -+# $detached == "standard" || $detached == "detached" -+ -+proc test_body { detached } { -+ global binfile -+ global GCORE -+ global corefile -+ -+ set res [remote_spawn target "$binfile $detached $GCORE $corefile"] -+ if { $res < 0 || $res == "" } { -+ fail "Spawning $detached gcore" -+ return 1 -+ } -+ pass "Spawning $detached gcore" -+ remote_expect target 20 { -+ timeout { -+ fail "Spawned $detached gcore finished (timeout)" -+ remote_exec target "kill -9 -[exp_pid -i $res]" -+ return 1 -+ } -+ "Saved corefile .*\r\nKilling parent PID " { -+ pass "Spawned $detached gcore finished" -+ remote_wait target 20 -+ } -+ } -+ -+ if {1 == [llength [glob -nocomplain [join [list $corefile *] ""]]]} { -+ pass "Core file generated by $detached gcore" -+ } else { -+ fail "Core file generated by $detached gcore" -+ } -+ core_clean -+} -+ -+# First a general `gdb_gcore.sh' spawn with its controlling terminal available. -+ -+test_body standard -+ -+# And now `gdb_gcore.sh' spawn without its controlling terminal available. -+# It is spawned through `gcorebg.c' using setpgrp (). -+ -+test_body detached -+ -+ -+# Cleanup. -+ -+set env(PATH) $oldpath -+remote_file target delete "./gdb" diff --git a/gdb-6.6-testsuite-timeouts.patch b/gdb-6.6-testsuite-timeouts.patch deleted file mode 100644 index 64102fa..0000000 --- a/gdb-6.6-testsuite-timeouts.patch +++ /dev/null @@ -1,32 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Fedora GDB patches -Date: Fri, 27 Oct 2017 21:07:50 +0200 -Subject: gdb-6.6-testsuite-timeouts.patch - -;; Avoid too long timeouts on failing cases of "annota1.exp annota3.exp". -;;=fedoratest - -diff --git a/gdb/testsuite/gdb.base/annota1.exp b/gdb/testsuite/gdb.base/annota1.exp ---- a/gdb/testsuite/gdb.base/annota1.exp -+++ b/gdb/testsuite/gdb.base/annota1.exp -@@ -37,6 +37,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb - - clean_restart ${binfile} - -+gdb_test "set breakpoint pending off" "" "Avoid lockup on nonexisting functions" -+ - # The commands we test here produce many lines of output; disable "press - # to continue" prompts. - gdb_test_no_output "set height 0" -diff --git a/gdb/testsuite/gdb.base/annota3.exp b/gdb/testsuite/gdb.base/annota3.exp ---- a/gdb/testsuite/gdb.base/annota3.exp -+++ b/gdb/testsuite/gdb.base/annota3.exp -@@ -36,6 +36,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb - - clean_restart ${binfile} - -+gdb_test "set breakpoint pending off" "" "Avoid lockup on nonexisting functions" -+ - # The commands we test here produce many lines of output; disable "press - # to continue" prompts. - gdb_test_no_output "set height 0" diff --git a/gdb-add-deprecated-settings-py-script.patch b/gdb-add-deprecated-settings-py-script.patch new file mode 100644 index 0000000..31acd3e --- /dev/null +++ b/gdb-add-deprecated-settings-py-script.patch @@ -0,0 +1,68 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Andrew Burgess +Date: Tue, 19 Nov 2024 13:56:56 +0000 +Subject: gdb-add-deprecated-settings-py-script.patch + +;; Not a backport. Add a new script which defines a setting which is +;; deprecated, but we don't want to remove it from Fedora GDB just yet. + +gdb: add script which defines a deprecated settings + +The build-id-core-load setting has not been useful since 2020, but its +not clear when it will be OK to remove this from GDB. + +Rather than defining this setting in C++ code, lets just create it +using this Python script, this helps keep the Fedora stuff out of core +GDB. + +diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in +--- a/gdb/data-directory/Makefile.in ++++ b/gdb/data-directory/Makefile.in +@@ -86,6 +86,7 @@ PYTHON_FILE_LIST = \ + gdb/unwinder.py \ + gdb/xmethod.py \ + gdb/command/__init__.py \ ++ gdb/command/deprecated-settings.py \ + gdb/command/explore.py \ + gdb/command/frame_filters.py \ + gdb/command/missing_files.py \ +diff --git a/gdb/python/lib/gdb/command/deprecated-settings.py b/gdb/python/lib/gdb/command/deprecated-settings.py +new file mode 100644 +--- /dev/null ++++ b/gdb/python/lib/gdb/command/deprecated-settings.py +@@ -0,0 +1,35 @@ ++import gdb ++ ++# This setting was added to Fedora GDB back in 2007. It controlled ++# whether GDB would use the build-id extracted from a core file to ++# auto-load the executable if the user had not already loaded an ++# executable. ++# ++# In 2020 this setting was effectively deprecated as the only use of ++# the setting's value was removed. After this GDB would always ++# auto-load an executable based on the build-id if no executable was ++# already loaded. ++# ++# For now we maintain this setting for backward compatibility reasons. ++ ++class build_id_core_load(gdb.Parameter): ++ """This setting is deprecated. Changing it will have no effect. ++ This is maintained only for backwards compatibility. ++ ++ When opening a core-file, and no executable is loaded, GDB will ++ always try to auto-load a suitable executable using the build-id ++ extracted from the core file (if a suitable build-id can be ++ found).""" ++ ++ def __init__(self): ++ self.set_doc = "This setting is deprecated and has no effect." ++ self.show_doc = "This setting is deprecated and has no effect." ++ self.value = True ++ ++ super().__init__("build-id-core-load", gdb.COMMAND_DATA, gdb.PARAM_BOOLEAN) ++ def validate(self): ++ return True ++ def get_set_string(self): ++ raise gdb.GdbError("The 'build-id-core-load' setting is deprecated.") ++ ++build_id_core_load() diff --git a/gdb-add-rpm-suggestion-script-suse.patch b/gdb-add-rpm-suggestion-script-suse.patch new file mode 100644 index 0000000..747184c --- /dev/null +++ b/gdb-add-rpm-suggestion-script-suse.patch @@ -0,0 +1,40 @@ +From 423c53757e2fe22815fef8a04abf21caff951937 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Tue, 25 Mar 2025 14:12:51 +0100 +Subject: [PATCH 1/4] [distro] Update gdb-add-rpm-suggestion-script.patch for + SUSE + +--- + gdb/python/lib/gdb/command/rpm-suggestions.py | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/gdb/python/lib/gdb/command/rpm-suggestions.py b/gdb/python/lib/gdb/command/rpm-suggestions.py +index 156fce0672b..f1034070989 100644 +--- a/gdb/python/lib/gdb/command/rpm-suggestions.py ++++ b/gdb/python/lib/gdb/command/rpm-suggestions.py +@@ -358,7 +358,7 @@ else: + # Take a non-empty list of RPM names and print a command line a + # user could run to install these RPMs. + def print_rpm_suggestions(rpm_name_list): +- print("Missing rpms, try: dnf --enablerepo='*debug*' install " + ' '.join(rpm_name_list)) ++ print("Missing separate debuginfos, use: zypper install " + ' '.join(rpm_name_list)) + + # Take a non-empty list of build-id strings and print a series of + # lines that a user could run to instll the RPMs that provide +@@ -423,7 +423,10 @@ else: + + # Register the missing debug and missing objfile handlers with GDB. + gdb.missing_debug.register_handler(None, RPM_MissingDebugHandler()) +- gdb.missing_objfile.register_handler(None, RPM_MissingObjfileHandler()) ++ ++ # Not enabled for SUSE/openSUSE. Zypper doesn't support finding packages ++ # based on build-id, unless the package's installed. ++ #gdb.missing_objfile.register_handler(None, RPM_MissingObjfileHandler()) + + # Implement the core of 'info rpm-suggestions'. Reprint all rpm + # suggestions. + +base-commit: 956ad1d51aa6e4117a98c4124bd7154a1aaeec55 +-- +2.43.0 + diff --git a/gdb-add-rpm-suggestion-script.patch b/gdb-add-rpm-suggestion-script.patch new file mode 100644 index 0000000..93c1c29 --- /dev/null +++ b/gdb-add-rpm-suggestion-script.patch @@ -0,0 +1,806 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Andrew Burgess +Date: Thu, 7 Mar 2024 15:14:23 +0000 +Subject: gdb-add-rpm-suggestion-script.patch + +;; Not a backport. Add a new script which hooks into GDB and suggests +;; RPMs to install when GDB finds an objfile with no debug info. + +gdb: add script which will suggest debuginfo RPMs to install + +This script hooks into GDB's missing debug info Python API and +suggests debuginfo RPMs to install. + +diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in +--- a/gdb/data-directory/Makefile.in ++++ b/gdb/data-directory/Makefile.in +@@ -91,6 +91,7 @@ PYTHON_FILE_LIST = \ + gdb/command/missing_files.py \ + gdb/command/pretty_printers.py \ + gdb/command/prompt.py \ ++ gdb/command/rpm-suggestions.py \ + gdb/command/type_printers.py \ + gdb/command/unwinders.py \ + gdb/command/xmethods.py \ +diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo +--- a/gdb/doc/gdb.texinfo ++++ b/gdb/doc/gdb.texinfo +@@ -186,6 +186,7 @@ + * Trace File Format:: @value{GDBN} trace file format + * Index Section Format:: .gdb_index section format + * Debuginfod:: Download debugging resources with @code{debuginfod} ++* RPM Suggestions:: RPM Suggestions from GDB + * Man Pages:: Manual pages + * Copying:: GNU General Public License says + how you can copy and share @value{GDBN} +@@ -50341,6 +50342,111 @@ + + @end table + ++@node RPM Suggestions ++@appendix Receiving RPM installation suggestions ++@cindex rpm suggestions ++ ++When @value{GDBN} loads an executable, or shared library, and cannot ++find the corresponding debug information, @value{GDBN} will check to ++see if an RPM is available which could provide the missing debug ++information. If a suitable RPM is found then @value{GDBN} will print ++a hint before the next prompt is displayed: ++ ++@smallexample ++(@value{GDBP}) file /bin/ls ++Reading symbols from /bin/ls... ++Reading symbols from .gnu_debugdata for /usr/bin/ls... ++(No debugging symbols found in .gnu_debugdata for /usr/bin/ls) ++Missing rpms, try: dnf --enablerepo='*debug*' install coreutils-debuginfo-9.3-7.fc39.x86_64 ++(@value{GDBP}) ++@end smallexample ++ ++In this case, installing @file{coreutils-debuginfo-9.3-7.fc39.x86_64} ++will provide the missing debug information for @file{/bin/ls}. It is ++up to you to install the suggested package, if possible, and after ++that reload the executable in @value{GDBN} so that the newly installed ++debug information can be found. ++ ++The RPM suggestion feature can be disabled: ++ ++@table @code ++@kindex set rpm-suggestion enabled ++@kindex show rpm-suggestion enabled ++@cindex rpm suggestions, disabling ++@item set rpm-suggestion enabled @r{[}on@r{|}off@r{]} ++@itemx show rpm-suggestion enabled ++When @samp{on} @value{GDBN} will make RPM suggestions where possible. ++When @samp{off} all RPM suggestion will be disabled. ++@end table ++ ++When opening a core file (@pxref{core-file command}), it may be the ++case that not only is the debug information missing, but the ++corresponding executable itself is missing. For example, if a core ++file is copied from one machine to another in order to debug. ++ ++In this case @value{GDBN} is able to suggest a command which will ++install the missing executable based on the build-id of the ++executable. For example: ++ ++@smallexample ++(@value{GDBP}) core-file /tmp/core.5489 ++warning: Can't open file /usr/bin/sl during file-backed mapping note processing ++[New LWP 5489] ++Core was generated by `sl'. ++Program terminated with signal SIGQUIT, Quit. ++#0 0x00007f1b41ced1a7 in ?? () ++Missing file(s), try: dnf --enablerepo='*debug*' install /usr/lib/.build-id/33/2f1a8e56693960e3beb2d70cd79ddfec451cc3 /usr/lib/debug/.build-id/33/2f1a8e56693960e3beb2d70cd79ddfec451cc3.debug ++(@value{GDBP}) ++@end smallexample ++ ++The core file was generated from the @file{/usr/bin/sl} binary, which ++is not present on the machine opening the core file. @value{GDBN} has ++suggested a command, based on the build-id of the binary, which was ++extracted from the core file, that would install both the missing ++binary, and the corresponding debug information. ++ ++Unfortunately, @value{GDBN} doesn't know if the suggested command will ++actually find a matching RPM or not. Querying the RPM database to see ++which packages, if any, will provide a file with the given build-id, ++is rather slow. As @file{/usr/bin/sl} is available in an RPM, then ++the above command will succeed. ++ ++It is possible to have @value{GDBN} check to see if there is a package ++available before making the suggestion, but this is significantly ++slower. To enable this mode use the following command: ++ ++@table @code ++@kindex set rpm-suggestion build-id-mode ++@kindex show rpm-suggestion build-id-mode ++@cindex rpm suggestions, build-id-mode ++@item set rpm-suggestion build-id-mode @r{[}fast@r{|}slow@r{]} ++@itemx show rpm-suggestion build-id-mode ++When set to @samp{fast}, which is the default, @value{GDBN} will offer ++suggestions based on the build-id of any missing executables or shared ++libraries while opening a core file. This is fast, but @value{GDBN} ++has not checked if there is a package available that can supply the ++required file, so running the suggested command might not install any ++packages. ++ ++When set to @samp{slow}, each time @value{GDBN} encounters an ++executable, or shared library, that is missing, @value{GDBN} will ++check to see if there is an RPM available that will supply the missing ++binary. If a suitable RPM is found then @value{GDBN} will offer a ++command which will install the missing RPM. If no suitable RPM is ++found then @value{GDBN} will make no suggestions. ++@end table ++ ++It is possible to review all of the previous RPM suggestions that ++@value{GDBN} has made using the following command: ++ ++@table @code ++@kindex info rpm-suggestions ++@cindex rpm suggestions, listing ++@item info rpm-suggestions ++List all of the RPM suggestions @value{GDBN} has made since the ++executable was last changed. ++@end table ++ + @node Man Pages + @appendix Manual pages + @cindex Man pages +diff --git a/gdb/python/lib/gdb/command/rpm-suggestions.py b/gdb/python/lib/gdb/command/rpm-suggestions.py +new file mode 100644 +--- /dev/null ++++ b/gdb/python/lib/gdb/command/rpm-suggestions.py +@@ -0,0 +1,552 @@ ++# Copyright 2023 Free Software Foundation, Inc. ++ ++# 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 . ++ ++import gdb ++import gdb.missing_debug ++import gdb.missing_objfile ++ ++# These modules are all system modules, and should be available on any ++# correctly setup Python install. ++import sys ++import os ++import subprocess ++import re ++from threading import Thread ++import time ++ ++try: ++ import rpm ++except ModuleNotFoundError: ++ # The "RPM suggestions" mechanism will not work without the (python) ++ # rpm module. Inform the user of this, but wait to do so until ++ # just prior to printing the GDB prompt. If we do it right away, ++ # the message typically appears before the version and copyright ++ # info, which is easily missed by many users. Additionally, it ++ # seems that several other packages which parse GDB version info ++ # are confused by an early error message regarding a missing ++ # python3-rpm package, so waiting to print the error allows those ++ # applications to work as they used to. ++ def before_prompt(): ++ print( ++ ("\nUnable to load the Python 'rpm' module. Lack of this module disables\n" ++ "the RPM suggestions mechanism which recommends shell commands for\n" ++ "installing missing debuginfo packages. To enable this functionality,\n" ++ "please install the python3-rpm package."), ++ file=sys.stderr ++ ) ++ gdb.events.before_prompt.disconnect(before_prompt) ++ ++ gdb.events.before_prompt.connect(before_prompt) ++ ++ # Implement 'info rpm-suggestions' when the 'rpm' module is not ++ # available. Just throws an error. ++ def info_rpm_suggestions(): ++ raise gdb.GdbError("rpm-suggestions are disabled as the Python 'rpm' module is not installed") ++else: ++ # Track all the RPMs suggested during a single debug session so we ++ # don't suggest the same RPM twice. This is only cleared when the ++ # main executable is changed. ++ __missing_rpms = {} ++ ++ # Track any missing RPMs that have been discovered since the last time ++ # the prompt was displayed. RPMs in here are also present in the ++ # __MISSING_RPMS dictionary, but this dictionary is cleared each time ++ # the prompt is shown. ++ __suggest_rpms = {} ++ ++ # Track all the build-ids suggested during a single debug session so we ++ # don't suggest installing using the same build-id twice. This is only ++ # cleared when the main executable is changed. ++ __missing_build_ids = {} ++ ++ # Track any build-ids that have been discovered missing since the last ++ # time the prompt was displayed. Build-ids in here are also present in ++ # the __MISSING_BUILD_IDS dictionary, but this dictionary is cleared ++ # each time the prompt is shown. ++ __suggest_build_ids = {} ++ ++ # The build-id to RPM lookup is very slow. This cache maps ++ # build-ids to the set of RPM we can suggest installing. The key ++ # is the build-id string, and the value is a list of RPM names, or ++ # None if there was an error with the build-id to RPM lookup. ++ # ++ # This cache is never cleared, even when the executable is ++ # changed. The build-ids should be unique, so a build-id lookup ++ # should be good for the lifetime of the session. ++ __build_id_lookup_cache = {} ++ ++ # When searching for an RPM given a build-id, if the search takes ++ # too long, then a message is printed to the user. We only print ++ # the message once between each GDB prompt. This flag is set True ++ # when the message is printed, and reset to False when a prompt is ++ # displayed. ++ __searching_message_printed = False ++ ++ # Add a suggestion to install RPM_NAME (the full name of an RPM) ++ # to the list of suggestions to make the next time a prompt is ++ # displayed. ++ def add_rpm_suggestion(rpm_name): ++ global __missing_rpms ++ global __suggest_rpms ++ ++ if not rpm_name in __missing_rpms: ++ __suggest_rpms[rpm_name] = True ++ __missing_rpms[rpm_name] = True ++ ++ # Return True if RPM_NAME is installed, where RPM_NAME is the full ++ # name of an RPM. ++ def is_rpm_installed(ts, rpm_name): ++ res = ts.dbMatch(rpm.RPMDBI_LABEL, rpm_name) ++ return len(res) > 0 ++ ++ # Add a suggestion to install RPMs based on BUILD_ID, a string ++ # containing a build-id, to the list of suggestions to make the next ++ # time a prompt is displayed. ++ def add_build_id_suggestion(build_id): ++ global __missing_build_ids ++ global __suggest_build_ids ++ ++ if not build_id in __missing_build_ids: ++ __suggest_build_ids[build_id] = True ++ __missing_build_ids[build_id] = True ++ ++ # Return true if '/usr/lib' is in the debug-file-directory list. ++ # System packages install their debug information into /usr/lib, ++ # so if GDB isn't looking in that directory, then there's no ++ # reason to try and figure out a suitable RPM to install. ++ def using_suitable_debug_file_directory(): ++ debug_file_directories = gdb.parameter("debug-file-directory") ++ for d in debug_file_directories.split(os.pathsep): ++ if d[:8] == "/usr/lib": ++ return True ++ return False ++ ++ # Return True if rpm-suggestion is disabled for any reason. ++ def rpm_suggestion_is_disabled(): ++ global param_build_id_verbose ++ ++ # If /usr/lib/ is not being used to find debug information ++ # then there's no point offering any RPMs as GDB would not ++ # find the newly installed content. ++ if not using_suitable_debug_file_directory(): ++ return True ++ ++ # For backwards compatibility, if build-id-verbose is set to ++ # zero, then disable RPM suggestion. ++ if param_build_id_verbose.value == 0: ++ return True ++ ++ # Is 'rpm-suggestion enabled' set to 'off'? ++ if not param_rpm_suggestion_enabled.value: ++ return True ++ ++ return False ++ ++ ++ # Lookup RPMs that might provide the debug information for FILENAME, ++ # which is a string containing the path to an object file GDB could ++ # not find any debug information for. ++ # ++ # If a possible RPM is found then this is added to the globals ++ # __MISSING_RPMS and __SUGGEST_RPMS, which are used elsewhere in this ++ # script. ++ def find_debug_suggestions(filename): ++ if rpm_suggestion_is_disabled(): ++ return ++ ++ ts = rpm.TransactionSet() ++ mi = ts.dbMatch(rpm.RPMDBI_BASENAMES, filename) ++ for h in mi: ++ # Build the debuginfo package name. ++ obj = h.format("%{name}-debuginfo-%{version}-%{release}.%{arch}") ++ rpm_name = str(obj) ++ ++ # Check to see if the package is installed. ++ if is_rpm_installed(ts, rpm_name): ++ continue ++ ++ add_rpm_suggestion(rpm_name) ++ ++ ++ # Return a string which is the filename of the filename ++ # corresponding to BUILD_ID in one of the two locations under ++ # /usr/lib. ++ # ++ # When DEBUG_P is True, return a filename within: ++ # /usr/lib/debug/.build-id/ and when DEBUG_P is False, return a ++ # filename within: /usr/lib/.build-id/. ++ # ++ # The SUFFIX string is appended to the generated filename. ++ def build_id_to_usr_lib_filename(build_id, debug_p, suffix = ""): ++ key = build_id[:2] ++ rst = build_id[2:] ++ ++ filename = '/usr/lib' ++ if debug_p: ++ filename += '/debug' ++ filename += '/.build-id/' + key + '/' + rst + suffix ++ ++ return filename ++ ++ # A regexp object used to match against the output of `dnf`. This ++ # is initialised the first time it is needed. ++ find_objfile_suggestions_re = None ++ ++ # Given BUILD_ID, a string containing a build-id, run a `dnf` ++ # command to figure out if any RPMs can provide a file with that ++ # build-id. ++ # ++ # If any suitable RPMs are found then `add_rpm_suggestion` is called ++ # to register the suggestion. ++ # ++ # This function is pretty slow, which is a shame, as the results ++ # returned are much nicer than just telling the user to try the ++ # lookup command for themselves. ++ def find_objfile_suggestions_in_thread(build_id): ++ global find_objfile_suggestions_re ++ ++ if find_objfile_suggestions_re is None: ++ find_objfile_suggestions_re = re.compile("^(.*)-debuginfo-(.*) : Debug information for package (.*)$") ++ ++ result = subprocess.run(['dnf', "--enablerepo=*debug*", '--nogpgcheck', '-C', 'provides', ++ build_id_to_usr_lib_filename(build_id, True)], ++ capture_output=True, timeout=30) ++ ++ lines = result.stdout.decode('utf-8').splitlines() ++ ts = rpm.TransactionSet() ++ ++ for l in lines: ++ m = find_objfile_suggestions_re.match(l) ++ if not m: ++ continue ++ if m.group(1) != m.group(3): ++ return ++ ++ main_rpm = m.group(1) + '-' + m.group(2) ++ dbg_rpm = m.group(1) + '-debuginfo-' + m.group(2) ++ ++ if not is_rpm_installed(ts, main_rpm): ++ add_rpm_suggestion(main_rpm) ++ ++ if not is_rpm_installed(ts, dbg_rpm): ++ add_rpm_suggestion(dbg_rpm) ++ ++ return ++ ++ # Call `find_objfile_suggestions_in_thread` is a separate thread, ++ # then wait for the thread to complete. Don't touch any shared ++ # state while waiting for the thread to complete. There's no ++ # locking on any of our caches, and the worker thread will add RPM ++ # suggestions as it wants. ++ # ++ # If thre thread takes too long to complete then print a message ++ # to the user telling them what's going on. ++ def find_objfile_suggestions_slow_core(build_id): ++ global __searching_message_printed ++ ++ thread = Thread(target = find_objfile_suggestions_in_thread, args = (build_id, )) ++ thread.start() ++ start = time.time_ns() ++ ++ while thread.is_alive (): ++ time.sleep(0.05) ++ now = time.time_ns () ++ if not __searching_message_printed and (now - start > 1000000000): ++ print("Searching for packages to install that could improve debugging...") ++ __searching_message_printed = True ++ ++ thread.join() ++ ++ ++ # Given BUILD_ID, a string containing a build-id, lookup suitable ++ # RPMs that could be installed to provide a file with the required ++ # build-id. ++ # ++ # Any suitable RPMs are recorded by calling `add_rpm_suggestion`, and ++ # will be printed before the next prompt. ++ def find_objfile_suggestions_slow(build_id): ++ global __build_id_lookup_cache ++ global __suggest_rpms ++ ++ # The code to lookup an RPM given only a build-id is pretty ++ # slow. Cache the results to try and reduce the UI delays. ++ if build_id in __build_id_lookup_cache: ++ rpms = __build_id_lookup_cache[build_id] ++ if rpms is not None: ++ for r in rpms: ++ add_rpm_suggestion(r) ++ return ++ ++ # Make sure the cache entry exists before we do the lookup. ++ # If, for any reason, the lookup raises an exception, then ++ # having a cache entry will prevent us retrying this lookup in ++ # the future. ++ __build_id_lookup_cache[build_id] = None ++ ++ # Now do the lookup. This is the slow part. ++ find_objfile_suggestions_slow_core(build_id) ++ ++ # Fill in the cache, for a given build-id which RPMs were ++ # suggested. ++ rpms = [] ++ for r in __suggest_rpms: ++ rpms.append(r) ++ __build_id_lookup_cache[build_id] = rpms ++ ++ ++ # Given BUILD_ID, a string containing a build-id, just record that we ++ # should advise the user to try installing RPMs based on this build-id. ++ def find_objfile_suggestions_fast(build_id): ++ add_build_id_suggestion(build_id) ++ ++ # Given BUILD_ID, a string containing a build-id, which GDB has failed ++ # to find, possibly record some information so that we can, at the next ++ # prompt, give some RPM installation advice to the user. ++ # ++ # We have two different strategies for RPM lookup based on a build-id, ++ # one approach is that we actually lookup the RPMs and only suggest ++ # something if there is a suitable RPM. However, this is pretty slow, ++ # and users will probably find this annoying. ++ # ++ # So we also have a fast way. With this approach we just record the ++ # build-id that was missing and tell the user to try installing based on ++ # the build-id. The downside with this is that if there is no RPM for ++ # that build-id, then the user will try the command, but nothing will ++ # install. ++ def find_objfile_suggestions(build_id): ++ if rpm_suggestion_is_disabled(): ++ return ++ ++ if param_rpm_suggestion_build_id_mode.fast_mode(): ++ find_objfile_suggestions_fast(build_id) ++ else: ++ find_objfile_suggestions_slow(build_id) ++ ++ # A missing debug handler class. Just forwards the name of the ++ # objfile for which we are missing debug information to ++ # find_debug_suggestions. ++ class RPM_MissingDebugHandler(gdb.missing_debug.MissingDebugHandler): ++ def __init__(self): ++ super().__init__("rpm-suggestions") ++ ++ def __call__(self, objfile): ++ find_debug_suggestions(objfile.filename) ++ return False ++ ++ # A missing objfile handler class. Just forwards the build-id of ++ # the objfile that is missing to find_objfile_suggestions. ++ class RPM_MissingObjfileHandler(gdb.missing_objfile.MissingObjfileHandler): ++ def __init__(self): ++ super().__init__("rpm-suggestions") ++ ++ def __call__(self, pspace, build_id, filename): ++ find_objfile_suggestions(build_id) ++ return False ++ ++ # Take a non-empty list of RPM names and print a command line a ++ # user could run to install these RPMs. ++ def print_rpm_suggestions(rpm_name_list): ++ print("Missing rpms, try: dnf --enablerepo='*debug*' install " + ' '.join(rpm_name_list)) ++ ++ # Take a non-empty list of build-id strings and print a series of ++ # lines that a user could run to instll the RPMs that provide ++ # files with this build-id. ++ # ++ # The printed commands will also install the corresponding debug ++ # packages for the executable with the given build-id. ++ def print_build_id_suggestions(build_id_list): ++ for build_id in build_id_list: ++ print("Missing file(s), try: dnf --enablerepo='*debug*' install " ++ + build_id_to_usr_lib_filename(build_id, False) ++ + ' ' ++ + build_id_to_usr_lib_filename(build_id, True, ".debug")) ++ ++ # Called before GDB displays its prompt. If the global __SUGGEST_RPMS ++ # dictionary is not empty, then this hook prints the keys of this ++ # dictionary as strings which are the names of RPMs. This hook formats ++ # each RPM name into a suggested 'dnf install' command and suggests this ++ # to the user. ++ # ++ # Additionally, if the global __SUGGEST_BUILD_IDS dictionary is not ++ # empty, then this hook uses the keys of this dictionary as build-ids ++ # that were found to be missing, and formats these into some file based ++ # 'dnf install' suggestions to the user. ++ def before_prompt(): ++ global __suggest_rpms ++ global __suggest_build_ids ++ global __searching_message_printed ++ ++ # We allow the searching message to be printed just once ++ # between prompts. ++ __searching_message_printed = False ++ ++ if len(__suggest_rpms) > 0: ++ print_rpm_suggestions(__suggest_rpms.keys()) ++ __suggest_rpms = {} ++ ++ if len(__suggest_build_ids) > 0: ++ print_build_id_suggestions(__suggest_build_ids.keys()) ++ __suggest_build_ids = {} ++ ++ # Called when the executable within a progrm space is changed. Clear ++ # the lists of RPM suggestions. We only clear the previous suggestion ++ # list when the executable really changes. If the user simply ++ # recompiles the executable, then we don't both clearing this list. ++ def executable_changed_handler(event): ++ global __missing_rpms ++ global __suggest_rpms ++ global __suggest_build_ids ++ global __missing_build_ids ++ ++ if not event.reload: ++ __missing_rpms = {} ++ __suggest_rpms = {} ++ __missing_build_ids = {} ++ __suggest_build_ids = {} ++ ++ ++ # Attach to the required GDB events. ++ gdb.events.executable_changed.connect(executable_changed_handler) ++ gdb.events.before_prompt.connect(before_prompt) ++ ++ # Register the missing debug and missing objfile handlers with GDB. ++ gdb.missing_debug.register_handler(None, RPM_MissingDebugHandler()) ++ gdb.missing_objfile.register_handler(None, RPM_MissingObjfileHandler()) ++ ++ # Implement the core of 'info rpm-suggestions'. Reprint all rpm ++ # suggestions. ++ def info_rpm_suggestions(): ++ global __missing_rpms ++ global __missing_build_ids ++ ++ if len(__missing_rpms) == 0 and len(__missing_build_ids) == 0: ++ print("No RPM suggestions have been made so far.") ++ return ++ ++ if len(__missing_rpms) > 0: ++ print_rpm_suggestions(__missing_rpms.keys()) ++ if len(__missing_build_ids) > 0: ++ print_build_id_suggestions(__missing_build_ids.keys()) ++ ++#################################################################### ++# The following code is outside the 'else' block of the attempt to # ++# load the 'rpm' module. Nothing after this point depends on the # ++# 'rpm' module. # ++#################################################################### ++ ++# The 'set rpm-suggestion' prefix command. ++class rpm_suggestion_set_prefix(gdb.Command): ++ """Prefix command for 'set' rpm-suggestion related commands.""" ++ ++ def __init__(self): ++ super().__init__("set rpm-suggestion", gdb.COMMAND_NONE, ++ gdb.COMPLETE_NONE, True) ++ ++# The 'show rpm-suggestion' prefix command. ++class rpm_suggestion_show_prefix(gdb.Command): ++ """Prefix command for 'show' rpm-suggestion related commands.""" ++ ++ def __init__(self): ++ super().__init__("show rpm-suggestion", gdb.COMMAND_NONE, ++ gdb.COMPLETE_NONE, True) ++ ++# The 'set/show rpm-suggestion enabled' command. ++class rpm_suggestion_enabled(gdb.Parameter): ++ """ ++ When 'on' GDB will search for RPMS that might provide additional ++ debug information, or provide missing executables or shared ++ libraries (when opening a core file), and will make suggestions ++ about what should be installed. ++ ++ When 'off' GDB will not make these suggestions. ++ """ ++ ++ set_doc = "Set whether to perform rpm-suggestion." ++ show_doc = "Show whether rpm-suggestion is enabled." ++ ++ def __init__(self): ++ super().__init__("rpm-suggestion enabled", gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN) ++ self.value = True ++ ++# The 'set/show rpm-suggestion enabled' command. ++class rpm_suggestion_build_id_mode(gdb.Parameter): ++ """ ++ When set to 'fast' (the default), GDB doesn't try to map a build-id to ++ an actual RPM, instead, GDB just suggests a command based on the ++ build-id which might install some RPMs, if there are any RPMs that ++ supply that build-id. However, it is equally possible that there are no ++ suitable RPMs, and nothing will install. This approach has almost zero ++ overhead. ++ ++ When set to 'slow', GDB first does the build-id to RPM check itself, and ++ only if something is found are RPMs installation commands suggested. ++ The suggested command will include the name of the RPM to install. This ++ approach is considerably slower as querying the RPM database for the RPM ++ that supplies a specific file is slow. ++ """ ++ ++ set_doc = "Set how build-id based rpm suggestions should be performed." ++ show_doc = "Show how build-id based rpm suggestions shoud be performed." ++ ++ def __init__(self): ++ super().__init__("rpm-suggestion build-id-mode", ++ gdb.COMMAND_NONE, gdb.PARAM_ENUM, ["fast", "slow"]) ++ self.value = "fast" ++ ++ def fast_mode(self): ++ return self.value == "fast" ++ ++# The 'info rpm-suggestions' command. ++class rpm_suggestion_info(gdb.Command): ++ """Relist any RPM installation suggestions that have been made ++ since the executable was last changed.""" ++ def __init__(self): ++ super().__init__("info rpm-suggestions", gdb.COMMAND_NONE, gdb.COMPLETE_NONE) ++ ++ def invoke(self, args, from_tty): ++ if args != "": ++ raise gdb.GdbError("unexpected arguments: %s" % args) ++ ++ info_rpm_suggestions () ++ ++ ++# Create the 'set/show rpm-suggestion' commands. ++rpm_suggestion_set_prefix() ++rpm_suggestion_show_prefix() ++param_rpm_suggestion_enabled = rpm_suggestion_enabled() ++param_rpm_suggestion_build_id_mode = rpm_suggestion_build_id_mode() ++ ++# Create the 'info rpm-suggestions' commands. ++rpm_suggestion_info() ++ ++# Create the 'build-id-verbose' parameter. This is implemented as an ++# integer for backward compatibility reasons. It would be nice to ++# convert this to a boolean, but it's not clear if that will break ++# existing users uses of this flag. ++ ++class build_id_verbose(gdb.Parameter): ++ """ ++ Level 0 disable printing the missing debug filesname, ++ Level 1 (default) enables printing the missing debug filenames, ++ """ ++ ++ set_doc = "Set debugging level of the build-id locator." ++ show_doc = "Show debugging level of the build-id locator." ++ ++ def __init__(self): ++ super().__init__("build-id-verbose", gdb.COMMAND_NONE, gdb.PARAM_ZINTEGER) ++ self.value = 1 ++ ++param_build_id_verbose = build_id_verbose() +diff --git a/gdb/testsuite/gdb.base/gdbinit-history.exp b/gdb/testsuite/gdb.base/gdbinit-history.exp +--- a/gdb/testsuite/gdb.base/gdbinit-history.exp ++++ b/gdb/testsuite/gdb.base/gdbinit-history.exp +@@ -179,7 +179,8 @@ proc test_empty_history_filename { } { + global env + global gdb_prompt + +- set common_history [list "set height 0" "set width 0"] ++ set common_history [list "set height 0" "set width 0" \ ++ "set build-id-verbose 0"] + + set test_dir [standard_output_file history_test] + remote_exec host "mkdir -p $test_dir" +diff --git a/gdb/testsuite/gdb.python/py-missing-debug.py b/gdb/testsuite/gdb.python/py-missing-debug.py +--- a/gdb/testsuite/gdb.python/py-missing-debug.py ++++ b/gdb/testsuite/gdb.python/py-missing-debug.py +@@ -19,6 +19,13 @@ from enum import Enum + import gdb + from gdb.missing_debug import MissingDebugHandler + ++# This is a RHEL/Fedora work around: There's already a ++# missing-debug-info handler registered for these versions of GDB. ++# Discard the handler now so that the tests will pass (the tests ++# assume no handler is currently registered). ++gdb.missing_debug_handlers = [] ++ ++ + # A global log that is filled in by instances of the LOG_HANDLER class + # when they are called. + handler_call_log = [] +@@ -118,4 +125,7 @@ def register(name, locus=None): + rhandler = exception_handler() + handler_obj = handler() + ++# Discard the rpm-suggestion handler. ++gdb.missing_file_handlers = [] ++ + print("Success") +diff --git a/gdb/testsuite/gdb.python/py-missing-objfile.py b/gdb/testsuite/gdb.python/py-missing-objfile.py +--- a/gdb/testsuite/gdb.python/py-missing-objfile.py ++++ b/gdb/testsuite/gdb.python/py-missing-objfile.py +@@ -164,4 +164,7 @@ def register(name, locus=None): + rhandler = exception_handler() + handler_obj = handler() + ++# Discard the rpm-suggestion handler. ++gdb.missing_file_handlers = [] ++ + print("Success") +diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp +--- a/gdb/testsuite/lib/gdb.exp ++++ b/gdb/testsuite/lib/gdb.exp +@@ -238,7 +238,8 @@ if ![info exists INTERNAL_GDBFLAGS] { + "-nx" \ + "-q" \ + {-iex "set height 0"} \ +- {-iex "set width 0"}]] ++ {-iex "set width 0"} \ ++ {-iex "set build-id-verbose 0"}]] + + # If DEBUGINFOD_URLS is set, gdb will try to download sources and + # debug info for f.i. system libraries. Prevent this. +@@ -2493,6 +2494,18 @@ proc default_gdb_start { } { + } + } + ++ # Turn off the missing debug info messages as the testsuite does ++ # not expect them. ++ send_gdb "set build-id-verbose 0\n" ++ gdb_expect 10 { ++ -re "$gdb_prompt $" { ++ verbose "Disabled the missing debug info messages." 2 ++ } ++ timeout { ++ warning "Could not disable the missing debug info messages." ++ } ++ } ++ + gdb_debug_init + return 0 + } +diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp +--- a/gdb/testsuite/lib/mi-support.exp ++++ b/gdb/testsuite/lib/mi-support.exp +@@ -321,6 +321,17 @@ proc default_mi_gdb_start { { flags {} } } { + warning "Couldn't set the width to 0." + } + } ++ # Turn off the missing debug info messages as the testsuite does ++ # not expect them. ++ send_gdb "190-gdb-set build-id-verbose 0\n" ++ gdb_expect 10 { ++ -re ".*190-gdb-set build-id-verbose 0\r\n190\\\^done\r\n$mi_gdb_prompt$" { ++ verbose "Disabled the missing debug info messages." 2 ++ } ++ timeout { ++ warning "Could not disable the missing debug info messages." ++ } ++ } + + if { $separate_inferior_pty } { + mi_create_inferior_pty diff --git a/gdb-archer-next-over-throw-cxx-exec.patch b/gdb-archer-next-over-throw-cxx-exec.patch index ce3c1aa..510363e 100644 --- a/gdb-archer-next-over-throw-cxx-exec.patch +++ b/gdb-archer-next-over-throw-cxx-exec.patch @@ -59,7 +59,7 @@ new file mode 100644 +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + -+if { [skip_cplus_tests] } { continue } ++require allow_cplus_tests + +set testfile cxxexec +if { [prepare_for_testing ${testfile}.exp ${testfile} ${testfile}.cc {c++ debug}] } { diff --git a/gdb-arm-fix-epilogue-frame-id.patch b/gdb-arm-fix-epilogue-frame-id.patch deleted file mode 100644 index 8b9abe9..0000000 --- a/gdb-arm-fix-epilogue-frame-id.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 40b2857e42b477832ca7fc2771b6cde910e22f05 Mon Sep 17 00:00:00 2001 -From: Thiago Jung Bauermann -Date: Tue, 23 Jan 2024 14:11:33 -0300 -Subject: [PATCH 4/7] gdb/arm: Fix epilogue frame id - -arm_epilogue_frame_this_id has a comment saying that it fall backs to using -the current PC if the function start address can't be identified, but it -actually uses only the PC to make the frame id. - -This patch makes the code match the comment. Another hint that it's what -is intended is that arm_prologue_this_id, a function almost identical to -it, does that. - -The problem was found by code inspection. It fixes the following testsuite -failures: - -FAIL: gdb.base/unwind-on-each-insn.exp: foo: instruction 9: check frame-id matches -FAIL: gdb.reverse/solib-reverse.exp: reverse-next third shr1 -FAIL: gdb.reverse/solib-reverse.exp: reverse-next second shr1 -FAIL: gdb.reverse/solib-reverse.exp: reverse-next first shr1 -FAIL: gdb.reverse/solib-reverse.exp: reverse-next generic -FAIL: gdb.reverse/solib-reverse.exp: reverse-step into solib function one -FAIL: gdb.reverse/solib-reverse.exp: reverse-step within solib function one -FAIL: gdb.reverse/solib-reverse.exp: reverse-step into solib function two -FAIL: gdb.reverse/solib-reverse.exp: reverse-step within solib function two - -Tested on arm-linux-gnueabi-hf. ---- - gdb/arm-tdep.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c -index 3b1682a2aea..21dad198dc7 100644 ---- a/gdb/arm-tdep.c -+++ b/gdb/arm-tdep.c -@@ -3252,7 +3252,7 @@ arm_epilogue_frame_this_id (frame_info_ptr this_frame, - - arm_gdbarch_tdep *tdep - = gdbarch_tdep (get_frame_arch (this_frame)); -- *this_id = frame_id_build (arm_cache_get_prev_sp_value (cache, tdep), pc); -+ *this_id = frame_id_build (arm_cache_get_prev_sp_value (cache, tdep), func); - } - - /* Implementation of function hook 'prev_register' in --- -2.35.3 - diff --git a/gdb-arm-remove-thumb-bit-in-arm_adjust_breakpoint_ad.patch b/gdb-arm-remove-thumb-bit-in-arm_adjust_breakpoint_ad.patch deleted file mode 100644 index f6620c7..0000000 --- a/gdb-arm-remove-thumb-bit-in-arm_adjust_breakpoint_ad.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 51a5415b3313470cb62fda7ad6762fc1c41c8cbd Mon Sep 17 00:00:00 2001 -From: Simon Marchi -Date: Tue, 7 Nov 2023 11:11:18 -0500 -Subject: [PATCH] gdb/arm: remove thumb bit in arm_adjust_breakpoint_address - -When compiling gdb with -fsanitize=address on ARM, I get a crash in test -gdb.arch/arm-disp-step.exp, reproduced easily with: - - $ ./gdb -nx -q --data-directory=data-directory testsuite/outputs/gdb.arch/arm-disp-step/arm-disp-step -ex "break *test_call_end" - Reading symbols from testsuite/outputs/gdb.arch/arm-disp-step/arm-disp-step... - ================================================================= - ==23295==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xb4a14fd1 at pc 0x01a48871 bp 0xbeab8490 sp 0xbeab8494 - -Since it doesn't require running the program, it can be reproduced locally on a -dev machine other than ARM, after acquiring the test binary. - -The length of the allocate buffer `buf` is 1, and we try to extract an -integer of size 2 from it. The length of 1 comes from the subtraction -`bpaddr - boundary`. Normally, on ARM, all instructions are aligned on -a multiple of 2, so it's weird for this subtraction to result in 1. In -this case, boundary comes from the result of find_pc_partial_function -returning 0x549: - - (gdb) p/x bpaddr - $2 = 0x54a - (gdb) p/x boundary - $3 = 0x549 - (gdb) p/x bpaddr - boundary - $4 = 0x1 - -0x549 is the address of the test_call_subr label, 0x548, with the thumb -bit enabled. Before doing some math with the address, I think we need -to strip the thumb bit, like is done elsewhere (for instance for bpaddr -earlier in the same function). - -I wonder if find_pc_partial_function should do that itself, in order to -return an address that is suitable for arithmetic. In any case, that -would be a change with a broad impact, so for now just fix the issue -locally. - -After the patch: - - $ ./gdb -nx -q --data-directory=data-directory testsuite/outputs/gdb.arch/arm-disp-step/arm-disp-step -ex "break *test_call_end" - Reading symbols from testsuite/outputs/gdb.arch/arm-disp-step/arm-disp-step... - Breakpoint 1 at 0x54a: file /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.arch/arm-disp-step.S, line 103. - -Change-Id: I74fc458dbea0d2c1e1f5eadd90755188df089288 -Approved-By: Luis Machado ---- - gdb/arm-tdep.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c -index 21dad198dc7..e61342f3ccb 100644 ---- a/gdb/arm-tdep.c -+++ b/gdb/arm-tdep.c -@@ -5340,9 +5340,12 @@ arm_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr) - - bpaddr = gdbarch_addr_bits_remove (gdbarch, bpaddr); - -- if (find_pc_partial_function (bpaddr, NULL, &func_start, NULL) -- && func_start > boundary) -- boundary = func_start; -+ if (find_pc_partial_function (bpaddr, NULL, &func_start, NULL)) -+ { -+ func_start = gdbarch_addr_bits_remove (gdbarch, func_start); -+ if (func_start > boundary) -+ boundary = func_start; -+ } - - /* Search for a candidate IT instruction. We have to do some fancy - footwork to distinguish a real IT instruction from the second - -base-commit: eafca1ce3d589c731927e5481199db715bcbeff3 --- -2.35.3 - diff --git a/gdb-arm-remove-tpidruro-register-from-non-freebsd-ta.patch b/gdb-arm-remove-tpidruro-register-from-non-freebsd-ta.patch deleted file mode 100644 index 554c88f..0000000 --- a/gdb-arm-remove-tpidruro-register-from-non-freebsd-ta.patch +++ /dev/null @@ -1,219 +0,0 @@ -From 7973eaf11e33ddd405830b9bd29495991db5901d Mon Sep 17 00:00:00 2001 -From: Thiago Jung Bauermann -Date: Mon, 26 Feb 2024 19:11:45 -0300 -Subject: [PATCH 2/7] gdb/arm: Remove tpidruro register from non-FreeBSD target - descriptions - -Commit 92d48a1e4eac ("Add an arm-tls feature which includes the tpidruro -register from CP15.") introduced the org.gnu.gdb.arm.tls feature, which -adds the tpidruro register, and unconditionally enabled it in -aarch32_create_target_description. - -In Linux, the tpidruro register isn't available via ptrace in the 32-bit -kernel but it is available for an aarch32 program running under an arm64 -kernel via the ptrace compat interface. This isn't currently implemented -however, which causes GDB on arm-linux with 64-bit kernel to list the -register but show it as unavailable, as reported by Tom de Vries: - - $ gdb -q -batch a.out -ex start -ex 'p $tpidruro' - Temporary breakpoint 1 at 0x512 - - Temporary breakpoint 1, 0xaaaaa512 in main () - $1 = - -Simon Marchi then clarified: - -> The only time we should be seeing some "unavailable" registers or memory -> is in the context of tracepoints, for things that are not collected. -> Seeing an unavailable register here is a sign that something is not -> right. - -Therefore, disable the TLS feature in aarch32 target descriptions for Linux -and NetBSD targets (the latter also doesn't seem to support accessing -tpidruro either, based on a quick look at arm-netbsd-nat.c). - -This patch fixes the following tests: - -Running gdb.base/inline-frame-cycle-unwind.exp ... -FAIL: gdb.base/inline-frame-cycle-unwind.exp: cycle at level 3: backtrace when the unwind is broken at frame 3 -FAIL: gdb.base/inline-frame-cycle-unwind.exp: cycle at level 5: backtrace when the unwind is broken at frame 5 -FAIL: gdb.base/inline-frame-cycle-unwind.exp: cycle at level 1: backtrace when the unwind is broken at frame 1 - -Tested with Ubuntu 22.04.3 on armv8l-linux-gnueabihf in native, -native-gdbserver and native-extended-gdbserver targets with no regressions. - -PR tdep/31418 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31418 - -Approved-By: John Baldwin ---- - gdb/aarch32-tdep.c | 15 ++++++++++----- - gdb/aarch32-tdep.h | 2 +- - gdb/aarch64-linux-nat.c | 2 +- - gdb/arch/aarch32.c | 5 +++-- - gdb/arch/aarch32.h | 2 +- - gdb/arm-fbsd-tdep.c | 2 +- - gdb/arm-linux-nat.c | 2 +- - gdb/arm-linux-tdep.c | 2 +- - gdb/arm-netbsd-nat.c | 2 +- - gdbserver/linux-aarch32-tdesc.cc | 2 +- - 10 files changed, 21 insertions(+), 15 deletions(-) - -diff --git a/gdb/aarch32-tdep.c b/gdb/aarch32-tdep.c -index bfa88a96522..395328936e4 100644 ---- a/gdb/aarch32-tdep.c -+++ b/gdb/aarch32-tdep.c -@@ -22,15 +22,20 @@ - #include "gdbsupport/common-regcache.h" - #include "arch/aarch32.h" - --static struct target_desc *tdesc_aarch32; -+static struct target_desc *tdesc_aarch32_list[2]; - - /* See aarch32-tdep.h. */ - - const target_desc * --aarch32_read_description () -+aarch32_read_description (bool tls) - { -- if (tdesc_aarch32 == nullptr) -- tdesc_aarch32 = aarch32_create_target_description (); -+ struct target_desc *tdesc = tdesc_aarch32_list[tls]; - -- return tdesc_aarch32; -+ if (tdesc == nullptr) -+ { -+ tdesc = aarch32_create_target_description (tls); -+ tdesc_aarch32_list[tls] = tdesc; -+ } -+ -+ return tdesc; - } -diff --git a/gdb/aarch32-tdep.h b/gdb/aarch32-tdep.h -index bee4d4e9fc0..efc93351298 100644 ---- a/gdb/aarch32-tdep.h -+++ b/gdb/aarch32-tdep.h -@@ -22,6 +22,6 @@ struct target_desc; - - /* Get the AArch32 target description. */ - --const target_desc *aarch32_read_description (); -+const target_desc *aarch32_read_description (bool tls); - - #endif /* aarch32-tdep.h. */ -diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c -index 768748a20db..c680d6de0c9 100644 ---- a/gdb/aarch64-linux-nat.c -+++ b/gdb/aarch64-linux-nat.c -@@ -887,7 +887,7 @@ aarch64_linux_nat_target::read_description () - - ret = ptrace (PTRACE_GETREGSET, tid, NT_ARM_VFP, &iovec); - if (ret == 0) -- return aarch32_read_description (); -+ return aarch32_read_description (false); - - CORE_ADDR hwcap = linux_get_hwcap (); - CORE_ADDR hwcap2 = linux_get_hwcap2 (); -diff --git a/gdb/arch/aarch32.c b/gdb/arch/aarch32.c -index 5be2cc0156e..b7510ee41e9 100644 ---- a/gdb/arch/aarch32.c -+++ b/gdb/arch/aarch32.c -@@ -25,7 +25,7 @@ - /* See aarch32.h. */ - - target_desc * --aarch32_create_target_description () -+aarch32_create_target_description (bool tls) - { - target_desc_up tdesc = allocate_target_description (); - -@@ -39,7 +39,8 @@ aarch32_create_target_description () - /* Create a vfpv3 feature, then a blank NEON feature. */ - regnum = create_feature_arm_arm_vfpv3 (tdesc.get (), regnum); - tdesc_create_feature (tdesc.get (), "org.gnu.gdb.arm.neon"); -- regnum = create_feature_arm_arm_tls (tdesc.get (), regnum); -+ if (tls) -+ regnum = create_feature_arm_arm_tls (tdesc.get (), regnum); - - return tdesc.release (); - } -diff --git a/gdb/arch/aarch32.h b/gdb/arch/aarch32.h -index 6b24ae94335..e06e260e370 100644 ---- a/gdb/arch/aarch32.h -+++ b/gdb/arch/aarch32.h -@@ -22,6 +22,6 @@ - - /* Create the AArch32 target description. */ - --target_desc *aarch32_create_target_description (); -+target_desc *aarch32_create_target_description (bool tls); - - #endif /* aarch32.h. */ -diff --git a/gdb/arm-fbsd-tdep.c b/gdb/arm-fbsd-tdep.c -index b46fa91d0a0..a4cea77f388 100644 ---- a/gdb/arm-fbsd-tdep.c -+++ b/gdb/arm-fbsd-tdep.c -@@ -228,7 +228,7 @@ arm_fbsd_read_description_auxv (const gdb::optional &auxv, - if (arm_hwcap & HWCAP_VFP) - { - if (arm_hwcap & HWCAP_NEON) -- return aarch32_read_description (); -+ return aarch32_read_description (tls); - else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPD32)) - == (HWCAP_VFPv3 | HWCAP_VFPD32)) - return arm_read_description (ARM_FP_TYPE_VFPV3, tls); -diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c -index 70c6bc684fa..07af23d3881 100644 ---- a/gdb/arm-linux-nat.c -+++ b/gdb/arm-linux-nat.c -@@ -568,7 +568,7 @@ arm_linux_nat_target::read_description () - /* NEON implies VFPv3-D32 or no-VFP unit. Say that we only support - Neon with VFPv3-D32. */ - if (arm_hwcap & HWCAP_NEON) -- return aarch32_read_description (); -+ return aarch32_read_description (false); - else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPv3D16)) == HWCAP_VFPv3) - return arm_read_description (ARM_FP_TYPE_VFPV3, false); - -diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c -index dfa816990ff..33748731cfd 100644 ---- a/gdb/arm-linux-tdep.c -+++ b/gdb/arm-linux-tdep.c -@@ -740,7 +740,7 @@ arm_linux_core_read_description (struct gdbarch *gdbarch, - /* NEON implies VFPv3-D32 or no-VFP unit. Say that we only support - Neon with VFPv3-D32. */ - if (arm_hwcap & HWCAP_NEON) -- return aarch32_read_description (); -+ return aarch32_read_description (false); - else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPv3D16)) == HWCAP_VFPv3) - return arm_read_description (ARM_FP_TYPE_VFPV3, false); - -diff --git a/gdb/arm-netbsd-nat.c b/gdb/arm-netbsd-nat.c -index d83714a46c3..018964b010d 100644 ---- a/gdb/arm-netbsd-nat.c -+++ b/gdb/arm-netbsd-nat.c -@@ -350,7 +350,7 @@ arm_netbsd_nat_target::read_description () - - len = sizeof(flag); - if (sysctlbyname("machdep.neon_present", &flag, &len, NULL, 0) == 0 && flag) -- return aarch32_read_description (); -+ return aarch32_read_description (false); - - return arm_read_description (ARM_FP_TYPE_VFPV3, false); - } -diff --git a/gdbserver/linux-aarch32-tdesc.cc b/gdbserver/linux-aarch32-tdesc.cc -index e1380fa2a40..443f91e3585 100644 ---- a/gdbserver/linux-aarch32-tdesc.cc -+++ b/gdbserver/linux-aarch32-tdesc.cc -@@ -32,7 +32,7 @@ aarch32_linux_read_description () - { - if (tdesc_aarch32 == nullptr) - { -- tdesc_aarch32 = aarch32_create_target_description (); -+ tdesc_aarch32 = aarch32_create_target_description (false); - - static const char *expedite_regs[] = { "r11", "sp", "pc", 0 }; - init_target_desc (tdesc_aarch32, expedite_regs); --- -2.35.3 - diff --git a/gdb-backport-buildid-related-changes.patch b/gdb-backport-buildid-related-changes.patch new file mode 100644 index 0000000..8c288ae --- /dev/null +++ b/gdb-backport-buildid-related-changes.patch @@ -0,0 +1,6753 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Andrew Burgess +Date: Wed, 31 Jul 2024 15:58:20 +0100 +Subject: gdb-backport-buildid-related-changes.patch + +;; Backport patches related to build-id usage when opening a core +;; file, and also improving general build-id based lookup. These will +;; all drop out when rebasing to GDB 16. + +backport the following patches related to build-id usage + +This one patch backports the following upstream commits: + + * 195795b0fd4 gdb: fix a target: prefix issue in find_separate_debug_file + * ea4c968ce54 gdb: avoid '//' in filenames when searching for debuginfo + * 22836ca8859 gdb: check for multiple matching build-id files + * 6d45af96ea5 gdbserver: add gdbserver support for vFile::stat packet + * 3055e3d2f13 gdb: add GDB side target_ops::fileio_stat implementation + * 08a115cc1c4 gdb: add target_fileio_stat, but no implementations yet + * c7e38ee47c9 gdb: avoid duplicate search in build_id_to_bfd_suffix + * 10ac7e80c01 gdb: remove find_and_open_solib so_list method + * 3e35b4deae2 gdb/testsuite: tests for debug lookup within the sysroot + * 6dfd07222c0 gdb: convert separate-debug-file to new(ish) debug scheme + * 5cabc8098e6 gdb/python: implement Python find_exec_by_build_id hook + * ef1a41f20b7 gdb: add extension hook ext_lang_find_objfile_from_buildid + * 629bcc68d79 gdb: rename ext_lang_missing_debuginfo_result + * 73d7312ff61 gdb: use mapped file information to improve debuginfod text + * 5ddd0d7eefb gdb/python: avoid depending on the curses library + * 8358d39b4f0 gdb: unify build-id to objfile lookup code + * fa826a4bbe9 gdb: improve shared library build-id check for core-files + * a47a679c769 gdb/corefile: improve file backed mapping handling + * 522875f679b gdb/corefile: don't pretend unavailable sections are readable + * 97832471899 gdb/build-id: protect against weirdly short build-ids + * 9543c37620c gdb/testsuite: make gdb_gnu_strip_debug consistent + * fc240bb143c gdb/fileio: fix errno for packets where an attachment is expected + * df0445b370f gdb/testsuite: fix typo 'unsupport' to 'unsupported' + +I've merged these into a single (large) patch as these all merged +without any changes (i.e. these represent exactly the upstream code), +and all of these will be included in GDB 16, and so should all drop +out together when we rebase to GDB 16 (the next rebase). + +All of these patches relate to either build-id usage when opening a +core file, or improving GDB's build-id based debug lookup. + +diff --git a/gdb/NEWS b/gdb/NEWS +--- a/gdb/NEWS ++++ b/gdb/NEWS +@@ -1,6 +1,36 @@ + What has changed in GDB? + (Organized release by release) + ++*** Change since GDB 15 ++ ++* Python API ++ ++ ** New module gdb.missing_objfile that facilitates dealing with ++ missing objfiles when opening a core-file. ++ ++ ** New function gdb.missing_objfile.register_handler that can ++ register an instance of a sub-class of ++ gdb.missing_debug.MissingObjfileHandler as a handler for missing ++ objfiles. ++ ++ ** New class gdb.missing_objfile.MissingObjfileHandler which can be ++ sub-classed to create handlers for missing objfiles. ++ ++* New commands ++ ++info missing-objfile-handlers ++ List all the registered missing-objfile handlers. ++ ++enable missing-objfile-handler LOCUS HANDLER ++disable missing-objfile-handler LOCUS HANDLER ++ Enable or disable a missing-objfile handler with a name matching the ++ regular expression HANDLER, in LOCUS. ++ ++ LOCUS can be 'global' to operate on global missing-objfile handler, ++ 'progspace' to operate on handlers within the current program space, ++ or can be a regular expression which is matched against the filename ++ of the primary executable in each program space. ++ + *** Changes in GDB 15 + + * The MPX commands "show/set mpx bound" have been deprecated, as Intel +@@ -212,6 +242,11 @@ qIsAddressTagged + file is about, this new packet provides a more generic way to perform such + a check. + ++vFile:stat ++ Return information about files on the remote system. Like ++ vFile:fstat but takes a filename rather than an open file ++ descriptor. ++ + *** Changes in GDB 14 + + * GDB now supports the AArch64 Scalable Matrix Extension 2 (SME2), which +diff --git a/gdb/build-id.c b/gdb/build-id.c +--- a/gdb/build-id.c ++++ b/gdb/build-id.c +@@ -26,6 +26,9 @@ + #include "filenames.h" + #include "gdbcore.h" + #include "cli/cli-style.h" ++#include "gdbsupport/scoped_fd.h" ++#include "debuginfod-support.h" ++#include "extension.h" + + /* See build-id.h. */ + +@@ -73,73 +76,177 @@ build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check) + return retval; + } + +-/* Helper for build_id_to_debug_bfd. LINK is a path to a potential +- build-id-based separate debug file, potentially a symlink to the real file. +- If the file exists and matches BUILD_ID, return a BFD reference to it. */ ++/* Helper for build_id_to_debug_bfd. ORIGINAL_LINK with SUFFIX appended is ++ a path to a potential build-id-based separate debug file, potentially a ++ symlink to the real file. If the file exists and matches BUILD_ID, ++ return a BFD reference to it. */ + + static gdb_bfd_ref_ptr +-build_id_to_debug_bfd_1 (const std::string &link, size_t build_id_len, +- const bfd_byte *build_id) ++build_id_to_debug_bfd_1 (const std::string &original_link, ++ size_t build_id_len, const bfd_byte *build_id, ++ const char *suffix) + { +- if (separate_debug_file_debug) ++ tribool supports_target_stat = TRIBOOL_UNKNOWN; ++ ++ /* Drop the 'target:' prefix if the target filesystem is local. */ ++ std::string_view original_link_view (original_link); ++ if (is_target_filename (original_link) && target_filesystem_is_local ()) ++ original_link_view ++ = original_link_view.substr (strlen (TARGET_SYSROOT_PREFIX)); ++ ++ /* The upper bound of '10' here is completely arbitrary. The loop should ++ terminate via 'break' when either (a) a readable symlink is found, or ++ (b) a non-existing entry is found. ++ ++ However, for remote targets, we rely on the remote returning sane ++ error codes. If a remote sends back the wrong error code then it ++ might trick GDB into thinking that the symlink exists, but points to a ++ missing file, in which case GDB will try the next seqno. We don't ++ want a broken remote to cause GDB to spin here forever, hence a fixed ++ upper bound. */ ++ ++ for (unsigned seqno = 0; seqno < 10; seqno++) + { +- gdb_printf (gdb_stdlog, _(" Trying %s..."), link.c_str ()); +- gdb_flush (gdb_stdlog); +- } ++ std::string link (original_link_view); + +- /* lrealpath() is expensive even for the usually non-existent files. */ +- gdb::unique_xmalloc_ptr filename_holder; +- const char *filename = nullptr; +- if (is_target_filename (link)) +- filename = link.c_str (); +- else if (access (link.c_str (), F_OK) == 0) +- { +- filename_holder.reset (lrealpath (link.c_str ())); +- filename = filename_holder.get (); +- } ++ if (seqno > 0) ++ string_appendf (link, ".%u", seqno); + +- if (filename == NULL) +- { +- if (separate_debug_file_debug) +- gdb_printf (gdb_stdlog, +- _(" no, unable to compute real path\n")); ++ link += suffix; + +- return {}; +- } ++ separate_debug_file_debug_printf ("Trying %s...", link.c_str ()); + +- /* We expect to be silent on the non-existing files. */ +- gdb_bfd_ref_ptr debug_bfd = gdb_bfd_open (filename, gnutarget); ++ gdb::unique_xmalloc_ptr filename_holder; ++ const char *filename = nullptr; ++ if (is_target_filename (link)) ++ { ++ gdb_assert (link.length () >= strlen (TARGET_SYSROOT_PREFIX)); ++ const char *link_on_target ++ = link.c_str () + strlen (TARGET_SYSROOT_PREFIX); ++ ++ fileio_error target_errno; ++ if (supports_target_stat != TRIBOOL_FALSE) ++ { ++ struct stat sb; ++ int res = target_fileio_stat (nullptr, link_on_target, &sb, ++ &target_errno); ++ ++ if (res != 0 && target_errno != FILEIO_ENOSYS) ++ { ++ separate_debug_file_debug_printf ("path doesn't exist"); ++ break; ++ } ++ else if (res != 0 && target_errno == FILEIO_ENOSYS) ++ supports_target_stat = TRIBOOL_FALSE; ++ else ++ { ++ supports_target_stat = TRIBOOL_TRUE; ++ filename = link.c_str (); ++ } ++ } ++ ++ if (supports_target_stat == TRIBOOL_FALSE) ++ { ++ gdb_assert (filename == nullptr); ++ ++ /* Connecting to a target that doesn't support 'stat'. Try ++ 'readlink' as an alternative. This isn't ideal, but is ++ maybe better than nothing. Returns EINVAL if the path ++ isn't a symbolic link, which hints that the path is ++ available -- there are other errors e.g. ENOENT for when ++ the path doesn't exist, but we just assume that anything ++ other than EINVAL indicates the path doesn't exist. */ ++ std::optional link_target ++ = target_fileio_readlink (nullptr, link_on_target, ++ &target_errno); ++ if (link_target.has_value () ++ || target_errno == FILEIO_EINVAL) ++ filename = link.c_str (); ++ else ++ { ++ separate_debug_file_debug_printf ("path doesn't exist"); ++ break; ++ } ++ } ++ } ++ else ++ { ++ struct stat buf; ++ ++ /* The `access' call below automatically dereferences LINK, but ++ we want to stop incrementing SEQNO once we find a symlink ++ that doesn't exist. */ ++ if (lstat (link.c_str (), &buf) != 0) ++ { ++ separate_debug_file_debug_printf ("path doesn't exist"); ++ break; ++ } ++ ++ /* Can LINK be accessed, or if LINK is a symlink, can the file ++ pointed too be accessed? Do this as lrealpath() is ++ expensive, even for the usually non-existent files. */ ++ if (access (link.c_str (), F_OK) == 0) ++ { ++ filename_holder.reset (lrealpath (link.c_str ())); ++ filename = filename_holder.get (); ++ } ++ } + +- if (debug_bfd == NULL) +- { +- if (separate_debug_file_debug) +- gdb_printf (gdb_stdlog, _(" no, unable to open.\n")); ++ if (filename == nullptr) ++ { ++ separate_debug_file_debug_printf ("unable to compute real path"); ++ continue; ++ } + +- return {}; +- } ++ /* We expect to be silent on the non-existing files. */ ++ gdb_bfd_ref_ptr debug_bfd = gdb_bfd_open (filename, gnutarget); + +- if (!build_id_verify (debug_bfd.get(), build_id_len, build_id)) +- { +- if (separate_debug_file_debug) +- gdb_printf (gdb_stdlog, _(" no, build-id does not match.\n")); ++ if (debug_bfd == NULL) ++ { ++ separate_debug_file_debug_printf ("unable to open `%s`", filename); ++ continue; ++ } + +- return {}; +- } ++ if (!build_id_verify (debug_bfd.get(), build_id_len, build_id)) ++ { ++ separate_debug_file_debug_printf ("build-id does not match"); ++ continue; ++ } + +- if (separate_debug_file_debug) +- gdb_printf (gdb_stdlog, _(" yes!\n")); ++ separate_debug_file_debug_printf ("found a match"); ++ return debug_bfd; ++ } + +- return debug_bfd; ++ separate_debug_file_debug_printf ("no suitable file found"); ++ return {}; + } + + /* Common code for finding BFDs of a given build-id. This function + works with both debuginfo files (SUFFIX == ".debug") and executable +- files (SUFFIX == ""). */ ++ files (SUFFIX == ""). ++ ++ The build-id will be split into a single byte sub-directory, followed by ++ the remaining build-id bytes as the filename, i.e. we use the lookup ++ format: `.build-id/xx/yy....zz`. As a consequence, if BUILD_ID_LEN is ++ less than 2 (bytes), no results will be found as there are not enough ++ bytes to form the `yy....zz` part of the lookup filename. */ + + static gdb_bfd_ref_ptr + build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id, + const char *suffix) + { ++ SEPARATE_DEBUG_FILE_SCOPED_DEBUG_ENTER_EXIT; ++ ++ if (build_id_len < 2) ++ { ++ /* Zero length build-ids are ignored by bfd. */ ++ gdb_assert (build_id_len > 0); ++ separate_debug_file_debug_printf ++ ("Ignoring short build-id `%s' for build-id based lookup", ++ bin2hex (build_id, build_id_len).c_str ()); ++ return {}; ++ } ++ + /* Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will + cause "/.build-id/..." lookups. */ + +@@ -158,30 +265,33 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id, + std::string link = debugdir.get (); + link += "/.build-id/"; + +- if (size > 0) +- { +- size--; +- string_appendf (link, "%02x/", (unsigned) *data++); +- } ++ gdb_assert (size > 1); ++ size--; ++ string_appendf (link, "%02x/", (unsigned) *data++); + + while (size-- > 0) + string_appendf (link, "%02x", (unsigned) *data++); + +- link += suffix; +- + gdb_bfd_ref_ptr debug_bfd +- = build_id_to_debug_bfd_1 (link, build_id_len, build_id); ++ = build_id_to_debug_bfd_1 (link, build_id_len, build_id, suffix); + if (debug_bfd != NULL) + return debug_bfd; + + /* Try to look under the sysroot as well. If the sysroot is + "/the/sysroot", it will give +- "/the/sysroot/usr/lib/debug/.build-id/ab/cdef.debug". */ ++ "/the/sysroot/usr/lib/debug/.build-id/ab/cdef.debug". ++ ++ If the sysroot is 'target:' and the target filesystem is local to ++ GDB then 'target:/path/to/check' becomes '/path/to/check' which ++ we just checked above. */ + +- if (!gdb_sysroot.empty ()) ++ if (!gdb_sysroot.empty () ++ && (gdb_sysroot != TARGET_SYSROOT_PREFIX ++ || !target_filesystem_is_local ())) + { + link = gdb_sysroot + link; +- debug_bfd = build_id_to_debug_bfd_1 (link, build_id_len, build_id); ++ debug_bfd = build_id_to_debug_bfd_1 (link, build_id_len, build_id, ++ suffix); + if (debug_bfd != NULL) + return debug_bfd; + } +@@ -198,9 +308,11 @@ build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id) + return build_id_to_bfd_suffix (build_id_len, build_id, ".debug"); + } + +-/* See build-id.h. */ ++/* Find and open a BFD for an executable file given a build-id. If no BFD ++ can be found, return NULL. The returned reference to the BFD must be ++ released by the caller. */ + +-gdb_bfd_ref_ptr ++static gdb_bfd_ref_ptr + build_id_to_exec_bfd (size_t build_id_len, const bfd_byte *build_id) + { + return build_id_to_bfd_suffix (build_id_len, build_id, ""); +@@ -217,10 +329,9 @@ find_separate_debug_file_by_buildid (struct objfile *objfile, + build_id = build_id_bfd_get (objfile->obfd.get ()); + if (build_id != NULL) + { +- if (separate_debug_file_debug) +- gdb_printf (gdb_stdlog, +- _("\nLooking for separate debug info (build-id) for " +- "%s\n"), objfile_name (objfile)); ++ SEPARATE_DEBUG_FILE_SCOPED_DEBUG_START_END ++ ("looking for separate debug info (build-id) for %s", ++ objfile_name (objfile)); + + gdb_bfd_ref_ptr abfd (build_id_to_debug_bfd (build_id->size, + build_id->data)); +@@ -229,9 +340,9 @@ find_separate_debug_file_by_buildid (struct objfile *objfile, + && filename_cmp (bfd_get_filename (abfd.get ()), + objfile_name (objfile)) == 0) + { +- if (separate_debug_file_debug) +- gdb_printf (gdb_stdlog, "\"%s\": separate debug info file has no " +- "debug info", bfd_get_filename (abfd.get ())); ++ separate_debug_file_debug_printf ++ ("\"%s\": separate debug info file has no debug info", ++ bfd_get_filename (abfd.get ())); + warnings->warn (_("\"%ps\": separate debug info file has no " + "debug info"), + styled_string (file_name_style.style (), +@@ -243,3 +354,78 @@ find_separate_debug_file_by_buildid (struct objfile *objfile, + + return std::string (); + } ++ ++/* See build-id.h. */ ++ ++gdb_bfd_ref_ptr ++find_objfile_by_build_id (program_space *pspace, ++ const bfd_build_id *build_id, ++ const char *expected_filename) ++{ ++ gdb_bfd_ref_ptr abfd; ++ ++ for (unsigned attempt = 0, max_attempts = 1; ++ attempt < max_attempts && abfd == nullptr; ++ ++attempt) ++ { ++ /* Try to find the executable (or shared object) by looking for a ++ (sym)link on disk from the build-id to the object file. */ ++ abfd = build_id_to_exec_bfd (build_id->size, build_id->data); ++ ++ if (abfd != nullptr || attempt > 0) ++ break; ++ ++ /* Attempt to query debuginfod for the executable. This will only ++ get run during the first attempt, if an extension language hook ++ (see below) asked for a second attempt then we will have already ++ broken out of the loop above. */ ++ gdb::unique_xmalloc_ptr path; ++ scoped_fd fd = debuginfod_exec_query (build_id->data, build_id->size, ++ expected_filename, &path); ++ if (fd.get () >= 0) ++ { ++ abfd = gdb_bfd_open (path.get (), gnutarget); ++ ++ if (abfd == nullptr) ++ warning (_("\"%ps\" from debuginfod cannot be opened as bfd: %s"), ++ styled_string (file_name_style.style (), path.get ()), ++ gdb_bfd_errmsg (bfd_get_error (), nullptr).c_str ()); ++ else if (!build_id_verify (abfd.get (), build_id->size, ++ build_id->data)) ++ abfd = nullptr; ++ } ++ ++ if (abfd != nullptr) ++ break; ++ ++ ext_lang_missing_file_result ext_result ++ = ext_lang_find_objfile_from_buildid (pspace, build_id, ++ expected_filename); ++ if (!ext_result.filename ().empty ()) ++ { ++ /* The extension identified the file for us. */ ++ abfd = gdb_bfd_open (ext_result.filename ().c_str (), gnutarget); ++ if (abfd == nullptr) ++ { ++ warning (_("\"%ps\" from extension cannot be opened as bfd: %s"), ++ styled_string (file_name_style.style (), ++ ext_result.filename ().c_str ()), ++ gdb_bfd_errmsg (bfd_get_error (), nullptr).c_str ()); ++ break; ++ } ++ ++ /* If the extension gave us a path to a file then we always ++ assume that it is the correct file, we do no additional check ++ of its build-id. */ ++ } ++ else if (ext_result.try_again ()) ++ { ++ /* The extension might have installed the file in the expected ++ location, we should try again. */ ++ max_attempts = 2; ++ continue; ++ } ++ } ++ ++ return abfd; ++} +diff --git a/gdb/build-id.h b/gdb/build-id.h +--- a/gdb/build-id.h ++++ b/gdb/build-id.h +@@ -40,13 +40,6 @@ extern int build_id_verify (bfd *abfd, + extern gdb_bfd_ref_ptr build_id_to_debug_bfd (size_t build_id_len, + const bfd_byte *build_id); + +-/* Find and open a BFD for an executable file given a build-id. If no BFD +- can be found, return NULL. The returned reference to the BFD must be +- released by the caller. */ +- +-extern gdb_bfd_ref_ptr build_id_to_exec_bfd (size_t build_id_len, +- const bfd_byte *build_id); +- + /* Find the separate debug file for OBJFILE, by using the build-id + associated with OBJFILE's BFD. If successful, returns the file name for the + separate debug file, otherwise, return an empty string. +@@ -60,6 +53,22 @@ extern gdb_bfd_ref_ptr build_id_to_exec_bfd (size_t build_id_len, + extern std::string find_separate_debug_file_by_buildid + (struct objfile *objfile, deferred_warnings *warnings); + ++/* Find an objfile (executable or shared library) that matches BUILD_ID. ++ This is done by first checking in the debug-file-directory for a ++ suitable .build-id/ sub-directory, and looking for a file with the ++ required build-id (usually a symbolic link or hard link to the actual ++ file). ++ ++ If that doesn't find us a file then we call to debuginfod to see if it ++ can provide the required file. ++ ++ EXPECTED_FILENAME is used in output messages from debuginfod, this ++ should be the file we were looking for but couldn't find. */ ++ ++extern gdb_bfd_ref_ptr find_objfile_by_build_id ++ (struct program_space *pspace, const bfd_build_id *build_id, ++ const char *expected_filename); ++ + /* Return an hex-string representation of BUILD_ID. */ + + static inline std::string +diff --git a/gdb/corelow.c b/gdb/corelow.c +--- a/gdb/corelow.c ++++ b/gdb/corelow.c +@@ -47,17 +47,130 @@ + #include "gdbsupport/pathstuff.h" + #include "gdbsupport/scoped_fd.h" + #include "gdbsupport/x86-xstate.h" +-#include "debuginfod-support.h" + #include + #include + #include "cli/cli-cmds.h" + #include "xml-tdesc.h" + #include "memtag.h" ++#include "cli/cli-style.h" + + #ifndef O_LARGEFILE + #define O_LARGEFILE 0 + #endif + ++/* A mem_range and the build-id associated with the file mapped into the ++ given range. */ ++ ++struct mem_range_and_build_id ++{ ++ mem_range_and_build_id (mem_range &&r, const bfd_build_id *id) ++ : range (r), ++ build_id (id) ++ { /* Nothing. */ } ++ ++ /* A range of memory addresses. */ ++ mem_range range; ++ ++ /* The build-id of the file mapped into RANGE. */ ++ const bfd_build_id *build_id; ++}; ++ ++/* An instance of this class is created within the core_target and is used ++ to hold all the information that relating to mapped files, their address ++ ranges, and their corresponding build-ids. */ ++ ++struct mapped_file_info ++{ ++ /* See comment on function definition. */ ++ ++ void add (const char *soname, const char *expected_filename, ++ const char *actual_filename, std::vector &&ranges, ++ const bfd_build_id *build_id); ++ ++ /* See comment on function definition. */ ++ ++ std::optional ++ lookup (const char *filename, const std::optional &addr); ++ ++private: ++ ++ /* Helper for ::lookup. BUILD_ID is a build-id that was found in ++ one of the data structures within this class. Lookup the ++ corresponding filename in m_build_id_to_filename_map and return a pair ++ containing the build-id and filename. ++ ++ If no corresponding filename is found in m_build_id_to_filename_map ++ then the returned pair contains BUILD_ID and an empty string. ++ ++ If BUILD_ID is nullptr then the returned pair contains nullptr and an ++ empty string. */ ++ ++ struct core_target_mapped_file_info ++ make_result (const bfd_build_id *build_id) ++ { ++ if (build_id != nullptr) ++ { ++ auto it = m_build_id_to_filename_map.find (build_id); ++ if (it != m_build_id_to_filename_map.end ()) ++ return { build_id, it->second }; ++ } ++ ++ return { build_id, {} }; ++ } ++ ++ /* A type that maps a string to a build-id. */ ++ using string_to_build_id_map ++ = std::unordered_map; ++ ++ /* A type that maps a build-id to a string. */ ++ using build_id_to_string_map ++ = std::unordered_map; ++ ++ /* When loading a core file, the build-ids are extracted based on the ++ file backed mappings. This map associates the name of a file that was ++ mapped into the core file with the corresponding build-id. The ++ build-id pointers in this map will never be nullptr as we only record ++ files if they have a build-id. */ ++ ++ string_to_build_id_map m_filename_to_build_id_map; ++ ++ /* Map a build-id pointer back to the name of the file that was mapped ++ into the inferior's address space. If we lookup a matching build-id ++ using either a soname or an address then this map allows us to also ++ provide a full path to a file with a matching build-id. */ ++ ++ build_id_to_string_map m_build_id_to_filename_map; ++ ++ /* If the file that was mapped into the core file was a shared library ++ then it might have a DT_SONAME tag in its .dynamic section, this tag ++ contains the name of a shared object. When opening a shared library, ++ if it's basename appears in this map then we can use the corresponding ++ build-id. ++ ++ In the rare case that two different files have the same DT_SONAME ++ value then the build-id pointer in this map will be nullptr, this ++ indicates that it's not possible to find a build-id based on the given ++ DT_SONAME value. */ ++ ++ string_to_build_id_map m_soname_to_build_id_map; ++ ++ /* This vector maps memory ranges onto an associated build-id. The ++ ranges are those of the files mapped into the core file. ++ ++ Entries in this vector must not overlap, and are sorted be increasing ++ memory address. Within each entry the build-id pointer will not be ++ nullptr. ++ ++ While building this vector the entries are not sorted, they are ++ sorted once after the table has finished being built. */ ++ ++ std::vector m_address_to_build_id_list; ++ ++ /* False if address_to_build_id_list is unsorted, otherwise true. */ ++ ++ bool m_address_to_build_id_list_sorted = false; ++}; ++ + /* The core file target. */ + + static const target_info core_target_info = { +@@ -134,6 +247,34 @@ class core_target final : public process_stratum_target + /* See definition. */ + void info_proc_mappings (struct gdbarch *gdbarch); + ++ std::optional ++ lookup_mapped_file_info (const char *filename, ++ const std::optional &addr) ++ { ++ return m_mapped_file_info.lookup (filename, addr); ++ } ++ ++ /* Return a string containing the expected executable filename obtained ++ from the mapped file information within the core file. The filename ++ returned will be for the mapped file whose ELF headers are mapped at ++ the lowest address (i.e. which GDB encounters first). ++ ++ If no suitable filename can be found then the returned string will be ++ empty. ++ ++ If there are no build-ids embedded into the core file then the ++ returned string will be empty. ++ ++ If a non-empty string is returned then there is no guarantee that the ++ named file exists on disk, or if it does exist on disk, then the ++ on-disk file might have a different build-id to the desired ++ build-id. */ ++ const std::string & ++ expected_exec_filename () const ++ { ++ return m_expected_exec_filename; ++ } ++ + private: /* per-core data */ + + /* Get rid of the core inferior. */ +@@ -156,19 +297,23 @@ class core_target final : public process_stratum_target + still be useful. */ + std::vector m_core_unavailable_mappings; + +- /* Build m_core_file_mappings. Called from the constructor. */ +- void build_file_mappings (); ++ /* Data structure that holds information mapping filenames and address ++ ranges to the corresponding build-ids as well as the reverse build-id ++ to filename mapping. */ ++ mapped_file_info m_mapped_file_info; + +- /* Helper method for xfer_partial. */ +- enum target_xfer_status xfer_memory_via_mappings (gdb_byte *readbuf, +- const gdb_byte *writebuf, +- ULONGEST offset, +- ULONGEST len, +- ULONGEST *xfered_len); ++ /* Build m_core_file_mappings and m_mapped_file_info. Called from the ++ constructor. */ ++ void build_file_mappings (); + + /* FIXME: kettenis/20031023: Eventually this field should + disappear. */ + struct gdbarch *m_core_gdbarch = NULL; ++ ++ /* If not empty then this contains the name of the executable discovered ++ when processing the memory-mapped file information. This will only ++ be set if we find a mapped with a suitable build-id. */ ++ std::string m_expected_exec_filename; + }; + + core_target::core_target () +@@ -216,9 +361,51 @@ core_target::core_target () + void + core_target::build_file_mappings () + { ++ /* Type holding information about a single file mapped into the inferior ++ at the point when the core file was created. Associates a build-id ++ with the list of regions the file is mapped into. */ ++ struct mapped_file ++ { ++ /* Type for a region of a file that was mapped into the inferior when ++ the core file was generated. */ ++ struct region ++ { ++ /* Constructor. See member variables for argument descriptions. */ ++ region (CORE_ADDR start_, CORE_ADDR end_, CORE_ADDR file_ofs_) ++ : start (start_), ++ end (end_), ++ file_ofs (file_ofs_) ++ { /* Nothing. */ } ++ ++ /* The inferior address for the start of the mapped region. */ ++ CORE_ADDR start; ++ ++ /* The inferior address immediately after the mapped region. */ ++ CORE_ADDR end; ++ ++ /* The offset within the mapped file for this content. */ ++ CORE_ADDR file_ofs; ++ }; ++ ++ /* If not nullptr, then this is the build-id associated with this ++ file. */ ++ const bfd_build_id *build_id = nullptr; ++ ++ /* If true then we have seen multiple different build-ids associated ++ with the same filename. The build_id field will have been set back ++ to nullptr, and we should not set build_id in future. */ ++ bool ignore_build_id_p = false; ++ ++ /* All the mapped regions of this file. */ ++ std::vector regions; ++ }; ++ + std::unordered_map bfd_map; + std::unordered_set unavailable_paths; + ++ /* All files mapped into the core file. The key is the filename. */ ++ std::unordered_map mapped_files; ++ + /* See linux_read_core_file_mappings() in linux-tdep.c for an example + read_core_file_mappings method. */ + gdbarch_read_core_file_mappings (m_core_gdbarch, +@@ -239,87 +426,206 @@ core_target::build_file_mappings () + weed out non-file-backed mappings. */ + gdb_assert (filename != nullptr); + +- if (unavailable_paths.find (filename) != unavailable_paths.end ()) +- { +- /* We have already seen some mapping for FILENAME but failed to +- find/open the file. There is no point in trying the same +- thing again so just record that the range [start, end) is +- unavailable. */ +- m_core_unavailable_mappings.emplace_back (start, end - start); +- return; +- } +- +- struct bfd *bfd = bfd_map[filename]; +- if (bfd == nullptr) ++ /* Add this mapped region to the data for FILENAME. */ ++ mapped_file &file_data = mapped_files[filename]; ++ file_data.regions.emplace_back (start, end, file_ofs); ++ if (build_id != nullptr && !file_data.ignore_build_id_p) + { +- /* Use exec_file_find() to do sysroot expansion. It'll +- also strip the potential sysroot "target:" prefix. If +- there is no sysroot, an equivalent (possibly more +- canonical) pathname will be provided. */ +- gdb::unique_xmalloc_ptr expanded_fname +- = exec_file_find (filename, NULL); +- +- if (expanded_fname == nullptr && build_id != nullptr) +- debuginfod_exec_query (build_id->data, build_id->size, +- filename, &expanded_fname); +- +- if (expanded_fname == nullptr) ++ if (file_data.build_id == nullptr) ++ file_data.build_id = build_id; ++ else if (!build_id_equal (build_id, file_data.build_id)) + { +- m_core_unavailable_mappings.emplace_back (start, end - start); +- unavailable_paths.insert (filename); +- warning (_("Can't open file %s during file-backed mapping " +- "note processing"), +- filename); +- return; ++ warning (_("Multiple build-ids found for %ps"), ++ styled_string (file_name_style.style (), filename)); ++ file_data.build_id = nullptr; ++ file_data.ignore_build_id_p = true; + } ++ } ++ }); + +- bfd = bfd_openr (expanded_fname.get (), "binary"); ++ /* Get the build-id of the core file. */ ++ const bfd_build_id *core_build_id ++ = build_id_bfd_get (current_program_space->core_bfd ()); + +- if (bfd == nullptr || !bfd_check_format (bfd, bfd_object)) +- { +- m_core_unavailable_mappings.emplace_back (start, end - start); +- unavailable_paths.insert (filename); +- warning (_("Can't open file %s which was expanded to %s " ++ for (const auto &iter : mapped_files) ++ { ++ const std::string &filename = iter.first; ++ const mapped_file &file_data = iter.second; ++ ++ /* If this mapped file has the same build-id as was discovered for ++ the core-file itself, then we assume this is the main ++ executable. Record the filename as we can use this later. */ ++ if (file_data.build_id != nullptr ++ && m_expected_exec_filename.empty () ++ && build_id_equal (file_data.build_id, core_build_id)) ++ m_expected_exec_filename = filename; ++ ++ /* Use exec_file_find() to do sysroot expansion. It'll ++ also strip the potential sysroot "target:" prefix. If ++ there is no sysroot, an equivalent (possibly more ++ canonical) pathname will be provided. */ ++ gdb::unique_xmalloc_ptr expanded_fname ++ = exec_file_find (filename.c_str (), nullptr); ++ ++ bool build_id_mismatch = false; ++ if (expanded_fname != nullptr && file_data.build_id != nullptr) ++ { ++ /* We temporarily open the bfd as a structured target, this ++ allows us to read the build-id from the bfd if there is one. ++ For this task it's OK if we reuse an already open bfd object, ++ so we make this call through GDB's bfd cache. Once we've ++ checked the build-id (if there is one) we'll drop this ++ reference and re-open the bfd using the "binary" target. */ ++ gdb_bfd_ref_ptr tmp_bfd ++ = gdb_bfd_open (expanded_fname.get (), gnutarget); ++ ++ if (tmp_bfd != nullptr ++ && bfd_check_format (tmp_bfd.get (), bfd_object) ++ && build_id_bfd_get (tmp_bfd.get ()) != nullptr) ++ { ++ /* The newly opened TMP_BFD has a build-id, and this mapped ++ file has a build-id extracted from the core-file. Check ++ the build-id's match, and if not, reject TMP_BFD. */ ++ const struct bfd_build_id *found ++ = build_id_bfd_get (tmp_bfd.get ()); ++ if (!build_id_equal (found, file_data.build_id)) ++ build_id_mismatch = true; ++ } ++ } ++ ++ gdb_bfd_ref_ptr abfd; ++ if (expanded_fname != nullptr && !build_id_mismatch) ++ { ++ struct bfd *b = bfd_openr (expanded_fname.get (), "binary"); ++ abfd = gdb_bfd_ref_ptr::new_reference (b); ++ } ++ ++ if ((expanded_fname == nullptr ++ || abfd == nullptr ++ || !bfd_check_format (abfd.get (), bfd_object)) ++ && file_data.build_id != nullptr) ++ { ++ abfd = find_objfile_by_build_id (current_program_space, ++ file_data.build_id, ++ filename.c_str ()); ++ ++ if (abfd != nullptr) ++ { ++ /* The find_objfile_by_build_id will have opened ABFD using ++ the GNUTARGET global bfd type, however, we need the bfd ++ opened as the binary type (see the function's header ++ comment), so now we reopen ABFD with the desired binary ++ type. */ ++ expanded_fname ++ = make_unique_xstrdup (bfd_get_filename (abfd.get ())); ++ struct bfd *b = bfd_openr (expanded_fname.get (), "binary"); ++ gdb_assert (b != nullptr); ++ abfd = gdb_bfd_ref_ptr::new_reference (b); ++ } ++ } ++ ++ std::vector ranges; ++ for (const mapped_file::region ®ion : file_data.regions) ++ ranges.emplace_back (region.start, region.end - region.start); ++ ++ if (expanded_fname == nullptr ++ || abfd == nullptr ++ || !bfd_check_format (abfd.get (), bfd_object)) ++ { ++ /* If ABFD was opened, but the wrong format, close it now. */ ++ abfd = nullptr; ++ ++ /* Record all regions for this file as unavailable. */ ++ for (const mapped_file::region ®ion : file_data.regions) ++ m_core_unavailable_mappings.emplace_back (region.start, ++ region.end ++ - region.start); ++ ++ /* And give the user an appropriate warning. */ ++ if (build_id_mismatch) ++ { ++ if (expanded_fname == nullptr ++ || filename == expanded_fname.get ()) ++ warning (_("File %ps doesn't match build-id from core-file " ++ "during file-backed mapping processing"), ++ styled_string (file_name_style.style (), ++ filename.c_str ())); ++ else ++ warning (_("File %ps which was expanded to %ps, doesn't match " ++ "build-id from core-file during file-backed " ++ "mapping processing"), ++ styled_string (file_name_style.style (), ++ filename.c_str ()), ++ styled_string (file_name_style.style (), ++ expanded_fname.get ())); ++ } ++ else ++ { ++ if (expanded_fname == nullptr ++ || filename == expanded_fname.get ()) ++ warning (_("Can't open file %ps during file-backed mapping " ++ "note processing"), ++ styled_string (file_name_style.style (), ++ filename.c_str ())); ++ else ++ warning (_("Can't open file %ps which was expanded to %ps " + "during file-backed mapping note processing"), +- filename, expanded_fname.get ()); ++ styled_string (file_name_style.style (), ++ filename.c_str ()), ++ styled_string (file_name_style.style (), ++ expanded_fname.get ())); ++ } ++ } ++ else ++ { ++ /* Ensure that the bfd will be closed when core_bfd is closed. ++ This can be checked before/after a core file detach via "maint ++ info bfds". */ ++ gdb_bfd_record_inclusion (current_program_space->core_bfd (), ++ abfd.get ()); ++ ++ /* Create sections for each mapped region. */ ++ for (const mapped_file::region ®ion : file_data.regions) ++ { ++ /* Make new BFD section. All sections have the same name, ++ which is permitted by bfd_make_section_anyway(). */ ++ asection *sec = bfd_make_section_anyway (abfd.get (), "load"); ++ if (sec == nullptr) ++ error (_("Can't make section")); ++ sec->filepos = region.file_ofs; ++ bfd_set_section_flags (sec, SEC_READONLY | SEC_HAS_CONTENTS); ++ bfd_set_section_size (sec, region.end - region.start); ++ bfd_set_section_vma (sec, region.start); ++ bfd_set_section_lma (sec, region.start); ++ bfd_set_section_alignment (sec, 2); ++ ++ /* Set target_section fields. */ ++ m_core_file_mappings.emplace_back (region.start, region.end, sec); ++ } ++ } + +- if (bfd != nullptr) +- bfd_close (bfd); +- return; +- } +- /* Ensure that the bfd will be closed when core_bfd is closed. +- This can be checked before/after a core file detach via +- "maint info bfds". */ +- gdb_bfd_record_inclusion (current_program_space->core_bfd (), bfd); +- bfd_map[filename] = bfd; +- } ++ /* If this is a bfd with a build-id then record the filename, ++ optional soname (DT_SONAME .dynamic attribute), and the range of ++ addresses at which this bfd is mapped. This information can be ++ used to perform build-id checking when loading the shared ++ libraries. */ ++ if (file_data.build_id != nullptr) ++ { ++ normalize_mem_ranges (&ranges); + +- /* Make new BFD section. All sections have the same name, +- which is permitted by bfd_make_section_anyway(). */ +- asection *sec = bfd_make_section_anyway (bfd, "load"); +- if (sec == nullptr) +- error (_("Can't make section")); +- sec->filepos = file_ofs; +- bfd_set_section_flags (sec, SEC_READONLY | SEC_HAS_CONTENTS); +- bfd_set_section_size (sec, end - start); +- bfd_set_section_vma (sec, start); +- bfd_set_section_lma (sec, start); +- bfd_set_section_alignment (sec, 2); +- +- /* Set target_section fields. */ +- m_core_file_mappings.emplace_back (start, end, sec); +- +- /* If this is a bfd of a shared library, record its soname +- and build id. */ +- if (build_id != nullptr) +- { +- gdb::unique_xmalloc_ptr soname +- = gdb_bfd_read_elf_soname (bfd->filename); +- if (soname != nullptr) +- set_cbfd_soname_build_id (current_program_space->cbfd, +- soname.get (), build_id); +- } +- }); ++ const char *actual_filename = nullptr; ++ gdb::unique_xmalloc_ptr soname; ++ if (abfd != nullptr) ++ { ++ actual_filename = bfd_get_filename (abfd.get ()); ++ soname = gdb_bfd_read_elf_soname (actual_filename); ++ } ++ ++ m_mapped_file_info.add (soname.get (), filename.c_str (), ++ actual_filename, std::move (ranges), ++ file_data.build_id); ++ } ++ } + + normalize_mem_ranges (&m_core_unavailable_mappings); + } +@@ -564,36 +870,31 @@ rename_vmcore_idle_reg_sections (bfd *abfd, inferior *inf) + BFD ABFD. */ + + static void +-locate_exec_from_corefile_build_id (bfd *abfd, int from_tty) ++locate_exec_from_corefile_build_id (bfd *abfd, core_target *target, ++ int from_tty) + { + const bfd_build_id *build_id = build_id_bfd_get (abfd); + if (build_id == nullptr) + return; + +- gdb_bfd_ref_ptr execbfd +- = build_id_to_exec_bfd (build_id->size, build_id->data); ++ /* The filename used for the find_objfile_by_build_id call. */ ++ std::string filename; + +- if (execbfd == nullptr) ++ if (!target->expected_exec_filename ().empty ()) ++ filename = target->expected_exec_filename (); ++ else + { +- /* Attempt to query debuginfod for the executable. */ +- gdb::unique_xmalloc_ptr execpath; +- scoped_fd fd = debuginfod_exec_query (build_id->data, build_id->size, +- abfd->filename, &execpath); +- +- if (fd.get () >= 0) +- { +- execbfd = gdb_bfd_open (execpath.get (), gnutarget); +- +- if (execbfd == nullptr) +- warning (_("\"%s\" from debuginfod cannot be opened as bfd: %s"), +- execpath.get (), +- gdb_bfd_errmsg (bfd_get_error (), nullptr).c_str ()); +- else if (!build_id_verify (execbfd.get (), build_id->size, +- build_id->data)) +- execbfd.reset (nullptr); +- } ++ /* We didn't find an executable name from the mapped file ++ information, so as a stand-in build a string based on the ++ build-id. */ ++ std::string build_id_hex_str = bin2hex (build_id->data, build_id->size); ++ filename = string_printf ("with build-id %s", build_id_hex_str.c_str ()); + } + ++ gdb_bfd_ref_ptr execbfd ++ = find_objfile_by_build_id (current_program_space, build_id, ++ filename.c_str ()); ++ + if (execbfd != nullptr) + { + exec_file_attach (bfd_get_filename (execbfd.get ()), from_tty); +@@ -724,7 +1025,7 @@ core_target_open (const char *arg, int from_tty) + + if (current_program_space->exec_bfd () == nullptr) + locate_exec_from_corefile_build_id (current_program_space->core_bfd (), +- from_tty); ++ target, from_tty); + + post_create_inferior (from_tty); + +@@ -963,55 +1264,6 @@ core_target::files_info () + print_section_info (&m_core_section_table, current_program_space->core_bfd ()); + } + +-/* Helper method for core_target::xfer_partial. */ +- +-enum target_xfer_status +-core_target::xfer_memory_via_mappings (gdb_byte *readbuf, +- const gdb_byte *writebuf, +- ULONGEST offset, ULONGEST len, +- ULONGEST *xfered_len) +-{ +- enum target_xfer_status xfer_status; +- +- xfer_status = (section_table_xfer_memory_partial +- (readbuf, writebuf, +- offset, len, xfered_len, +- m_core_file_mappings)); +- +- if (xfer_status == TARGET_XFER_OK || m_core_unavailable_mappings.empty ()) +- return xfer_status; +- +- /* There are instances - e.g. when debugging within a docker +- container using the AUFS storage driver - where the pathnames +- obtained from the note section are incorrect. Despite the path +- being wrong, just knowing the start and end addresses of the +- mappings is still useful; we can attempt an access of the file +- stratum constrained to the address ranges corresponding to the +- unavailable mappings. */ +- +- ULONGEST memaddr = offset; +- ULONGEST memend = offset + len; +- +- for (const auto &mr : m_core_unavailable_mappings) +- { +- if (mr.contains (memaddr)) +- { +- if (!mr.contains (memend)) +- len = mr.start + mr.length - memaddr; +- +- xfer_status = this->beneath ()->xfer_partial (TARGET_OBJECT_MEMORY, +- NULL, +- readbuf, +- writebuf, +- offset, +- len, +- xfered_len); +- break; +- } +- } +- +- return xfer_status; +-} + + enum target_xfer_status + core_target::xfer_partial (enum target_object object, const char *annex, +@@ -1039,26 +1291,72 @@ core_target::xfer_partial (enum target_object object, const char *annex, + if (xfer_status == TARGET_XFER_OK) + return TARGET_XFER_OK; + +- /* Check file backed mappings. If they're available, use +- core file provided mappings (e.g. from .note.linuxcore.file +- or the like) as this should provide a more accurate +- result. If not, check the stratum beneath us, which should +- be the file stratum. ++ /* Check file backed mappings. If they're available, use core file ++ provided mappings (e.g. from .note.linuxcore.file or the like) ++ as this should provide a more accurate result. */ ++ if (!m_core_file_mappings.empty ()) ++ { ++ xfer_status = section_table_xfer_memory_partial ++ (readbuf, writebuf, offset, len, xfered_len, ++ m_core_file_mappings); ++ if (xfer_status == TARGET_XFER_OK) ++ return xfer_status; ++ } + +- We also check unavailable mappings due to Docker/AUFS driver +- issues. */ +- if (!m_core_file_mappings.empty () +- || !m_core_unavailable_mappings.empty ()) ++ /* If the access is within an unavailable file mapping then we try ++ to check in the stratum below (the executable stratum). The ++ thinking here is that if the mapping was read/write then the ++ contents would have been written into the core file and the ++ access would have been satisfied by m_core_section_table. ++ ++ But if the access has not yet been resolved then we can assume ++ the access is read-only. If the executable was not found ++ during the mapped file check then we'll have an unavailable ++ mapping entry, however, if the user has provided the executable ++ (maybe in a different location) then we might be able to ++ resolve the access from there. ++ ++ If that fails, but the access is within an unavailable region, ++ then the access itself should fail. */ ++ for (const auto &mr : m_core_unavailable_mappings) + { +- xfer_status = xfer_memory_via_mappings (readbuf, writebuf, offset, ++ if (mr.contains (offset)) ++ { ++ if (!mr.contains (offset + len)) ++ len = mr.start + mr.length - offset; ++ ++ xfer_status ++ = this->beneath ()->xfer_partial (TARGET_OBJECT_MEMORY, ++ nullptr, readbuf, ++ writebuf, offset, + len, xfered_len); ++ if (xfer_status == TARGET_XFER_OK) ++ return TARGET_XFER_OK; ++ ++ return TARGET_XFER_E_IO; ++ } ++ } ++ ++ /* The following is acting as a fallback in case we encounter a ++ situation where the core file is lacking and mapped file ++ information. Here we query the exec file stratum to see if it ++ can resolve the access. Doing this when we are missing mapped ++ file information might be the best we can do, but there are ++ certainly cases this will get wrong, e.g. if an inferior created ++ a zero initialised mapping over the top of some data that exists ++ within the executable then this will return the executable data ++ rather than the zero data. Maybe we should just drop this ++ block? */ ++ if (m_core_file_mappings.empty () ++ && m_core_unavailable_mappings.empty ()) ++ { ++ xfer_status ++ = this->beneath ()->xfer_partial (object, annex, readbuf, ++ writebuf, offset, len, ++ xfered_len); ++ if (xfer_status == TARGET_XFER_OK) ++ return TARGET_XFER_OK; + } +- else +- xfer_status = this->beneath ()->xfer_partial (object, annex, readbuf, +- writebuf, offset, len, +- xfered_len); +- if (xfer_status == TARGET_XFER_OK) +- return TARGET_XFER_OK; + + /* Finally, attempt to access data in core file sections with + no contents. These will typically read as all zero. */ +@@ -1515,6 +1813,182 @@ maintenance_print_core_file_backed_mappings (const char *args, int from_tty) + targ->info_proc_mappings (targ->core_gdbarch ()); + } + ++/* Add more details discovered while processing the core-file's mapped file ++ information, we're building maps between filenames and the corresponding ++ build-ids, between address ranges and the corresponding build-ids, and ++ also a reverse map between build-id and the corresponding filename. ++ ++ SONAME is the DT_SONAME attribute extracted from the .dynamic section of ++ a shared library that was mapped into the core file. This can be ++ nullptr if the mapped files was not a shared library, or didn't have a ++ DT_SONAME attribute. ++ ++ EXPECTED_FILENAME is the name of the file that was mapped into the ++ inferior as extracted from the core file, this should never be nullptr. ++ ++ ACTUAL_FILENAME is the name of the actual file GDB found to provide the ++ mapped file information, this can be nullptr if GDB failed to find a ++ suitable file. This might be different to EXPECTED_FILENAME, e.g. GDB ++ might have downloaded the file from debuginfod and so ACTUAL_FILENAME ++ will be a file in the debuginfod client cache. ++ ++ RANGES is the list of memory ranges at which this file was mapped into ++ the inferior. ++ ++ BUILD_ID is the build-id for this mapped file, this will never be ++ nullptr. Not every mapped file will have a build-id, but there's no ++ point calling this function if we failed to find a build-id; this ++ structure only exists so we can lookup files based on their build-id. */ ++ ++void ++mapped_file_info::add (const char *soname, ++ const char *expected_filename, ++ const char *actual_filename, ++ std::vector &&ranges, ++ const bfd_build_id *build_id) ++{ ++ gdb_assert (build_id != nullptr); ++ gdb_assert (expected_filename != nullptr); ++ ++ if (soname != nullptr) ++ { ++ /* If we already have an entry with this SONAME then this indicates ++ that the inferior has two files mapped into memory with different ++ file names (and most likely different build-ids), but with the ++ same DT_SONAME attribute. In this case we can't use the ++ DT_SONAME to figure out the expected build-id of a shared ++ library, so poison the entry for this SONAME by setting the entry ++ to nullptr. */ ++ auto it = m_soname_to_build_id_map.find (soname); ++ if (it != m_soname_to_build_id_map.end () ++ && it->second != nullptr ++ && !build_id_equal (it->second, build_id)) ++ m_soname_to_build_id_map[soname] = nullptr; ++ else ++ m_soname_to_build_id_map[soname] = build_id; ++ } ++ ++ /* When the core file is initially opened and the mapped files are ++ parsed, we group the build-id information based on the file name. As ++ a consequence, we should see each EXPECTED_FILENAME value exactly ++ once. This means that each insertion should always succeed. */ ++ const auto [it, inserted] ++ = m_filename_to_build_id_map.emplace (expected_filename, build_id); ++ gdb_assert (inserted); ++ ++ /* Setup the reverse build-id to file name map. */ ++ if (actual_filename != nullptr) ++ m_build_id_to_filename_map.emplace (build_id, actual_filename); ++ ++ /* Setup the list of memory range to build-id objects. */ ++ for (mem_range &r : ranges) ++ m_address_to_build_id_list.emplace_back (std::move (r), build_id); ++ ++ /* At this point the m_address_to_build_id_list is unsorted (we just ++ added some entries to the end of the list). All entries should be ++ added before any look-ups are performed, and the list is only sorted ++ when the first look-up is performed. */ ++ gdb_assert (!m_address_to_build_id_list_sorted); ++} ++ ++/* FILENAME is the name of a file GDB is trying to load, and ADDR is ++ (optionally) an address within the file in the inferior's address space. ++ ++ Search through the information gathered from the core-file's mapped file ++ information looking for a file named FILENAME, or for a file that covers ++ ADDR. If a match is found then return the build-id for the file along ++ with the location where GDB found the mapped file. ++ ++ The location of the mapped file might be the empty string if GDB was ++ unable to find the mapped file. ++ ++ If no build-id can be found for FILENAME then GDB will return a pair ++ containing nullptr (for the build-id) and an empty string for the file ++ name. */ ++ ++std::optional ++mapped_file_info::lookup (const char *filename, ++ const std::optional &addr) ++{ ++ if (filename != nullptr) ++ { ++ /* If there's a matching entry in m_filename_to_build_id_map then the ++ associated build-id will not be nullptr, and can be used to ++ validate that FILENAME is correct. */ ++ auto it = m_filename_to_build_id_map.find (filename); ++ if (it != m_filename_to_build_id_map.end ()) ++ return make_result (it->second); ++ } ++ ++ if (addr.has_value ()) ++ { ++ /* On the first lookup, sort the address_to_build_id_list. */ ++ if (!m_address_to_build_id_list_sorted) ++ { ++ std::sort (m_address_to_build_id_list.begin (), ++ m_address_to_build_id_list.end (), ++ [] (const mem_range_and_build_id &a, ++ const mem_range_and_build_id &b) { ++ return a.range < b.range; ++ }); ++ m_address_to_build_id_list_sorted = true; ++ } ++ ++ /* Look for the first entry whose range's start address is not less ++ than, or equal too, the address ADDR. If we find such an entry, ++ then the previous entry's range might contain ADDR. If it does ++ then that previous entry's build-id can be used. */ ++ auto it = std::lower_bound ++ (m_address_to_build_id_list.begin (), ++ m_address_to_build_id_list.end (), ++ *addr, ++ [] (const mem_range_and_build_id &a, ++ const CORE_ADDR &b) { ++ return a.range.start <= b; ++ }); ++ ++ if (it != m_address_to_build_id_list.begin ()) ++ { ++ --it; ++ ++ if (it->range.contains (*addr)) ++ return make_result (it->build_id); ++ } ++ } ++ ++ if (filename != nullptr) ++ { ++ /* If the basename of FILENAME appears in m_soname_to_build_id_map ++ then when the mapped files were processed, we saw a file with a ++ DT_SONAME attribute corresponding to FILENAME, use that build-id ++ to validate FILENAME. ++ ++ However, the build-id in this map might be nullptr if we saw ++ multiple mapped files with the same DT_SONAME attribute (though ++ this should be pretty rare). */ ++ auto it ++ = m_soname_to_build_id_map.find (lbasename (filename)); ++ if (it != m_soname_to_build_id_map.end () ++ && it->second != nullptr) ++ return make_result (it->second); ++ } ++ ++ return {}; ++} ++ ++/* See gdbcore.h. */ ++ ++std::optional ++core_target_find_mapped_file (const char *filename, ++ std::optional addr) ++{ ++ core_target *targ = get_current_core_target (); ++ if (targ == nullptr || current_program_space->cbfd.get () == nullptr) ++ return {}; ++ ++ return targ->lookup_mapped_file_info (filename, addr); ++} ++ + void _initialize_corelow (); + void + _initialize_corelow () +diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in +--- a/gdb/data-directory/Makefile.in ++++ b/gdb/data-directory/Makefile.in +@@ -77,6 +77,8 @@ PYTHON_FILE_LIST = \ + gdb/FrameIterator.py \ + gdb/frames.py \ + gdb/missing_debug.py \ ++ gdb/missing_objfile.py \ ++ gdb/missing_files.py \ + gdb/printing.py \ + gdb/prompt.py \ + gdb/styling.py \ +@@ -86,7 +88,7 @@ PYTHON_FILE_LIST = \ + gdb/command/__init__.py \ + gdb/command/explore.py \ + gdb/command/frame_filters.py \ +- gdb/command/missing_debug.py \ ++ gdb/command/missing_files.py \ + gdb/command/pretty_printers.py \ + gdb/command/prompt.py \ + gdb/command/type_printers.py \ +diff --git a/gdb/debuginfod-support.c b/gdb/debuginfod-support.c +--- a/gdb/debuginfod-support.c ++++ b/gdb/debuginfod-support.c +@@ -409,7 +409,7 @@ debuginfod_exec_query (const unsigned char *build_id, + std::optional term_state; + + { +- user_data data ("executable for", filename); ++ user_data data ("file", filename); + + debuginfod_set_user_data (c, &data); + if (target_supports_terminal_ours ()) +@@ -423,7 +423,7 @@ debuginfod_exec_query (const unsigned char *build_id, + debuginfod_set_user_data (c, nullptr); + } + +- print_outcome (fd.get (), "executable for", filename); ++ print_outcome (fd.get (), "file", filename); + + if (fd.get () >= 0) + destname->reset (dname); +diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo +--- a/gdb/doc/gdb.texinfo ++++ b/gdb/doc/gdb.texinfo +@@ -21786,6 +21786,7 @@ + @c (eg rooted in val of env var GDBSYMS) could exist for mappable symbol + @c files. + ++@anchor{core-file command} + @kindex core-file + @item core-file @r{[}@var{filename}@r{]} + @itemx core +@@ -24534,6 +24535,10 @@ + @tab @code{vFile:fstat} + @tab Host I/O + ++@item @code{hostio-stat-packet} ++@tab @code{vFile:stat} ++@tab Host I/O ++ + @item @code{hostio-setfs-packet} + @tab @code{vFile:setfs} + @tab Host I/O +@@ -46289,6 +46294,13 @@ + If an error occurs the return value is -1. The format of the + returned binary attachment is as described in @ref{struct stat}. + ++@item vFile:stat: @var{filename} ++Get information about the file @var{filename} on the target. ++On success the information is returned as a binary attachment ++and the return value is the size of this attachment in bytes. ++If an error occurs the return value is -1. The format of the ++returned binary attachment is as described in @ref{struct stat}. ++ + @item vFile:unlink: @var{filename} + Delete the file at @var{filename} on the target. Return 0, + or -1 if an error occurs. The @var{filename} is a string. +diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi +--- a/gdb/doc/python.texi ++++ b/gdb/doc/python.texi +@@ -231,6 +231,7 @@ + * TUI Windows In Python:: Implementing new TUI windows. + * Disassembly In Python:: Instruction Disassembly In Python + * Missing Debug Info In Python:: Handle missing debug info from Python. ++* Missing Objfiles In Python:: Handle objfiles from Python. + @end menu + + @node Basic Python +@@ -5370,10 +5371,11 @@ + objects. @xref{Frame Filter API}, for more information. + @end defvar + +-@defvar Progspace.missing_debug_handlers +-The @code{missing_debug_handlers} attribute is a list of the missing +-debug handler objects for this program space. @xref{Missing Debug +-Info In Python}, for more information. ++@defvar Progspace.missing_file_handlers ++The @code{missing_file_handlers} attribute is a list of tuples. Each ++tuple holds a missing-file handler object for this program space. For ++more information, @pxref{Missing Debug Info In Python}, and ++@ref{Missing Objfiles In Python}. + @end defvar + + A program space has the following methods: +@@ -5549,6 +5551,7 @@ + @code{gdb.Objfile.add_separate_debug_file} method, described below. + @end defvar + ++@anchor{Objfile.build_id} + @defvar Objfile.build_id + The build ID of the objfile as a string. + If the objfile does not have a build ID then the value is @code{None}. +@@ -8137,6 +8140,189 @@ + for this objfile. + @end defun + ++@node Missing Objfiles In Python ++@subsubsection Missing Objfiles In Python ++@cindex python, handle missing objfiles ++ ++When @value{GDBN} opens a core file, for example with the ++@kbd{core-file} command (@pxref{core-file command}), @value{GDBN} will ++attempt to load the corresponding executable and shared libraries. ++Often these files can be found on the local machine, but sometimes ++these files cannot be found, in which case the debugging experience ++will be restricted. ++ ++If @value{GDBN} fails to locate a particular file then there is an ++opportunity for a Python extension to step in. A Python extension can ++potentially locate the missing file using some platform- or ++project-specific steps, and inform @value{GDBN} of its location. Or a ++Python extension might provide some platform- or project-specific ++advice to the user about how to obtain the missing file. ++ ++A missing-objfile Python extension consists of a handler object which ++has the @code{name} and @code{enabled} attributes, and implements the ++@code{__call__} method. When @value{GDBN} encounters a situation ++where a file cannot be found, but the build-id (@pxref{build ID}) for ++the missing file is known, then the @code{__call__} method is invoked ++to try and find the file. Full details of how handlers are written ++can be found below. ++ ++@subheading The @code{gdb.missing_objfile} Module ++ ++@value{GDBN} comes with a @code{gdb.missing_objfile} module which ++contains the following class and global function: ++ ++@deftp{class} gdb.missing_objfile.MissingObjfileHandler ++ ++@code{MissingObjfileHandler} is a base class from which user-created ++handlers can derive, though it is not required that handlers derive ++from this class, so long as any user created handler has the ++@code{name} and @code{enabled} attributes, and implements the ++@code{__call__} method. ++ ++@defun MissingObjfileHandler.__init__ (name) ++The @var{name} is a string used to reference this missing-objfile ++handler within some @value{GDBN} commands. Valid names consist of the ++characters @samp{[-_a-zA-Z0-9]}, creating a handler with an invalid ++name raises a @code{ValueError} exception. ++@end defun ++ ++@defun MissingObjfileHandler.__call__ (pspace, build_id, filename) ++ ++Sub-classes must override the @code{__call__} method. The ++@var{pspace} argument will be a @code{gdb.Progspace} ++(@pxref{Progspaces In Python}), this is the program space in which ++@value{GDBN} is looking for the missing file. ++ ++The @var{build_id} argument is a string containing the build-id of the ++file that is missing, this will be in the same format as returned by ++@code{Objfile.build_id} (@pxref{Objfile.build_id}). ++ ++The @var{filename} argument contains the name of the file that ++@value{GDBN} is looking for. This information is provided to allow ++handlers to generate informative messages for the user. A handler is ++not required to place the missing file at this location. There might ++already be a file present at this location, but it might not match the ++required build-id, in which case @value{GDBN} will have ignored it. ++In some limited cases @value{GDBN} might not be able to establish the ++@var{filename} of the file it is searching for, in this case ++@value{GDBN} will use a string @samp{with build-id @var{build_id}} as a ++replacement. ++ ++The return value from the @code{__call__} method indicates what ++@value{GDBN} should do next. The possible return values are: ++ ++@itemize @bullet ++@item @code{None} ++ ++This indicates that this handler could not locate the missing file and ++@value{GDBN} should call any other registered handlers. ++ ++@item @code{True} ++ ++This indicates that this handler has installed the missing file into a ++location where @value{GDBN} would normally expect to find it. The ++only location in which @value{GDBN} will look is within the ++@file{.build-id} sub-directory within the @var{debug-file-directory} ++(@pxref{debug-file-directory}). ++ ++@value{GDBN} will repeat the normal lookup process, which should now ++find the previously missing file. ++ ++If @value{GDBN} still doesn't find file after this second attempt, ++then the Python missing-objfile handlers are not invoked a second ++time, this prevents a badly behaved handler causing @value{GDBN} to ++get stuck in a loop. @value{GDBN} will continue without the missing ++file, though this will degrade the debugging experience. ++ ++@item @code{False} ++ ++This indicates that this handler has done everything that it intends ++to do but the missing file could not be found. @value{GDBN} will not ++call any other registered handlers to look for the missing file. ++@value{GDBN} will continue without the missing file, though this will ++degrade the debugging experience. ++ ++@item A string ++ ++The returned string should contain a filename. @value{GDBN} will not ++call any further registered handlers, and will instead use the ++returned filename as the missing file. ++@end itemize ++ ++Invoking the @code{__call__} method from this base class will raise a ++@code{NotImplementedError} exception. ++@end defun ++ ++@defvar MissingObjfileHandler.name ++A read-only attribute which is a string, the name of this handler ++passed to the @code{__init__} method. ++@end defvar ++ ++@defvar MissingObjfileHandler.enabled ++A modifiable attribute containing a boolean; when @code{True}, the ++handler is enabled, and will be used by @value{GDBN}. When ++@code{False}, the handler has been disabled, and will not be used. ++@end defvar ++@end deftp ++ ++@defun gdb.missing_objfile.register_handler (locus, handler, replace=@code{False}) ++Register a new missing-objfile handler with @value{GDBN}. ++ ++@var{handler} is an instance of a sub-class of ++@code{MissingObjfileHandler}, or at least an instance of an object that ++has the same attributes and methods as @code{MissingObjfileHandler}. ++ ++@var{locus} specifies to which handler list to prepend @var{handler}. ++It can be either a @code{gdb.Progspace} (@pxref{Progspaces In Python}) ++or @code{None}, in which case the handler is registered globally. The ++newly registered @var{handler} will be called before any other handler ++from the same locus. Two handlers in the same locus cannot have the ++same name, an attempt to add a handler with an already existing name ++raises an exception unless @var{replace} is @code{True}, in which case ++the old handler is deleted and the new handler is prepended to the ++selected handler list. ++ ++@value{GDBN} first calls the handlers for the current program space, ++and then the globally registered handlers. As soon as a handler ++returns a value other than @code{None}, no further handlers are ++called. ++@end defun ++ ++@subheading Managing Missing-Objfile Handlers ++ ++@value{GDBN} defines the following commands to manage registered ++missing-objfile handlers: ++ ++@table @code ++ ++@kindex info missing-objfile-handlers ++@item info missing-objfile-handlers @r{[} @var{locus} @r{[} @var{name-regexp} @r{]} @r{]} ++Lists all registered missing-objfile handlers. Arguments @var{locus} ++and @var{name-regexp} are both optional and can be used to filter ++which handlers are listed. ++ ++The @var{locus} argument should be either @kbd{global}, ++@kbd{progspace}, or the name of an object file. Only handlers ++registered for the specified locus will be listed. ++ ++The @var{name-regexp} is a regular expression used to match against ++handler names. ++ ++@kindex disable missing-objfile-handler ++@item disable missing-objfile-handler @r{[} @var{locus} @r{[} @var{name-regexp} @r{]} @r{]} ++The @var{locus} and @var{name-regexp} are interpreted as in @kbd{info ++missing-objfile-handlers} above, but instead of listing the matching ++handlers, all of the matching handlers are disabled. The ++@code{enabled} field of each matching handler is set to @code{False}. ++ ++@kindex enable missing-objfile-handler ++@item enable missing-objfile-handler @r{[} @var{locus} @r{[} @var{name-regexp} @r{]} @r{]} ++The @var{locus} and @var{name-regexp} are interpreted as in @kbd{info ++missing-objfile-handlers} above, but instead of listing the matching ++handlers, all of the matching handlers are enabled. The ++@code{enabled} field of each matching handler is set to @code{True}. ++@end table ++ + @node Python Auto-loading + @subsection Python Auto-loading + @cindex Python auto-loading +diff --git a/gdb/extension-priv.h b/gdb/extension-priv.h +--- a/gdb/extension-priv.h ++++ b/gdb/extension-priv.h +@@ -287,9 +287,22 @@ struct extension_language_ops + /* Give extension languages a chance to deal with missing debug + information. OBJFILE is the file for which GDB was unable to find + any debug information. */ +- ext_lang_missing_debuginfo_result ++ ext_lang_missing_file_result + (*handle_missing_debuginfo) (const struct extension_language_defn *, + struct objfile *objfile); ++ ++ /* Give extension languages a chance to deal with missing objfiles. ++ PSPACE is the program space in which GDB is searching for a missing ++ objfile, and will not be NULL. BUILD_ID is the build-id of the ++ objfile we're looking for, and will not be NULL. FILENAME is the name ++ of the file we're looking for, and will not be NULL. See ++ ext_lang_find_objfile_from_buildid for some additional information ++ about the meaning of FILENAME. */ ++ ext_lang_missing_file_result ++ (*find_objfile_from_buildid) (const struct extension_language_defn *, ++ program_space *pspace, ++ const struct bfd_build_id *build_id, ++ const char *filename); + }; + + /* State necessary to restore a signal handler to its previous value. */ +diff --git a/gdb/extension.c b/gdb/extension.c +--- a/gdb/extension.c ++++ b/gdb/extension.c +@@ -1040,7 +1040,7 @@ ext_lang_print_insn (struct gdbarch *gdbarch, CORE_ADDR address, + + /* See extension.h. */ + +-ext_lang_missing_debuginfo_result ++ext_lang_missing_file_result + ext_lang_handle_missing_debuginfo (struct objfile *objfile) + { + for (const struct extension_language_defn *extlang : extension_languages) +@@ -1048,7 +1048,7 @@ ext_lang_handle_missing_debuginfo (struct objfile *objfile) + if (extlang->ops == nullptr + || extlang->ops->handle_missing_debuginfo == nullptr) + continue; +- ext_lang_missing_debuginfo_result result ++ ext_lang_missing_file_result result + = extlang->ops->handle_missing_debuginfo (extlang, objfile); + if (!result.filename ().empty () || result.try_again ()) + return result; +@@ -1057,6 +1057,28 @@ ext_lang_handle_missing_debuginfo (struct objfile *objfile) + return {}; + } + ++/* See extension.h. */ ++ ++ext_lang_missing_file_result ++ext_lang_find_objfile_from_buildid (program_space *pspace, ++ const struct bfd_build_id *build_id, ++ const char *filename) ++{ ++ for (const struct extension_language_defn *extlang : extension_languages) ++ { ++ if (extlang->ops == nullptr ++ || extlang->ops->find_objfile_from_buildid == nullptr) ++ continue; ++ ext_lang_missing_file_result result ++ = extlang->ops->find_objfile_from_buildid (extlang, pspace, build_id, ++ filename); ++ if (!result.filename ().empty () || result.try_again ()) ++ return result; ++ } ++ ++ return {}; ++} ++ + /* Called via an observer before gdb prints its prompt. + Iterate over the extension languages giving them a chance to + change the prompt. The first one to change the prompt wins, +diff --git a/gdb/extension.h b/gdb/extension.h +--- a/gdb/extension.h ++++ b/gdb/extension.h +@@ -36,6 +36,7 @@ struct ui_file; + struct ui_out; + struct value; + struct value_print_options; ++struct program_space; + + /* A function to load and process a script file. + The file has been opened and is ready to be read from the beginning. +@@ -358,23 +359,23 @@ extern std::optional ext_lang_print_insn + it. And the third option is for the extension to just return a null + result, indication there is nothing the extension can do to provide the + missing debug information. */ +-struct ext_lang_missing_debuginfo_result ++struct ext_lang_missing_file_result + { + /* Default result. The extension was unable to provide the missing debug + info. */ +- ext_lang_missing_debuginfo_result () ++ ext_lang_missing_file_result () + { /* Nothing. */ } + + /* When TRY_AGAIN is true GDB should try searching again, the extension + may have installed the missing debug info into a suitable location. + When TRY_AGAIN is false this is equivalent to the default, no + argument, constructor. */ +- ext_lang_missing_debuginfo_result (bool try_again) ++ ext_lang_missing_file_result (bool try_again) + : m_try_again (try_again) + { /* Nothing. */ } + + /* Look in FILENAME for the missing debug info. */ +- ext_lang_missing_debuginfo_result (std::string &&filename) ++ ext_lang_missing_file_result (std::string &&filename) + : m_filename (std::move (filename)) + { /* Nothing. */ } + +@@ -404,9 +405,28 @@ struct ext_lang_missing_debuginfo_result + + /* Called when GDB failed to find any debug information for OBJFILE. */ + +-extern ext_lang_missing_debuginfo_result ext_lang_handle_missing_debuginfo ++extern ext_lang_missing_file_result ext_lang_handle_missing_debuginfo + (struct objfile *objfile); + ++/* Called when GDB opens a core-file to find any object files for which a ++ build-id could be extracted from the core-file, but the matching file ++ could not otherwise be found by GDB. ++ ++ PSPACE is the program space in which GDB is opening the core-file and ++ is looking for a missing object file. BUILD_ID is the build-id of the ++ file being looked for, and will not be NULL. FILENAME is the name of ++ the file GDB is looking for, this will not be NULL. The FILENAME is ++ provided only for creating helpful messages for the user. FILENAME ++ might already exist on disk but have the wrong build-id, of FILENAME ++ might not exist on disk. If the missing objfile can be found then it ++ does not have to be placed at the location FILENAME. ++ ++ The returned object indicates if the file could be found or not. */ ++ ++extern ext_lang_missing_file_result ext_lang_find_objfile_from_buildid ++ (program_space *pspace, const struct bfd_build_id *build_id, ++ const char *filename); ++ + #if GDB_SELF_TEST + namespace selftests { + extern void (*hook_set_active_ext_lang) (); +diff --git a/gdb/gdbcore.h b/gdb/gdbcore.h +--- a/gdb/gdbcore.h ++++ b/gdb/gdbcore.h +@@ -196,4 +196,70 @@ class thread_section_name + std::string m_storage; + }; + ++/* Type returned from core_target_find_mapped_file. Holds information ++ about a mapped file that was processed when a core file was initially ++ loaded. */ ++struct core_target_mapped_file_info ++{ ++ /* Constructor. BUILD_ID is not nullptr, and is the build-id for the ++ mapped file. FILENAME is the location of the file that GDB loaded to ++ provide the mapped file. This might be different from the name of the ++ mapped file mentioned in the core file, e.g. if GDB downloads a file ++ from debuginfod then FILENAME would point into the debuginfod client ++ cache. The FILENAME can be the empty string if GDB was unable to find ++ a file to provide the mapped file. */ ++ ++ core_target_mapped_file_info (const bfd_build_id *build_id, ++ const std::string filename) ++ : m_build_id (build_id), ++ m_filename (filename) ++ { ++ gdb_assert (m_build_id != nullptr); ++ } ++ ++ /* The build-id for this mapped file. */ ++ ++ const bfd_build_id * ++ build_id () const ++ { ++ return m_build_id; ++ } ++ ++ /* The file GDB used to provide this mapped file. */ ++ ++ const std::string & ++ filename () const ++ { ++ return m_filename; ++ } ++ ++private: ++ const bfd_build_id *m_build_id = nullptr; ++ const std::string m_filename; ++}; ++ ++/* If the current inferior has a core_target for its process target, then ++ lookup information about a mapped file that was discovered when the ++ core file was loaded. ++ ++ The FILENAME is the file we're looking for. The ADDR, if provided, is a ++ mapped address within the inferior which is known to be part of the file ++ we are looking for. ++ ++ As an example, when loading shared libraries this function can be ++ called, in that case FILENAME will be the name of the shared library ++ that GDB is trying to load and ADDR will be an inferior address which is ++ part of the shared library we are looking for. ++ ++ This function looks for a mapped file which matches FILENAME and/or ++ which covers ADDR and returns information about that file. ++ ++ The returned information includes the name of the mapped file if known ++ and the build-id for the mapped file if known. ++ ++ */ ++std::optional ++core_target_find_mapped_file (const char *filename, ++ std::optional addr); ++ + #endif /* !defined (GDBCORE_H) */ +diff --git a/gdb/inf-child.c b/gdb/inf-child.c +--- a/gdb/inf-child.c ++++ b/gdb/inf-child.c +@@ -320,6 +320,21 @@ inf_child_target::fileio_fstat (int fd, struct stat *sb, fileio_error *target_er + return ret; + } + ++/* Implementation of to_fileio_stat. */ ++ ++int ++inf_child_target::fileio_stat (struct inferior *inf, const char *filename, ++ struct stat *sb, fileio_error *target_errno) ++{ ++ int ret; ++ ++ ret = lstat (filename, sb); ++ if (ret == -1) ++ *target_errno = host_to_fileio_error (errno); ++ ++ return ret; ++} ++ + /* Implementation of to_fileio_close. */ + + int +diff --git a/gdb/inf-child.h b/gdb/inf-child.h +--- a/gdb/inf-child.h ++++ b/gdb/inf-child.h +@@ -81,6 +81,8 @@ class inf_child_target + int fileio_pread (int fd, gdb_byte *read_buf, int len, + ULONGEST offset, fileio_error *target_errno) override; + int fileio_fstat (int fd, struct stat *sb, fileio_error *target_errno) override; ++ int fileio_stat (struct inferior *inf, const char *filename, ++ struct stat *sb, fileio_error *target_errno) override; + int fileio_close (int fd, fileio_error *target_errno) override; + int fileio_unlink (struct inferior *inf, + const char *filename, +diff --git a/gdb/python/lib/gdb/__init__.py b/gdb/python/lib/gdb/__init__.py +--- a/gdb/python/lib/gdb/__init__.py ++++ b/gdb/python/lib/gdb/__init__.py +@@ -87,8 +87,9 @@ xmethods = [] + frame_filters = {} + # Initial frame unwinders. + frame_unwinders = [] +-# Initial missing debug handlers. +-missing_debug_handlers = [] ++# The missing file handlers. Each item is a tuple with the form ++# (TYPE, HANDLER) where TYPE is a string either 'debug' or 'objfile'. ++missing_file_handlers = [] + + + def _execute_unwinders(pending_frame): +@@ -271,6 +272,61 @@ class Thread(threading.Thread): + super().start() + + ++def _filter_missing_file_handlers(handlers, handler_type): ++ """Each list of missing file handlers is a list of tuples, the first ++ item in the tuple is a string either 'debug' or 'objfile' to ++ indicate what type of handler it is. The second item in the tuple ++ is the actual handler object. ++ ++ This function takes HANDLER_TYPE which is a string, either 'debug' ++ or 'objfile' and HANDLERS, a list of tuples. The function returns ++ an iterable over all of the handler objects (extracted from the ++ tuples) which match HANDLER_TYPE. ++ """ ++ ++ return map(lambda t: t[1], filter(lambda t: t[0] == handler_type, handlers)) ++ ++ ++def _handle_missing_files(pspace, handler_type, cb): ++ """Helper for _handle_missing_debuginfo and _handle_missing_objfile. ++ ++ Arguments: ++ pspace: The gdb.Progspace in which we're operating. Used to ++ lookup program space specific handlers. ++ handler_type: A string, either 'debug' or 'objfile', this is the ++ type of handler we're looking for. ++ cb: A callback which takes a handler and returns the result of ++ calling the handler. ++ ++ Returns: ++ None: No suitable file could be found. ++ False: A handler has decided that the requested file cannot be ++ found, and no further searching should be done. ++ True: The file has been found and installed in a location ++ where GDB would normally look for it. GDB should ++ repeat its lookup process, the file should now be in ++ place. ++ A string: This is the filename of where the missing file can ++ be found. ++ """ ++ ++ for handler in _filter_missing_file_handlers( ++ pspace.missing_file_handlers, handler_type ++ ): ++ if handler.enabled: ++ result = cb(handler) ++ if result is not None: ++ return result ++ ++ for handler in _filter_missing_file_handlers(missing_file_handlers, handler_type): ++ if handler.enabled: ++ result = cb(handler) ++ if result is not None: ++ return result ++ ++ return None ++ ++ + def _handle_missing_debuginfo(objfile): + """Internal function called from GDB to execute missing debug + handlers. +@@ -293,18 +349,46 @@ def _handle_missing_debuginfo(objfile): + A string: This is the filename of a file containing the + required debug information. + """ ++ + pspace = objfile.progspace + +- for handler in pspace.missing_debug_handlers: +- if handler.enabled: +- result = handler(objfile) +- if result is not None: +- return result ++ return _handle_missing_files(pspace, "debug", lambda h: h(objfile)) + +- for handler in missing_debug_handlers: +- if handler.enabled: +- result = handler(objfile) +- if result is not None: +- return result + +- return None ++def _handle_missing_objfile(pspace, buildid, filename): ++ """Internal function called from GDB to execute missing objfile ++ handlers. ++ ++ Run each of the currently registered, and enabled missing objfile ++ handler objects for the gdb.Progspace passed in as an argument, ++ and then from the global list. Stop after the first handler that ++ returns a result other than None. ++ ++ Arguments: ++ pspace: A gdb.Progspace for which the missing objfile handlers ++ should be run. This is the program space in which an ++ objfile was found to be missing. ++ buildid: A string containing the build-id we're looking for. ++ filename: The filename of the file GDB tried to find but ++ couldn't. This is not where the file should be ++ placed if found, in fact, this file might already ++ exist on disk but have the wrong build-id. This is ++ mostly provided in order to be used in messages to ++ the user. ++ ++ Returns: ++ None: No objfile could be found for this build-id. ++ False: A handler has done all it can with for this build-id, ++ but no objfile could be found. ++ True: An objfile might have been installed by a handler, GDB ++ should check again. The only place GDB checks is within ++ the .build-id sub-directory within the ++ debug-file-directory. If the required file was not ++ installed there then GDB will not find it. ++ A string: This is the filename of a file containing the ++ missing objfile. ++ """ ++ ++ return _handle_missing_files( ++ pspace, "objfile", lambda h: h(pspace, buildid, filename) ++ ) +diff --git a/gdb/python/lib/gdb/command/missing_debug.py b/gdb/python/lib/gdb/command/missing_files.py +similarity index 54% +rename from gdb/python/lib/gdb/command/missing_debug.py +rename to gdb/python/lib/gdb/command/missing_files.py +--- a/gdb/python/lib/gdb/command/missing_debug.py ++++ b/gdb/python/lib/gdb/command/missing_files.py +@@ -1,4 +1,4 @@ +-# Missing debug related commands. ++# Missing debug and objfile related commands. + # + # Copyright 2023-2024 Free Software Foundation, Inc. + # +@@ -21,7 +21,7 @@ import gdb + + + def validate_regexp(exp, idstring): +- """Compile exp into a compiler regular expression object. ++ """Compile exp into a compiled regular expression object. + + Arguments: + exp: The string to compile into a re.Pattern object. +@@ -33,14 +33,15 @@ def validate_regexp(exp, idstring): + Raises: + SyntaxError: If exp is an invalid regexp. + """ ++ + try: + return re.compile(exp) + except SyntaxError: + raise SyntaxError("Invalid %s regexp: %s." % (idstring, exp)) + + +-def parse_missing_debug_command_args(arg): +- """Internal utility to parse missing debug handler command argv. ++def parse_missing_file_command_args(arg): ++ """Internal utility to parse missing file handler command argv. + + Arguments: + arg: The arguments to the command. The format is: +@@ -52,6 +53,7 @@ def parse_missing_debug_command_args(arg): + Raises: + SyntaxError: an error processing ARG + """ ++ + argv = gdb.string_to_argv(arg) + argc = len(argv) + if argc > 2: +@@ -68,10 +70,10 @@ def parse_missing_debug_command_args(arg): + ) + + +-class InfoMissingDebugHanders(gdb.Command): +- """GDB command to list missing debug handlers. ++class InfoMissingFileHandlers(gdb.Command): ++ """GDB command to list missing HTYPE handlers. + +- Usage: info missing-debug-handlers [LOCUS-REGEXP [NAME-REGEXP]] ++ Usage: info missing-HTYPE-handlers [LOCUS-REGEXP [NAME-REGEXP]] + + LOCUS-REGEXP is a regular expression matching the location of the + handler. If it is omitted, all registered handlers from all +@@ -79,38 +81,47 @@ class InfoMissingDebugHanders(gdb.Command): + the handlers from the current progspace, or a regular expression + matching filenames of progspaces. + +- NAME-REGEXP is a regular expression to filter missing debug ++ NAME-REGEXP is a regular expression to filter missing HTYPE + handler names. If this omitted for a specified locus, then all + registered handlers in the locus are listed. + """ + +- def __init__(self): +- super().__init__("info missing-debug-handlers", gdb.COMMAND_FILES) ++ def __init__(self, handler_type): ++ # Update the doc string before calling the parent constructor, ++ # replacing the string 'HTYPE' with the value of HANDLER_TYPE. ++ # The parent constructor will grab a copy of this string to ++ # use as the commands help text. ++ self.__doc__ = self.__doc__.replace("HTYPE", handler_type) ++ super().__init__( ++ "info missing-" + handler_type + "-handlers", gdb.COMMAND_FILES ++ ) ++ self.handler_type = handler_type + + def list_handlers(self, title, handlers, name_re): +- """Lists the missing debug handlers whose name matches regexp. ++ """Lists the missing file handlers whose name matches regexp. + + Arguments: + title: The line to print before the list. +- handlers: The list of the missing debug handlers. ++ handlers: The list of the missing file handlers. + name_re: handler name filter. + """ ++ + if not handlers: + return + print(title) +- for handler in handlers: ++ for handler in gdb._filter_missing_file_handlers(handlers, self.handler_type): + if name_re.match(handler.name): + print( + " %s%s" % (handler.name, "" if handler.enabled else " [disabled]") + ) + + def invoke(self, arg, from_tty): +- locus_re, name_re = parse_missing_debug_command_args(arg) ++ locus_re, name_re = parse_missing_file_command_args(arg) + + if locus_re.match("progspace") and locus_re.pattern != "": + cp = gdb.current_progspace() + self.list_handlers( +- "Progspace %s:" % cp.filename, cp.missing_debug_handlers, name_re ++ "Progspace %s:" % cp.filename, cp.missing_file_handlers, name_re + ) + + for progspace in gdb.progspaces(): +@@ -125,58 +136,71 @@ class InfoMissingDebugHanders(gdb.Command): + msg = "Progspace %s:" % filename + self.list_handlers( + msg, +- progspace.missing_debug_handlers, ++ progspace.missing_file_handlers, + name_re, + ) + + # Print global handlers last, as these are invoked last. + if locus_re.match("global"): +- self.list_handlers("Global:", gdb.missing_debug_handlers, name_re) ++ self.list_handlers("Global:", gdb.missing_file_handlers, name_re) + + +-def do_enable_handler1(handlers, name_re, flag): +- """Enable/disable missing debug handlers whose names match given regex. ++def do_enable_handler1(handlers, name_re, flag, handler_type): ++ """Enable/disable missing file handlers whose names match given regex. + + Arguments: +- handlers: The list of missing debug handlers. ++ handlers: The list of missing file handlers. + name_re: Handler name filter. + flag: A boolean indicating if we should enable or disable. ++ handler_type: A string, either 'debug' or 'objfile', use to control ++ which handlers are modified. + + Returns: + The number of handlers affected. + """ ++ + total = 0 +- for handler in handlers: ++ for handler in gdb._filter_missing_file_handlers(handlers, handler_type): + if name_re.match(handler.name) and handler.enabled != flag: + handler.enabled = flag + total += 1 + return total + + +-def do_enable_handler(arg, flag): +- """Enable or disable missing debug handlers.""" +- (locus_re, name_re) = parse_missing_debug_command_args(arg) ++def do_enable_handler(arg, flag, handler_type): ++ """Enable or disable missing file handlers.""" ++ ++ (locus_re, name_re) = parse_missing_file_command_args(arg) + total = 0 + if locus_re.match("global"): +- total += do_enable_handler1(gdb.missing_debug_handlers, name_re, flag) ++ total += do_enable_handler1( ++ gdb.missing_file_handlers, name_re, flag, handler_type ++ ) + if locus_re.match("progspace") and locus_re.pattern != "": + total += do_enable_handler1( +- gdb.current_progspace().missing_debug_handlers, name_re, flag ++ gdb.current_progspace().missing_file_handlers, name_re, flag, handler_type + ) + for progspace in gdb.progspaces(): + filename = progspace.filename or "" + if locus_re.match(filename): +- total += do_enable_handler1(progspace.missing_debug_handlers, name_re, flag) ++ total += do_enable_handler1( ++ progspace.missing_file_handlers, name_re, flag, handler_type ++ ) + print( +- "%d missing debug handler%s %s" +- % (total, "" if total == 1 else "s", "enabled" if flag else "disabled") ++ "%d missing %s handler%s %s" ++ % ( ++ total, ++ handler_type, ++ "" if total == 1 else "s", ++ "enabled" if flag else "disabled", ++ ) + ) + + +-class EnableMissingDebugHandler(gdb.Command): +- """GDB command to enable missing debug handlers. ++class EnableMissingFileHandler(gdb.Command): ++ """GDB command to enable missing HTYPE handlers. + +- Usage: enable missing-debug-handler [LOCUS-REGEXP [NAME-REGEXP]] ++ Usage: enable missing-HTYPE-handler [LOCUS-REGEXP [NAME-REGEXP]] + + LOCUS-REGEXP is a regular expression specifying the handlers to + enable. It can be 'global', 'progspace' for the current +@@ -187,18 +211,26 @@ class EnableMissingDebugHandler(gdb.Command): + in the locus are affected. + """ + +- def __init__(self): +- super().__init__("enable missing-debug-handler", gdb.COMMAND_FILES) ++ def __init__(self, handler_type): ++ # Update the doc string before calling the parent constructor, ++ # replacing the string 'HTYPE' with the value of HANDLER_TYPE. ++ # The parent constructor will grab a copy of this string to ++ # use as the commands help text. ++ self.__doc__ = self.__doc__.replace("HTYPE", handler_type) ++ super().__init__( ++ "enable missing-" + handler_type + "-handler", gdb.COMMAND_FILES ++ ) ++ self.handler_type = handler_type + + def invoke(self, arg, from_tty): + """GDB calls this to perform the command.""" +- do_enable_handler(arg, True) ++ do_enable_handler(arg, True, self.handler_type) + + +-class DisableMissingDebugHandler(gdb.Command): +- """GDB command to disable missing debug handlers. ++class DisableMissingFileHandler(gdb.Command): ++ """GDB command to disable missing HTYPE handlers. + +- Usage: disable missing-debug-handler [LOCUS-REGEXP [NAME-REGEXP]] ++ Usage: disable missing-HTYPE-handler [LOCUS-REGEXP [NAME-REGEXP]] + + LOCUS-REGEXP is a regular expression specifying the handlers to + enable. It can be 'global', 'progspace' for the current +@@ -209,19 +241,28 @@ class DisableMissingDebugHandler(gdb.Command): + in the locus are affected. + """ + +- def __init__(self): +- super().__init__("disable missing-debug-handler", gdb.COMMAND_FILES) ++ def __init__(self, handler_type): ++ # Update the doc string before calling the parent constructor, ++ # replacing the string 'HTYPE' with the value of HANDLER_TYPE. ++ # The parent constructor will grab a copy of this string to ++ # use as the commands help text. ++ self.__doc__ = self.__doc__.replace("HTYPE", handler_type) ++ super().__init__( ++ "disable missing-" + handler_type + "-handler", gdb.COMMAND_FILES ++ ) ++ self.handler_type = handler_type + + def invoke(self, arg, from_tty): + """GDB calls this to perform the command.""" +- do_enable_handler(arg, False) ++ do_enable_handler(arg, False, self.handler_type) + + +-def register_missing_debug_handler_commands(): +- """Installs the missing debug handler commands.""" +- InfoMissingDebugHanders() +- EnableMissingDebugHandler() +- DisableMissingDebugHandler() ++def register_missing_file_handler_commands(): ++ """Installs the missing file handler commands.""" ++ for handler_type in ["debug", "objfile"]: ++ InfoMissingFileHandlers(handler_type) ++ EnableMissingFileHandler(handler_type) ++ DisableMissingFileHandler(handler_type) + + +-register_missing_debug_handler_commands() ++register_missing_file_handler_commands() +diff --git a/gdb/python/lib/gdb/missing_debug.py b/gdb/python/lib/gdb/missing_debug.py +--- a/gdb/python/lib/gdb/missing_debug.py ++++ b/gdb/python/lib/gdb/missing_debug.py +@@ -17,48 +17,11 @@ + MissingDebugHandler base class, and register_handler function. + """ + +-import sys +- + import gdb ++from gdb.missing_files import MissingFileHandler + +-if sys.version_info >= (3, 7): +- # Functions str.isascii() and str.isalnum are available starting Python +- # 3.7. +- def isascii(ch): +- return ch.isascii() +- +- def isalnum(ch): +- return ch.isalnum() +- +-else: +- # Fall back to curses.ascii.isascii() and curses.ascii.isalnum() for +- # earlier versions. +- from curses.ascii import isalnum, isascii +- +- +-def _validate_name(name): +- """Validate a missing debug handler name string. +- +- If name is valid as a missing debug handler name, then this +- function does nothing. If name is not valid then an exception is +- raised. +- +- Arguments: +- name: A string, the name of a missing debug handler. +- +- Returns: +- Nothing. + +- Raises: +- ValueError: If name is invalid as a missing debug handler +- name. +- """ +- for ch in name: +- if not isascii(ch) or not (isalnum(ch) or ch in "_-"): +- raise ValueError("invalid character '%s' in handler name: %s" % (ch, name)) +- +- +-class MissingDebugHandler(object): ++class MissingDebugHandler(MissingFileHandler): + """Base class for missing debug handlers written in Python. + + A missing debug handler has a single method __call__ along with +@@ -69,41 +32,8 @@ class MissingDebugHandler(object): + enabled: When true this handler is enabled. + """ + +- def __init__(self, name): +- """Constructor. +- +- Args: +- name: An identifying name for this handler. +- +- Raises: +- TypeError: name is not a string. +- ValueError: name contains invalid characters. +- """ +- +- if not isinstance(name, str): +- raise TypeError("incorrect type for name: %s" % type(name)) +- +- _validate_name(name) +- +- self._name = name +- self._enabled = True +- +- @property +- def name(self): +- return self._name +- +- @property +- def enabled(self): +- return self._enabled +- +- @enabled.setter +- def enabled(self, value): +- if not isinstance(value, bool): +- raise TypeError("incorrect type for enabled attribute: %s" % type(value)) +- self._enabled = value +- + def __call__(self, objfile): +- """GDB handle missing debug information for an objfile. ++ """Handle missing debug information for an objfile. + + Arguments: + objfile: A gdb.Objfile for which GDB could not find any +@@ -124,62 +54,5 @@ class MissingDebugHandler(object): + + + def register_handler(locus, handler, replace=False): +- """Register handler in given locus. +- +- The handler is prepended to the locus's missing debug handlers +- list. The name of handler should be unique (or replace must be +- True). +- +- Arguments: +- locus: Either a progspace, or None (in which case the unwinder +- is registered globally). +- handler: An object of a gdb.MissingDebugHandler subclass. +- +- replace: If True, replaces existing handler with the same name +- within locus. Otherwise, raises RuntimeException if +- unwinder with the same name already exists. +- +- Returns: +- Nothing. +- +- Raises: +- RuntimeError: The name of handler is not unique. +- TypeError: Bad locus type. +- AttributeError: Required attributes of handler are missing. +- """ +- +- if locus is None: +- if gdb.parameter("verbose"): +- gdb.write("Registering global %s handler ...\n" % handler.name) +- locus = gdb +- elif isinstance(locus, gdb.Progspace): +- if gdb.parameter("verbose"): +- gdb.write( +- "Registering %s handler for %s ...\n" % (handler.name, locus.filename) +- ) +- else: +- raise TypeError("locus should be gdb.Progspace or None") +- +- # Some sanity checks on HANDLER. Calling getattr will raise an +- # exception if the attribute doesn't exist, which is what we want. +- # These checks are not exhaustive; we don't check the attributes +- # have the correct types, or the method has the correct signature, +- # but this should catch some basic mistakes. +- getattr(handler, "name") +- getattr(handler, "enabled") +- call_method = getattr(handler, "__call__") +- if not callable(call_method): +- raise AttributeError( +- "'%s' object's '__call__' attribute is not callable" +- % type(handler).__name__ +- ) +- +- i = 0 +- for needle in locus.missing_debug_handlers: +- if needle.name == handler.name: +- if replace: +- del locus.missing_debug_handlers[i] +- else: +- raise RuntimeError("Handler %s already exists." % handler.name) +- i += 1 +- locus.missing_debug_handlers.insert(0, handler) ++ """See gdb.missing_files.register_handler.""" ++ gdb.missing_files.register_handler("debug", locus, handler, replace) +diff --git a/gdb/python/lib/gdb/missing_files.py b/gdb/python/lib/gdb/missing_files.py +new file mode 100644 +--- /dev/null ++++ b/gdb/python/lib/gdb/missing_files.py +@@ -0,0 +1,204 @@ ++# Copyright (C) 2023-2024 Free Software Foundation, Inc. ++ ++# 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 . ++ ++""" ++MissingFileHandler base class, and support functions used by the ++missing_debug.py and missing_objfile.py modules. ++""" ++ ++import sys ++ ++import gdb ++ ++if sys.version_info >= (3, 7): ++ # Functions str.isascii() and str.isalnum are available starting Python ++ # 3.7. ++ def isascii(ch): ++ return ch.isascii() ++ ++ def isalnum(ch): ++ return ch.isalnum() ++ ++else: ++ # Older version of Python doesn't have str.isascii() and ++ # str.isalnum() so provide our own. ++ # ++ # We could import isalnum() and isascii() from the curses library, ++ # but that adds an extra dependency. Given these functions are ++ # both small and trivial lets implement them here. ++ # ++ # These definitions are based on those in the curses library, but ++ # simplified as we know C will always be a single character 'str'. ++ ++ def isdigit(c): ++ return 48 <= ord(c) <= 57 ++ ++ def islower(c): ++ return 97 <= ord(c) <= 122 ++ ++ def isupper(c): ++ return 65 <= ord(c) <= 90 ++ ++ def isalpha(c): ++ return isupper(c) or islower(c) ++ ++ def isalnum(c): ++ return isalpha(c) or isdigit(c) ++ ++ def isascii(c): ++ return 0 <= ord(c) <= 127 ++ ++ ++def _validate_name(name): ++ """Validate a missing file handler name string. ++ ++ If name is valid as a missing file handler name, then this ++ function does nothing. If name is not valid then an exception is ++ raised. ++ ++ Arguments: ++ name: A string, the name of a missing file handler. ++ ++ Returns: ++ Nothing. ++ ++ Raises: ++ ValueError: If name is invalid as a missing file handler ++ name. ++ """ ++ ++ for ch in name: ++ if not isascii(ch) or not (isalnum(ch) or ch in "_-"): ++ raise ValueError("invalid character '%s' in handler name: %s" % (ch, name)) ++ ++ ++class MissingFileHandler(object): ++ """Base class for missing file handlers written in Python. ++ ++ A missing file handler has a single method __call__ along with the ++ read/write attribute enabled, and a read-only attribute name. The ++ attributes are provided by this class while the __call__ method is ++ provided by a sub-class. Each sub-classes __call__ method will ++ have a different signature. ++ ++ Attributes: ++ name: Read-only attribute, the name of this handler. ++ enabled: When true this handler is enabled. ++ """ ++ ++ def __init__(self, name): ++ """Constructor. ++ ++ Args: ++ name: An identifying name for this handler. ++ ++ Raises: ++ TypeError: name is not a string. ++ ValueError: name contains invalid characters. ++ """ ++ ++ if not isinstance(name, str): ++ raise TypeError("incorrect type for name: %s" % type(name)) ++ ++ _validate_name(name) ++ ++ self._name = name ++ self._enabled = True ++ ++ @property ++ def name(self): ++ return self._name ++ ++ @property ++ def enabled(self): ++ return self._enabled ++ ++ @enabled.setter ++ def enabled(self, value): ++ if not isinstance(value, bool): ++ raise TypeError("incorrect type for enabled attribute: %s" % type(value)) ++ self._enabled = value ++ ++ ++def register_handler(handler_type, locus, handler, replace=False): ++ """Register handler in given locus. ++ ++ The handler is prepended to the locus's missing file handlers ++ list. The name of handler should be unique (or replace must be ++ True), and the name must pass the _validate_name check. ++ ++ Arguments: ++ handler_type: A string, either 'debug' or 'objfile' indicating the ++ type of handler to be registered. ++ locus: Either a progspace, or None (in which case the unwinder ++ is registered globally). ++ handler: An object used as a missing file handler. Usually a ++ sub-class of MissingFileHandler. ++ replace: If True, replaces existing handler with the same name ++ within locus. Otherwise, raises RuntimeException if ++ unwinder with the same name already exists. ++ ++ Returns: ++ Nothing. ++ ++ Raises: ++ RuntimeError: The name of handler is not unique. ++ TypeError: Bad locus type. ++ AttributeError: Required attributes of handler are missing. ++ ValueError: If the name of the handler is invalid, or if ++ handler_type is neither 'debug' or 'objfile'. ++ """ ++ ++ if handler_type != "debug" and handler_type != "objfile": ++ raise ValueError("handler_type must be 'debug' or 'objfile'") ++ ++ if locus is None: ++ if gdb.parameter("verbose"): ++ gdb.write("Registering global %s handler ...\n" % handler.name) ++ locus = gdb ++ elif isinstance(locus, gdb.Progspace): ++ if gdb.parameter("verbose"): ++ gdb.write( ++ "Registering %s handler for %s ...\n" % (handler.name, locus.filename) ++ ) ++ else: ++ raise TypeError("locus should be gdb.Progspace or None") ++ ++ # Some sanity checks on HANDLER. Calling getattr will raise an ++ # exception if the attribute doesn't exist, which is what we want. ++ # These checks are not exhaustive; we don't check the attributes ++ # have the correct types, or the method has the correct signature, ++ # but this should catch some basic mistakes. ++ name = getattr(handler, "name") ++ _validate_name(name) ++ ++ getattr(handler, "enabled") ++ ++ call_method = getattr(handler, "__call__") ++ if not callable(call_method): ++ raise AttributeError( ++ "'%s' object's '__call__' attribute is not callable" ++ % type(handler).__name__ ++ ) ++ ++ i = 0 ++ for needle in locus.missing_file_handlers: ++ if needle[0] == handler_type and needle[1].name == handler.name: ++ if replace: ++ del locus.missing_file_handlers[i] ++ else: ++ raise RuntimeError("Handler %s already exists." % handler.name) ++ i += 1 ++ locus.missing_file_handlers.insert(0, (handler_type, handler)) +diff --git a/gdb/python/lib/gdb/missing_objfile.py b/gdb/python/lib/gdb/missing_objfile.py +new file mode 100644 +--- /dev/null ++++ b/gdb/python/lib/gdb/missing_objfile.py +@@ -0,0 +1,67 @@ ++# Copyright (C) 2024 Free Software Foundation, Inc. ++ ++# 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 . ++ ++""" ++MissingObjfileHandler base class, and register_handler function. ++""" ++ ++import gdb ++from gdb.missing_files import MissingFileHandler ++ ++ ++class MissingObjfileHandler(MissingFileHandler): ++ """Base class for missing objfile handlers written in Python. ++ ++ A missing objfile handler has a single method __call__ along with ++ the read/write attribute enabled, and a read-only attribute name. ++ ++ Attributes: ++ name: Read-only attribute, the name of this handler. ++ enabled: When true this handler is enabled. ++ """ ++ ++ def __call__(self, buildid, filename): ++ """Handle a missing objfile when GDB can knows the build-id. ++ ++ Arguments: ++ ++ buildid: A string containing the build-id for the objfile ++ GDB is searching for. ++ filename: A string containing the name of the file GDB is ++ searching for. This is provided only for the purpose ++ of creating diagnostic messages. If the file is found ++ it does not have to be placed here, and this file ++ might already exist but GDB has determined it is not ++ suitable for use, e.g. if the build-id doesn't match. ++ ++ Returns: ++ ++ True: GDB should try again to locate the missing objfile, ++ the handler may have installed the missing file. ++ False: GDB should move on without the objfile. The ++ handler has determined that this objfile is not ++ available. ++ A string: GDB should load the file at the given path; it ++ contains the requested objfile. ++ None: This handler can't help with this objfile. GDB ++ should try any other registered handlers. ++ ++ """ ++ raise NotImplementedError("MissingObjfileHandler.__call__()") ++ ++ ++def register_handler(locus, handler, replace=False): ++ """See gdb.missing_files.register_handler.""" ++ gdb.missing_files.register_handler("objfile", locus, handler, replace) +diff --git a/gdb/python/py-progspace.c b/gdb/python/py-progspace.c +--- a/gdb/python/py-progspace.c ++++ b/gdb/python/py-progspace.c +@@ -55,8 +55,8 @@ struct pspace_object + /* The debug method list. */ + PyObject *xmethods; + +- /* The missing debug handler list. */ +- PyObject *missing_debug_handlers; ++ /* The missing file handler list. */ ++ PyObject *missing_file_handlers; + }; + + extern PyTypeObject pspace_object_type +@@ -166,7 +166,7 @@ pspy_dealloc (PyObject *self) + Py_XDECREF (ps_self->frame_unwinders); + Py_XDECREF (ps_self->type_printers); + Py_XDECREF (ps_self->xmethods); +- Py_XDECREF (ps_self->missing_debug_handlers); ++ Py_XDECREF (ps_self->missing_file_handlers); + Py_TYPE (self)->tp_free (self); + } + +@@ -202,8 +202,8 @@ pspy_initialize (pspace_object *self) + if (self->xmethods == NULL) + return 0; + +- self->missing_debug_handlers = PyList_New (0); +- if (self->missing_debug_handlers == nullptr) ++ self->missing_file_handlers = PyList_New (0); ++ if (self->missing_file_handlers == nullptr) + return 0; + + return 1; +@@ -349,18 +349,18 @@ pspy_get_xmethods (PyObject *o, void *ignore) + /* Return the list of missing debug handlers for this program space. */ + + static PyObject * +-pspy_get_missing_debug_handlers (PyObject *o, void *ignore) ++pspy_get_missing_file_handlers (PyObject *o, void *ignore) + { + pspace_object *self = (pspace_object *) o; + +- Py_INCREF (self->missing_debug_handlers); +- return self->missing_debug_handlers; ++ Py_INCREF (self->missing_file_handlers); ++ return self->missing_file_handlers; + } + + /* Set this program space's list of missing debug handlers to HANDLERS. */ + + static int +-pspy_set_missing_debug_handlers (PyObject *o, PyObject *handlers, ++pspy_set_missing_file_handlers (PyObject *o, PyObject *handlers, + void *ignore) + { + pspace_object *self = (pspace_object *) o; +@@ -380,9 +380,9 @@ pspy_set_missing_debug_handlers (PyObject *o, PyObject *handlers, + } + + /* Take care in case the LHS and RHS are related somehow. */ +- gdbpy_ref<> tmp (self->missing_debug_handlers); ++ gdbpy_ref<> tmp (self->missing_file_handlers); + Py_INCREF (handlers); +- self->missing_debug_handlers = handlers; ++ self->missing_file_handlers = handlers; + + return 0; + } +@@ -779,8 +779,8 @@ static gdb_PyGetSetDef pspace_getset[] = + "Type printers.", NULL }, + { "xmethods", pspy_get_xmethods, NULL, + "Debug methods.", NULL }, +- { "missing_debug_handlers", pspy_get_missing_debug_handlers, +- pspy_set_missing_debug_handlers, "Missing debug handlers.", NULL }, ++ { "missing_file_handlers", pspy_get_missing_file_handlers, ++ pspy_set_missing_file_handlers, "Missing file handlers.", NULL }, + { NULL } + }; + +diff --git a/gdb/python/python.c b/gdb/python/python.c +--- a/gdb/python/python.c ++++ b/gdb/python/python.c +@@ -35,6 +35,7 @@ + #include "location.h" + #include "run-on-main-thread.h" + #include "observable.h" ++#include "build-id.h" + + #if GDB_SELF_TEST + #include "gdbsupport/selftest.h" +@@ -128,8 +129,11 @@ static std::optional gdbpy_colorize + (const std::string &filename, const std::string &contents); + static std::optional gdbpy_colorize_disasm + (const std::string &content, gdbarch *gdbarch); +-static ext_lang_missing_debuginfo_result gdbpy_handle_missing_debuginfo ++static ext_lang_missing_file_result gdbpy_handle_missing_debuginfo + (const struct extension_language_defn *extlang, struct objfile *objfile); ++static ext_lang_missing_file_result gdbpy_find_objfile_from_buildid ++ (const struct extension_language_defn *extlang, program_space *pspace, ++ const struct bfd_build_id *build_id, const char *missing_filename); + + /* The interface between gdb proper and loading of python scripts. */ + +@@ -177,7 +181,8 @@ static const struct extension_language_ops python_extension_ops = + + gdbpy_print_insn, + +- gdbpy_handle_missing_debuginfo ++ gdbpy_handle_missing_debuginfo, ++ gdbpy_find_objfile_from_buildid + }; + + #endif /* HAVE_PYTHON */ +@@ -1761,10 +1766,10 @@ gdbpy_get_current_objfile (PyObject *unused1, PyObject *unused2) + /* Implement the 'handle_missing_debuginfo' hook for Python. GDB has + failed to find any debug information for OBJFILE. The extension has a + chance to record this, or even install the required debug information. +- See the description of ext_lang_missing_debuginfo_result in +- extension-priv.h for details of the return value. */ ++ See the description of ext_lang_missing_file_result in extension-priv.h ++ for details of the return value. */ + +-static ext_lang_missing_debuginfo_result ++static ext_lang_missing_file_result + gdbpy_handle_missing_debuginfo (const struct extension_language_defn *extlang, + struct objfile *objfile) + { +@@ -1812,7 +1817,7 @@ gdbpy_handle_missing_debuginfo (const struct extension_language_defn *extlang, + if (PyBool_Check (pyo_execute_ret.get ())) + { + bool try_again = PyObject_IsTrue (pyo_execute_ret.get ()); +- return ext_lang_missing_debuginfo_result (try_again); ++ return ext_lang_missing_file_result (try_again); + } + + if (!gdbpy_is_string (pyo_execute_ret.get ())) +@@ -1832,7 +1837,108 @@ gdbpy_handle_missing_debuginfo (const struct extension_language_defn *extlang, + return {}; + } + +- return ext_lang_missing_debuginfo_result (std::string (filename.get ())); ++ return ext_lang_missing_file_result (std::string (filename.get ())); ++} ++ ++/* Implement the find_objfile_from_buildid hook for Python. PSPACE is the ++ program space in which GDB is trying to find an objfile, BUILD_ID is the ++ build-id for the missing objfile, and EXPECTED_FILENAME is a non-NULL ++ string which can be used (if needed) in messages to the user, and ++ represents the file GDB is looking for. */ ++ ++static ext_lang_missing_file_result ++gdbpy_find_objfile_from_buildid (const struct extension_language_defn *extlang, ++ program_space *pspace, ++ const struct bfd_build_id *build_id, ++ const char *missing_filename) ++{ ++ gdb_assert (pspace != nullptr); ++ gdb_assert (build_id != nullptr); ++ gdb_assert (missing_filename != nullptr); ++ ++ /* Early exit if Python is not initialised. */ ++ if (!gdb_python_initialized || gdb_python_module == nullptr) ++ return {}; ++ ++ gdbpy_enter enter_py; ++ ++ /* Convert BUILD_ID into a Python object. */ ++ std::string hex_form = bin2hex (build_id->data, build_id->size); ++ gdbpy_ref<> pyo_buildid = host_string_to_python_string (hex_form.c_str ()); ++ if (pyo_buildid == nullptr) ++ { ++ gdbpy_print_stack (); ++ return {}; ++ } ++ ++ /* Convert MISSING_FILENAME to a Python object. */ ++ gdbpy_ref<> pyo_filename = host_string_to_python_string (missing_filename); ++ if (pyo_filename == nullptr) ++ { ++ gdbpy_print_stack (); ++ return {}; ++ } ++ ++ /* Convert PSPACE to a Python object. */ ++ gdbpy_ref<> pyo_pspace = pspace_to_pspace_object (pspace); ++ if (pyo_pspace == nullptr) ++ { ++ gdbpy_print_stack (); ++ return {}; ++ } ++ ++ /* Lookup the helper function within the GDB module. */ ++ gdbpy_ref<> pyo_handler ++ (PyObject_GetAttrString (gdb_python_module, "_handle_missing_objfile")); ++ if (pyo_handler == nullptr) ++ { ++ gdbpy_print_stack (); ++ return {}; ++ } ++ ++ /* Call the function, passing in the Python objfile object. */ ++ gdbpy_ref<> pyo_execute_ret ++ (PyObject_CallFunctionObjArgs (pyo_handler.get (), pyo_pspace.get (), ++ pyo_buildid.get (), pyo_filename.get (), ++ nullptr)); ++ if (pyo_execute_ret == nullptr) ++ { ++ /* If the handler is cancelled due to a Ctrl-C, then propagate ++ the Ctrl-C as a GDB exception instead of swallowing it. */ ++ gdbpy_print_stack_or_quit (); ++ return {}; ++ } ++ ++ /* Parse the result, and convert it back to the C++ object. */ ++ if (pyo_execute_ret == Py_None) ++ return {}; ++ ++ if (PyBool_Check (pyo_execute_ret.get ())) ++ { ++ /* We know the value is a bool, so it must be either Py_True or ++ Py_False. Anything else would not get past the above check. */ ++ bool try_again = pyo_execute_ret.get () == Py_True; ++ return ext_lang_missing_file_result (try_again); ++ } ++ ++ if (!gdbpy_is_string (pyo_execute_ret.get ())) ++ { ++ PyErr_SetString (PyExc_ValueError, ++ "return value from _find_objfile_by_buildid should " ++ "be None, a bool, or a str"); ++ gdbpy_print_stack (); ++ return {}; ++ } ++ ++ gdb::unique_xmalloc_ptr filename ++ = python_string_to_host_string (pyo_execute_ret.get ()); ++ if (filename == nullptr) ++ { ++ gdbpy_print_stack (); ++ return {}; ++ } ++ ++ return ext_lang_missing_file_result (std::string (filename.get ())); + } + + /* Compute the list of active python type printers and store them in +diff --git a/gdb/remote.c b/gdb/remote.c +--- a/gdb/remote.c ++++ b/gdb/remote.c +@@ -246,6 +246,7 @@ enum { + PACKET_vFile_unlink, + PACKET_vFile_readlink, + PACKET_vFile_fstat, ++ PACKET_vFile_stat, + PACKET_qXfer_auxv, + PACKET_qXfer_features, + PACKET_qXfer_exec_file, +@@ -996,6 +997,9 @@ class remote_target : public process_stratum_target + + int fileio_fstat (int fd, struct stat *sb, fileio_error *target_errno) override; + ++ int fileio_stat (struct inferior *inf, const char *filename, ++ struct stat *sb, fileio_error *target_errno) override; ++ + int fileio_close (int fd, fileio_error *target_errno) override; + + int fileio_unlink (struct inferior *inf, +@@ -12661,6 +12665,9 @@ remote_target::remote_hostio_send_command (int command_bytes, int which_packet, + return -1; + } + ++ if (*remote_errno != FILEIO_SUCCESS) ++ return -1; ++ + /* Make sure we saw an attachment if and only if we expected one. */ + if ((attachment_tmp == NULL && attachment != NULL) + || (attachment_tmp != NULL && attachment == NULL)) +@@ -13027,6 +13034,41 @@ remote_target::fileio_readlink (struct inferior *inf, const char *filename, + return ret; + } + ++/* Helper function to handle ::fileio_fstat and ::fileio_stat result ++ processing. When this function is called the remote syscall has been ++ performed and we know we didn't get an error back. ++ ++ ATTACHMENT and ATTACHMENT_LEN are the attachment data extracted from the ++ remote syscall reply. EXPECTED_LEN is the length returned from the ++ fstat or stat call, this the length of the returned data (in ATTACHMENT) ++ once it has been decoded. The fstat/stat result (from the ATTACHMENT ++ data) is to be placed in ST. */ ++ ++static int ++fileio_process_fstat_and_stat_reply (const char *attachment, ++ int attachment_len, ++ int expected_len, ++ struct stat *st) ++{ ++ struct fio_stat fst; ++ ++ int read_len ++ = remote_unescape_input ((gdb_byte *) attachment, attachment_len, ++ (gdb_byte *) &fst, sizeof (fst)); ++ ++ if (read_len != expected_len) ++ error (_("vFile:fstat returned %d, but %d bytes."), ++ expected_len, read_len); ++ ++ if (read_len != sizeof (fst)) ++ error (_("vFile:fstat returned %d bytes, but expecting %d."), ++ read_len, (int) sizeof (fst)); ++ ++ remote_fileio_to_host_stat (&fst, st); ++ ++ return 0; ++} ++ + /* Implementation of to_fileio_fstat. */ + + int +@@ -13037,8 +13079,6 @@ remote_target::fileio_fstat (int fd, struct stat *st, fileio_error *remote_errno + int left = get_remote_packet_size (); + int attachment_len, ret; + const char *attachment; +- struct fio_stat fst; +- int read_len; + + remote_buffer_add_string (&p, &left, "vFile:fstat:"); + +@@ -13070,19 +13110,41 @@ remote_target::fileio_fstat (int fd, struct stat *st, fileio_error *remote_errno + return 0; + } + +- read_len = remote_unescape_input ((gdb_byte *) attachment, attachment_len, +- (gdb_byte *) &fst, sizeof (fst)); ++ return fileio_process_fstat_and_stat_reply (attachment, attachment_len, ++ ret, st); ++} + +- if (read_len != ret) +- error (_("vFile:fstat returned %d, but %d bytes."), ret, read_len); ++/* Implementation of to_fileio_stat. */ + +- if (read_len != sizeof (fst)) +- error (_("vFile:fstat returned %d bytes, but expecting %d."), +- read_len, (int) sizeof (fst)); ++int ++remote_target::fileio_stat (struct inferior *inf, const char *filename, ++ struct stat *st, fileio_error *remote_errno) ++{ ++ struct remote_state *rs = get_remote_state (); ++ char *p = rs->buf.data (); ++ int left = get_remote_packet_size () - 1; + +- remote_fileio_to_host_stat (&fst, st); ++ if (remote_hostio_set_filesystem (inf, remote_errno) != 0) ++ return {}; + +- return 0; ++ remote_buffer_add_string (&p, &left, "vFile:stat:"); ++ ++ remote_buffer_add_bytes (&p, &left, (const gdb_byte *) filename, ++ strlen (filename)); ++ ++ int attachment_len; ++ const char *attachment; ++ int ret = remote_hostio_send_command (p - rs->buf.data (), PACKET_vFile_stat, ++ remote_errno, &attachment, ++ &attachment_len); ++ ++ /* Unlike ::fileio_fstat, the stat fileio call was added later on, and ++ has none of the legacy bfd issues, so we can just return the error. */ ++ if (ret < 0) ++ return ret; ++ ++ return fileio_process_fstat_and_stat_reply (attachment, attachment_len, ++ ret, st); + } + + /* Implementation of to_filesystem_is_local. */ +@@ -16157,6 +16219,8 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL, + + add_packet_config_cmd (PACKET_vFile_fstat, "vFile:fstat", "hostio-fstat", 0); + ++ add_packet_config_cmd (PACKET_vFile_stat, "vFile:stat", "hostio-stat", 0); ++ + add_packet_config_cmd (PACKET_vAttach, "vAttach", "attach", 0); + + add_packet_config_cmd (PACKET_vRun, "vRun", "run", 0); +diff --git a/gdb/solib-aix.c b/gdb/solib-aix.c +--- a/gdb/solib-aix.c ++++ b/gdb/solib-aix.c +@@ -689,6 +689,11 @@ const solib_ops solib_aix_so_ops = + solib_aix_open_symbol_file_object, + solib_aix_in_dynsym_resolve_code, + solib_aix_bfd_open, ++ nullptr, ++ nullptr, ++ nullptr, ++ nullptr, ++ default_find_solib_addr, + }; + + void _initialize_solib_aix (); +diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c +--- a/gdb/solib-darwin.c ++++ b/gdb/solib-darwin.c +@@ -665,4 +665,9 @@ const solib_ops darwin_so_ops = + open_symbol_file_object, + darwin_in_dynsym_resolve_code, + darwin_bfd_open, ++ nullptr, ++ nullptr, ++ nullptr, ++ nullptr, ++ default_find_solib_addr, + }; +diff --git a/gdb/solib-dsbt.c b/gdb/solib-dsbt.c +--- a/gdb/solib-dsbt.c ++++ b/gdb/solib-dsbt.c +@@ -914,6 +914,11 @@ const solib_ops dsbt_so_ops = + open_symbol_file_object, + dsbt_in_dynsym_resolve_code, + solib_bfd_open, ++ nullptr, ++ nullptr, ++ nullptr, ++ nullptr, ++ default_find_solib_addr, + }; + + void _initialize_dsbt_solib (); +diff --git a/gdb/solib-frv.c b/gdb/solib-frv.c +--- a/gdb/solib-frv.c ++++ b/gdb/solib-frv.c +@@ -1086,4 +1086,9 @@ const solib_ops frv_so_ops = + open_symbol_file_object, + frv_in_dynsym_resolve_code, + solib_bfd_open, ++ nullptr, ++ nullptr, ++ nullptr, ++ nullptr, ++ default_find_solib_addr, + }; +diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c +--- a/gdb/solib-svr4.c ++++ b/gdb/solib-svr4.c +@@ -3353,6 +3353,15 @@ svr4_iterate_over_objfiles_in_search_order + } + } + ++/* See solib_ops::find_solib_addr in solist.h. */ ++ ++static std::optional ++svr4_find_solib_addr (solib &so) ++{ ++ auto *li = gdb::checked_static_cast (so.lm_info.get ()); ++ return li->l_addr_inferior; ++} ++ + const struct solib_ops svr4_so_ops = + { + svr4_relocate_section_addresses, +@@ -3363,11 +3372,11 @@ const struct solib_ops svr4_so_ops = + open_symbol_file_object, + svr4_in_dynsym_resolve_code, + solib_bfd_open, +- nullptr, + svr4_same, + svr4_keep_data_in_core, + svr4_update_solib_event_breakpoints, + svr4_handle_solib_event, ++ svr4_find_solib_addr, + }; + + void _initialize_svr4_solib (); +diff --git a/gdb/solib-target.c b/gdb/solib-target.c +--- a/gdb/solib-target.c ++++ b/gdb/solib-target.c +@@ -412,4 +412,9 @@ const solib_ops solib_target_so_ops = + solib_target_open_symbol_file_object, + solib_target_in_dynsym_resolve_code, + solib_bfd_open, ++ nullptr, ++ nullptr, ++ nullptr, ++ nullptr, ++ default_find_solib_addr, + }; +diff --git a/gdb/solib.c b/gdb/solib.c +--- a/gdb/solib.c ++++ b/gdb/solib.c +@@ -45,7 +45,6 @@ + #include "gdb_bfd.h" + #include "gdbsupport/filestuff.h" + #include "gdbsupport/scoped_fd.h" +-#include "debuginfod-support.h" + #include "source.h" + #include "cli/cli-style.h" + +@@ -113,7 +112,6 @@ show_solib_search_path (struct ui_file *file, int from_tty, + static gdb::unique_xmalloc_ptr + solib_find_1 (const char *in_pathname, int *fd, bool is_solib) + { +- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ()); + int found_file = -1; + gdb::unique_xmalloc_ptr temp_pathname; + const char *fskind = effective_target_file_system_kind (); +@@ -296,12 +294,6 @@ solib_find_1 (const char *in_pathname, int *fd, bool is_solib) + target_lbasename (fskind, in_pathname), + O_RDONLY | O_BINARY, &temp_pathname); + +- /* If not found, and we're looking for a solib, try to use target +- supplied solib search method. */ +- if (is_solib && found_file < 0 && ops->find_and_open_solib) +- found_file = ops->find_and_open_solib (in_pathname, O_RDONLY | O_BINARY, +- &temp_pathname); +- + /* If not found, next search the inferior's $PATH environment variable. */ + if (found_file < 0 && sysroot == NULL) + found_file = openp (current_inferior ()->environment.get ("PATH"), +@@ -475,58 +467,6 @@ solib_bfd_open (const char *pathname) + return abfd; + } + +-/* Mapping of a core file's shared library sonames to their respective +- build-ids. Added to the registries of core file bfds. */ +- +-typedef std::unordered_map soname_build_id_map; +- +-/* Key used to associate a soname_build_id_map to a core file bfd. */ +- +-static const struct registry::key +- cbfd_soname_build_id_data_key; +- +-/* See solib.h. */ +- +-void +-set_cbfd_soname_build_id (gdb_bfd_ref_ptr abfd, const char *soname, +- const bfd_build_id *build_id) +-{ +- gdb_assert (abfd.get () != nullptr); +- gdb_assert (soname != nullptr); +- gdb_assert (build_id != nullptr); +- +- soname_build_id_map *mapptr +- = cbfd_soname_build_id_data_key.get (abfd.get ()); +- +- if (mapptr == nullptr) +- mapptr = cbfd_soname_build_id_data_key.emplace (abfd.get ()); +- +- (*mapptr)[soname] = build_id_to_string (build_id); +-} +- +-/* If SONAME had a build-id associated with it in ABFD's registry by a +- previous call to set_cbfd_soname_build_id then return the build-id +- as a NULL-terminated hex string. */ +- +-static gdb::unique_xmalloc_ptr +-get_cbfd_soname_build_id (gdb_bfd_ref_ptr abfd, const char *soname) +-{ +- if (abfd.get () == nullptr || soname == nullptr) +- return {}; +- +- soname_build_id_map *mapptr +- = cbfd_soname_build_id_data_key.get (abfd.get ()); +- +- if (mapptr == nullptr) +- return {}; +- +- auto it = mapptr->find (lbasename (soname)); +- if (it == mapptr->end ()) +- return {}; +- +- return make_unique_xstrdup (it->second.c_str ()); +-} +- + /* Given a pointer to one of the shared objects in our list of mapped + objects, use the recorded name to open a bfd descriptor for the + object, build a section table, relocate all the section addresses +@@ -546,36 +486,55 @@ solib_map_sections (solib &so) + + gdb::unique_xmalloc_ptr filename (tilde_expand (so.so_name.c_str ())); + gdb_bfd_ref_ptr abfd (ops->bfd_open (filename.get ())); +- gdb::unique_xmalloc_ptr build_id_hexstr +- = get_cbfd_soname_build_id (current_program_space->cbfd, +- so.so_name.c_str ()); ++ ++ /* If we have a core target then the core target might have some helpful ++ information (i.e. build-ids) about the shared libraries we are trying ++ to load. Grab those hints now and use the below to validate or find ++ the shared libraries. ++ ++ If we don't have a core target then this will return an empty struct ++ with no hint information, we then lookup the shared library based on ++ its filename. */ ++ std::optional solib_addr = ops->find_solib_addr (so); ++ std::optional mapped_file_info ++ = core_target_find_mapped_file (so.so_name.c_str (), solib_addr); + + /* If we already know the build-id of this solib from a core file, verify + it matches ABFD's build-id. If there is a mismatch or the solib wasn't + found, attempt to query debuginfod for the correct solib. */ +- if (build_id_hexstr.get () != nullptr) ++ if (mapped_file_info.has_value ()) + { +- bool mismatch = false; ++ bool mismatch = (abfd != nullptr ++ && build_id_bfd_get (abfd.get ()) != nullptr ++ && !build_id_equal (mapped_file_info->build_id (), ++ build_id_bfd_get (abfd.get ()))); + +- if (abfd != nullptr && abfd->build_id != nullptr) +- { +- std::string build_id = build_id_to_string (abfd->build_id); +- +- if (build_id != build_id_hexstr.get ()) +- mismatch = true; +- } + if (abfd == nullptr || mismatch) + { +- scoped_fd fd = debuginfod_exec_query ( +- (const unsigned char *) build_id_hexstr.get (), 0, +- so.so_name.c_str (), &filename); +- +- if (fd.get () >= 0) +- abfd = ops->bfd_open (filename.get ()); +- else if (mismatch) +- warning (_ ("Build-id of %ps does not match core file."), +- styled_string (file_name_style.style (), +- filename.get ())); ++ /* If GDB found a suitable file during the file mapping ++ processing stage then lets use that. We don't check the ++ build-id after opening this file, either this file was found ++ by build-id, in which case it's going to match, or this file ++ doesn't have a build-id, so checking tells us nothing. ++ However, if it was good enough during the mapped file ++ processing, we assume it's good enough now. */ ++ if (!mapped_file_info->filename ().empty ()) ++ abfd = ops->bfd_open (mapped_file_info->filename ().c_str ()); ++ else ++ abfd = nullptr; ++ ++ if (abfd == nullptr) ++ abfd = find_objfile_by_build_id (current_program_space, ++ mapped_file_info->build_id (), ++ so.so_name.c_str ()); ++ ++ if (abfd == nullptr && mismatch) ++ { ++ warning (_ ("Build-id of %ps does not match core file."), ++ styled_string (file_name_style.style (), ++ filename.get ())); ++ abfd = nullptr; ++ } + } + } + +@@ -1705,6 +1664,14 @@ remove_user_added_objfile (struct objfile *objfile) + } + } + ++/* See solist.h. */ ++ ++std::optional ++default_find_solib_addr (solib &so) ++{ ++ return {}; ++} ++ + void _initialize_solib (); + + void +diff --git a/gdb/solib.h b/gdb/solib.h +--- a/gdb/solib.h ++++ b/gdb/solib.h +@@ -136,11 +136,4 @@ extern void update_solib_breakpoints (void); + + extern void handle_solib_event (void); + +-/* Associate SONAME with BUILD_ID in ABFD's registry so that it can be +- retrieved with get_cbfd_soname_build_id. */ +- +-extern void set_cbfd_soname_build_id (gdb_bfd_ref_ptr abfd, +- const char *soname, +- const bfd_build_id *build_id); +- + #endif /* SOLIB_H */ +diff --git a/gdb/solist.h b/gdb/solist.h +--- a/gdb/solist.h ++++ b/gdb/solist.h +@@ -132,14 +132,6 @@ struct solib_ops + /* Find and open shared library binary file. */ + gdb_bfd_ref_ptr (*bfd_open) (const char *pathname); + +- /* Optional extra hook for finding and opening a solib. +- If TEMP_PATHNAME is non-NULL: If the file is successfully opened a +- pointer to a malloc'd and realpath'd copy of SONAME is stored there, +- otherwise NULL is stored there. */ +- int (*find_and_open_solib) (const char *soname, +- unsigned o_flags, +- gdb::unique_xmalloc_ptr *temp_pathname); +- + /* Given two so_list objects, one from the GDB thread list + and another from the list returned by current_sos, return 1 + if they represent the same library. +@@ -167,6 +159,23 @@ struct solib_ops + NULL, in which case no specific preprocessing is necessary + for this target. */ + void (*handle_event) (void); ++ ++ /* Return an address within the inferior's address space which is known ++ to be part of SO. If there is no such address, or GDB doesn't know ++ how to figure out such an address then an empty optional is ++ returned. ++ ++ The returned address can be used when loading the shared libraries ++ for a core file. GDB knows the build-ids for (some) files mapped ++ into the inferior's address space, and knows the address ranges which ++ those mapped files cover. If GDB can figure out a representative ++ address for the library then this can be used to match a library to a ++ mapped file, and thus to a build-id. GDB can then use this ++ information to help locate the shared library objfile, if the objfile ++ is not in the expected place (as defined by the shared libraries file ++ name). */ ++ ++ std::optional (*find_solib_addr) (solib &so); + }; + + /* A unique pointer to a so_list. */ +@@ -186,4 +195,9 @@ extern gdb_bfd_ref_ptr solib_bfd_fopen (const char *pathname, int fd); + /* Find solib binary file and open it. */ + extern gdb_bfd_ref_ptr solib_bfd_open (const char *in_pathname); + ++/* A default implementation of the solib_ops::find_solib_addr callback. ++ This just returns an empty std::optional indicating GDB is ++ unable to find an address within the library SO. */ ++extern std::optional default_find_solib_addr (solib &so); ++ + #endif +diff --git a/gdb/symfile-debug.c b/gdb/symfile-debug.c +--- a/gdb/symfile-debug.c ++++ b/gdb/symfile-debug.c +@@ -637,7 +637,7 @@ objfile::find_and_add_separate_symbol_file (symfile_add_flags symfile_flags) + the user a system specific message that guides them to finding + the missing debug info. */ + +- ext_lang_missing_debuginfo_result ext_result ++ ext_lang_missing_file_result ext_result + = ext_lang_handle_missing_debuginfo (this); + if (!ext_result.filename ().empty ()) + { +diff --git a/gdb/symfile.c b/gdb/symfile.c +--- a/gdb/symfile.c ++++ b/gdb/symfile.c +@@ -1237,6 +1237,8 @@ separate_debug_file_exists (const std::string &name, unsigned long crc, + struct objfile *parent_objfile, + deferred_warnings *warnings) + { ++ SEPARATE_DEBUG_FILE_SCOPED_DEBUG_ENTER_EXIT; ++ + unsigned long file_crc; + int file_crc_p; + struct stat parent_stat, abfd_stat; +@@ -1251,19 +1253,13 @@ separate_debug_file_exists (const std::string &name, unsigned long crc, + if (filename_cmp (name.c_str (), objfile_name (parent_objfile)) == 0) + return 0; + +- if (separate_debug_file_debug) +- { +- gdb_printf (gdb_stdlog, _(" Trying %s..."), name.c_str ()); +- gdb_flush (gdb_stdlog); +- } ++ separate_debug_file_debug_printf ("Trying %s...", name.c_str ()); + + gdb_bfd_ref_ptr abfd (gdb_bfd_open (name.c_str (), gnutarget)); + + if (abfd == NULL) + { +- if (separate_debug_file_debug) +- gdb_printf (gdb_stdlog, _(" no, unable to open.\n")); +- ++ separate_debug_file_debug_printf ("unable to open file"); + return 0; + } + +@@ -1285,10 +1281,7 @@ separate_debug_file_exists (const std::string &name, unsigned long crc, + if (abfd_stat.st_dev == parent_stat.st_dev + && abfd_stat.st_ino == parent_stat.st_ino) + { +- if (separate_debug_file_debug) +- gdb_printf (gdb_stdlog, +- _(" no, same file as the objfile.\n")); +- ++ separate_debug_file_debug_printf ("same file as the objfile"); + return 0; + } + verified_as_different = 1; +@@ -1300,9 +1293,7 @@ separate_debug_file_exists (const std::string &name, unsigned long crc, + + if (!file_crc_p) + { +- if (separate_debug_file_debug) +- gdb_printf (gdb_stdlog, _(" no, error computing CRC.\n")); +- ++ separate_debug_file_debug_printf ("error computing CRC"); + return 0; + } + +@@ -1318,20 +1309,18 @@ separate_debug_file_exists (const std::string &name, unsigned long crc, + { + if (!gdb_bfd_crc (parent_objfile->obfd.get (), &parent_crc)) + { +- if (separate_debug_file_debug) +- gdb_printf (gdb_stdlog, +- _(" no, error computing CRC.\n")); +- ++ separate_debug_file_debug_printf ("error computing CRC"); + return 0; + } + } + + if (verified_as_different || parent_crc != file_crc) + { +- if (separate_debug_file_debug) +- gdb_printf (gdb_stdlog, "the debug information found in \"%s\"" +- " does not match \"%s\" (CRC mismatch).\n", +- name.c_str (), objfile_name (parent_objfile)); ++ separate_debug_file_debug_printf ++ ("the debug information found in \"%s\" does not match " ++ "\"%s\" (CRC mismatch).", name.c_str (), ++ objfile_name (parent_objfile)); ++ + warnings->warn (_("the debug information found in \"%ps\"" + " does not match \"%ps\" (CRC mismatch)."), + styled_string (file_name_style.style (), +@@ -1343,8 +1332,7 @@ separate_debug_file_exists (const std::string &name, unsigned long crc, + return 0; + } + +- if (separate_debug_file_debug) +- gdb_printf (gdb_stdlog, _(" yes!\n")); ++ separate_debug_file_debug_printf ("found a match"); + + return 1; + } +@@ -1385,23 +1373,18 @@ find_separate_debug_file (const char *dir, + unsigned long crc32, struct objfile *objfile, + deferred_warnings *warnings) + { +- if (separate_debug_file_debug) +- gdb_printf (gdb_stdlog, +- _("\nLooking for separate debug info (debug link) for " +- "%s\n"), objfile_name (objfile)); ++ SEPARATE_DEBUG_FILE_SCOPED_DEBUG_START_END ++ ("looking for separate debug info (debug link) for %s", ++ objfile_name (objfile)); + + /* First try in the same directory as the original file. */ +- std::string debugfile = dir; +- debugfile += debuglink; ++ std::string debugfile = path_join (dir, debuglink); + + if (separate_debug_file_exists (debugfile, crc32, objfile, warnings)) + return debugfile; + + /* Then try in the subdirectory named DEBUG_SUBDIRECTORY. */ +- debugfile = dir; +- debugfile += DEBUG_SUBDIRECTORY; +- debugfile += "/"; +- debugfile += debuglink; ++ debugfile = path_join (dir, DEBUG_SUBDIRECTORY, debuglink); + + if (separate_debug_file_exists (debugfile, crc32, objfile, warnings)) + return debugfile; +@@ -1414,10 +1397,13 @@ find_separate_debug_file (const char *dir, + bool target_prefix = is_target_filename (dir); + const char *dir_notarget + = target_prefix ? dir + strlen (TARGET_SYSROOT_PREFIX) : dir; ++ const char *target_prefix_str = target_prefix ? TARGET_SYSROOT_PREFIX : ""; + std::vector> debugdir_vec + = dirnames_to_char_ptr_vec (debug_file_directory.c_str ()); +- gdb::unique_xmalloc_ptr canon_sysroot +- = gdb_realpath (gdb_sysroot.c_str ()); ++ const char *sysroot_str = gdb_sysroot.c_str (); ++ if (is_target_filename (sysroot_str) && target_filesystem_is_local ()) ++ sysroot_str += strlen (TARGET_SYSROOT_PREFIX); ++ gdb::unique_xmalloc_ptr canon_sysroot = gdb_realpath (sysroot_str); + + /* MS-Windows/MS-DOS don't allow colons in file names; we must + convert the drive letter into a one-letter directory, so that the +@@ -1442,12 +1428,8 @@ find_separate_debug_file (const char *dir, + + for (const gdb::unique_xmalloc_ptr &debugdir : debugdir_vec) + { +- debugfile = target_prefix ? TARGET_SYSROOT_PREFIX : ""; +- debugfile += debugdir; +- debugfile += "/"; +- debugfile += drive; +- debugfile += dir_notarget; +- debugfile += debuglink; ++ debugfile = path_join (target_prefix_str, debugdir.get (), ++ drive.c_str (), dir_notarget, debuglink); + + if (separate_debug_file_exists (debugfile, crc32, objfile, warnings)) + return debugfile; +@@ -1464,39 +1446,18 @@ find_separate_debug_file (const char *dir, + { + /* If the file is in the sysroot, try using its base path in + the global debugfile directory. */ +- debugfile = target_prefix ? TARGET_SYSROOT_PREFIX : ""; +- debugfile += debugdir; +- debugfile += "/"; +- debugfile += base_path; +- debugfile += "/"; +- debugfile += debuglink; ++ debugfile = path_join (target_prefix_str, debugdir.get (), ++ base_path, debuglink); + + if (separate_debug_file_exists (debugfile, crc32, objfile, warnings)) + return debugfile; + + /* If the file is in the sysroot, try using its base path in +- the sysroot's global debugfile directory. GDB_SYSROOT +- might refer to a target: path; we strip the "target:" +- prefix -- but if that would yield the empty string, we +- don't bother at all, because that would just give the +- same result as above. */ ++ the sysroot's global debugfile directory. */ + if (gdb_sysroot != TARGET_SYSROOT_PREFIX) + { +- debugfile = target_prefix ? TARGET_SYSROOT_PREFIX : ""; +- if (is_target_filename (gdb_sysroot)) +- { +- std::string root +- = gdb_sysroot.substr (strlen (TARGET_SYSROOT_PREFIX)); +- gdb_assert (!root.empty ()); +- debugfile += root; +- } +- else +- debugfile += gdb_sysroot; +- debugfile += debugdir; +- debugfile += "/"; +- debugfile += base_path; +- debugfile += "/"; +- debugfile += debuglink; ++ debugfile = path_join (gdb_sysroot.c_str (), debugdir.get (), ++ base_path, debuglink); + + if (separate_debug_file_exists (debugfile, crc32, objfile, + warnings)) +diff --git a/gdb/symfile.h b/gdb/symfile.h +--- a/gdb/symfile.h ++++ b/gdb/symfile.h +@@ -371,6 +371,25 @@ extern gdb_bfd_ref_ptr find_separate_debug_file_in_section (struct objfile *); + + extern bool separate_debug_file_debug; + ++/* Print a "separate-debug-file" debug statement. */ ++ ++#define separate_debug_file_debug_printf(fmt, ...) \ ++ debug_prefixed_printf_cond (separate_debug_file_debug, \ ++ "separate-debug-file", \ ++ fmt, ##__VA_ARGS__) ++ ++/* Print "separate-debug-file" enter/exit debug statements. */ ++ ++#define SEPARATE_DEBUG_FILE_SCOPED_DEBUG_ENTER_EXIT \ ++ scoped_debug_enter_exit (separate_debug_file_debug, \ ++ "separate-debug-file") ++ ++/* Print "separate-debug-file" start/end debug statements. */ ++ ++#define SEPARATE_DEBUG_FILE_SCOPED_DEBUG_START_END(fmt, ...) \ ++ scoped_debug_start_end (separate_debug_file_debug, \ ++ "separate-debug-file", fmt, ##__VA_ARGS__) ++ + /* Read full symbols immediately. */ + + extern int readnow_symbol_files; +diff --git a/gdb/target.c b/gdb/target.c +--- a/gdb/target.c ++++ b/gdb/target.c +@@ -3196,6 +3196,14 @@ target_ops::fileio_fstat (int fd, struct stat *sb, fileio_error *target_errno) + return -1; + } + ++int ++target_ops::fileio_stat (struct inferior *inf, const char *filename, ++ struct stat *sb, fileio_error *target_errno) ++{ ++ *target_errno = FILEIO_ENOSYS; ++ return -1; ++} ++ + int + target_ops::fileio_close (int fd, fileio_error *target_errno) + { +@@ -3315,6 +3323,29 @@ target_fileio_fstat (int fd, struct stat *sb, fileio_error *target_errno) + + /* See target.h. */ + ++int ++target_fileio_stat (struct inferior *inf, const char *filename, ++ struct stat *sb, fileio_error *target_errno) ++{ ++ for (target_ops *t = default_fileio_target (); t != NULL; t = t->beneath ()) ++ { ++ int ret = t->fileio_stat (inf, filename, sb, target_errno); ++ ++ if (ret == -1 && *target_errno == FILEIO_ENOSYS) ++ continue; ++ ++ target_debug_printf_nofunc ("target_fileio_stat (%s) = %d (%d)", ++ filename, ret, ++ ret != -1 ? 0 : *target_errno); ++ return ret; ++ } ++ ++ *target_errno = FILEIO_ENOSYS; ++ return -1; ++} ++ ++/* See target.h. */ ++ + int + target_fileio_close (int fd, fileio_error *target_errno) + { +diff --git a/gdb/target.h b/gdb/target.h +--- a/gdb/target.h ++++ b/gdb/target.h +@@ -1011,6 +1011,14 @@ struct target_ops + *TARGET_ERRNO). */ + virtual int fileio_fstat (int fd, struct stat *sb, fileio_error *target_errno); + ++ /* Get information about the file FILENAME and put it in SB. Look for ++ FILENAME in the filesystem as seen by INF. If INF is NULL, use the ++ filesystem seen by the debugger (GDB or, for remote targets, the ++ remote stub). Return 0 on success, or -1 if an error occurs (and ++ set *TARGET_ERRNO). */ ++ virtual int fileio_stat (struct inferior *inf, const char *filename, ++ struct stat *sb, fileio_error *target_errno); ++ + /* Close FD on the target. Return 0, or -1 if an error occurs + (and set *TARGET_ERRNO). */ + virtual int fileio_close (int fd, fileio_error *target_errno); +@@ -2220,6 +2228,14 @@ extern int target_fileio_pread (int fd, gdb_byte *read_buf, int len, + extern int target_fileio_fstat (int fd, struct stat *sb, + fileio_error *target_errno); + ++/* Get information about the file at FILENAME on the target and put it in ++ SB. Look in the filesystem as seen by INF. If INF is NULL, use the ++ filesystem seen by the debugger (GDB or, for remote targets, the remote ++ stub). Return 0 on success, or -1 if an error occurs (and set ++ *TARGET_ERRNO). */ ++extern int target_fileio_stat (struct inferior *inf, const char *filename, ++ struct stat *sb, fileio_error *target_errno); ++ + /* Close FD on the target. Return 0, or -1 if an error occurs + (and set *TARGET_ERRNO). */ + extern int target_fileio_close (int fd, fileio_error *target_errno); +diff --git a/gdb/testsuite/gdb.base/build-id-seqno.c b/gdb/testsuite/gdb.base/build-id-seqno.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/build-id-seqno.c +@@ -0,0 +1,22 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++ Copyright 2024 Free Software Foundation, Inc. ++ ++ 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 . */ ++ ++int ++main (void) ++{ ++ return 0; ++} +diff --git a/gdb/testsuite/gdb.base/build-id-seqno.exp b/gdb/testsuite/gdb.base/build-id-seqno.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/build-id-seqno.exp +@@ -0,0 +1,133 @@ ++# This testcase is part of GDB, the GNU debugger. ++# ++# Copyright 2024 Free Software Foundation, Inc. ++# ++# 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 . ++ ++# Setup a .build-id/ based debug directory containing multiple entries ++# for the same build-id, with each entry given a different sequence ++# number. ++# ++# Ensure that GDB will scan over broken symlinks for the same build-id ++# (but different sequence number) to find later working symlinks. ++# ++# This test only places debug information on the host, so it is always ++# local to GDB. ++ ++require {!is_remote host} ++ ++standard_testfile ++ ++if {[build_executable "failed to prepare" $testfile $srcfile] == -1} { ++ return -1 ++} ++ ++# Split out BINFILE.debug. Remove debug from BINFILE. ++if {[gdb_gnu_strip_debug $binfile] != 0} { ++ return -1 ++} ++ ++# Get the '.build-id/xx/xxx...xxx' part of the filename. ++set build_id_filename [build_id_debug_filename_get $binfile] ++ ++# Hide (rename) BINFILE.debug, this should ensure GDB can't find it ++# directly but needs to look for the build-id based file in the debug ++# directory. ++set hidden_debuginfo [standard_output_file "hidden_$testfile.debug"] ++remote_exec build "mv ${binfile}.debug $hidden_debuginfo" ++ ++# A filename that doesn't exist. Some symlinks will point at this ++# file. ++set missing_debuginfo [host_standard_output_file "missing_debuginfo"] ++ ++# Create the debug directory, and the .build-id directory structure ++# within it. ++set debugdir [host_standard_output_file "debug"] ++remote_exec host "mkdir -p $debugdir/[file dirname $build_id_filename]" ++ ++set host_hidden_debuginfo [gdb_remote_download host $hidden_debuginfo] ++remote_exec host "ln -fs $host_hidden_debuginfo $debugdir/$build_id_filename" ++ ++# Start GDB and load global BINFILE. If FIND_DEBUGINFO is true then ++# we expect GDB to find the debug information matching BINFILE, ++# otherwise, we expect GDB not to find the debug information. ++proc load_binfile_check_debug_is_found { find_debuginfo testname } { ++ with_test_prefix "$testname" { ++ clean_restart ++ ++ gdb_test_no_output "set debug-file-directory $::debugdir" \ ++ "set debug-file-directory" ++ ++ gdb_file_cmd $::binfile ++ ++ if { $find_debuginfo } { ++ gdb_assert { [regexp [string_to_regexp \ ++ "Reading symbols from $::hidden_debuginfo..."] \ ++ $::gdb_file_cmd_msg] } \ ++ "debuginfo was read via build-id" ++ } else { ++ gdb_assert { [regexp "\\(No debugging symbols found in \[^\r\n\]+/$::testfile\\)" \ ++ $::gdb_file_cmd_msg] } \ ++ } ++ } ++} ++ ++# Return a copy of FILENAME, which should end '.debug', with NUMBER ++# added, e.g. add_seqno 1 "foo.debug" --> "foo.1.debug". ++proc add_seqno { number filename } { ++ return [regsub "\.debug\$" $filename ".${number}.debug"] ++} ++ ++load_binfile_check_debug_is_found true \ ++ "find debuginfo with a single build-id file" ++ ++remote_exec host "ln -fs $host_hidden_debuginfo \ ++ $debugdir/[add_seqno 1 $build_id_filename]" ++remote_exec host "ln -fs $host_hidden_debuginfo \ ++ $debugdir/[add_seqno 2 $build_id_filename]" ++remote_exec host "ln -fs $host_hidden_debuginfo \ ++ $debugdir/[add_seqno 3 $build_id_filename]" ++ ++load_binfile_check_debug_is_found true \ ++ "find debuginfo with 4 build-id files" ++ ++remote_exec host "ln -fs $missing_debuginfo $debugdir/$build_id_filename" ++ ++load_binfile_check_debug_is_found true \ ++ "find debuginfo, first build-id file is bad" ++ ++remote_exec host "ln -fs $missing_debuginfo \ ++ $debugdir/[add_seqno 1 $build_id_filename]" ++remote_exec host "ln -fs $missing_debuginfo \ ++ $debugdir/[add_seqno 3 $build_id_filename]" ++ ++load_binfile_check_debug_is_found true \ ++ "find debuginfo, first 2 build-id files are bad" ++ ++remote_exec host "ln -fs $missing_debuginfo \ ++ $debugdir/[add_seqno 2 $build_id_filename]" ++ ++load_binfile_check_debug_is_found false \ ++ "cannot find debuginfo, all build-id files are bad" ++ ++remote_exec host "ln -fs $host_hidden_debuginfo \ ++ $debugdir/[add_seqno 3 $build_id_filename]" ++ ++load_binfile_check_debug_is_found true \ ++ "find debuginfo, last build-id file is good" ++ ++remote_exec host "rm -f $debugdir/[add_seqno 1 $build_id_filename]" ++ ++load_binfile_check_debug_is_found false \ ++ "cannot find debuginfo, file with seqno 1 is missing" +diff --git a/gdb/testsuite/gdb.base/corefile-buildid.exp b/gdb/testsuite/gdb.base/corefile-buildid.exp +--- a/gdb/testsuite/gdb.base/corefile-buildid.exp ++++ b/gdb/testsuite/gdb.base/corefile-buildid.exp +@@ -172,11 +172,9 @@ proc locate_exec_from_core_build_id {corefile buildid suffix \ + "mkdir -p [file join $debugdir [file dirname $buildid]]" + + set files_list {} ++ lappend files_list $binfile $buildid + if {$sepdebug} { +- lappend files_list "$binfile.stripped" $buildid + lappend files_list "$binfile.debug" "$buildid.debug" +- } else { +- lappend files_list $binfile $buildid + } + if {$shared} { + global sharedir +@@ -200,12 +198,7 @@ proc locate_exec_from_core_build_id {corefile buildid suffix \ + gdb_test "core-file $corefile" "Program terminated with .*" \ + "load core file" + if {$symlink} { +- if {$sepdebug} { +- set expected_file [file join $builddir \ +- [file tail "$binfile.stripped"]] +- } else { +- set expected_file [file join $builddir [file tail $binfile]] +- } ++ set expected_file [file join $builddir [file tail $binfile]] + } else { + set expected_file $buildid + } +@@ -245,15 +238,12 @@ proc do_corefile_buildid_tests {args} { + + if {$sepdebug} { + # Strip debuginfo into its own file. +- if {[gdb_gnu_strip_debug [standard_output_file $program_to_run]] \ +- != 0} { ++ if {[gdb_gnu_strip_debug [standard_output_file $program_to_run] \ ++ no-debuglink] != 0} { + untested "could not strip executable for [join $suffix \ ]" + return + } + +- # Run the stripped program instead of the original. +- set program_to_run [file join $builddir \ +- [file tail "$binfile.stripped"]] + lappend suffix "sepdebug" + } + +diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp +--- a/gdb/testsuite/gdb.base/corefile.exp ++++ b/gdb/testsuite/gdb.base/corefile.exp +@@ -199,6 +199,45 @@ gdb_test "up" "#\[0-9\]* *(\[0-9xa-fH'\]* in)? .* \\(.*\\).*" "up (reinit)" + + gdb_test "core" "No core file now." + ++# Temporarily move coremmap.data out of the way and reload the core ++# file. We should still be able to read buf2 as the contents of this ++# are written into the core file. In contrast buf2ro should no longer ++# be readable as the contents of this region are not within the core ++# file, GDB relies on reading this from the coremmap.data file, which ++# can no longer be found. ++set coremmap_data_filename \ ++ [standard_output_file coredir.[getpid]/coremmap.data] ++set coremmap_data_backup_filename \ ++ [standard_output_file coredir.[getpid]/coremmap.data.backup] ++remote_exec host "mv ${coremmap_data_filename} \ ++ ${coremmap_data_backup_filename}" ++ ++clean_restart $binfile ++ ++# Load the core file and check we get a warning about the ++# coremmap.data file being missing. ++gdb_test_multiple "core-file $corefile" "warn about coremmap.data missing" { ++ -re -wrap "warning: Can't open file \[^\r\n\]+/coremmap.data during file-backed mapping note processing\r\n.*" { ++ pass $gdb_test_name ++ } ++} ++ ++# This xfail was just copied from earlier in the script where we also ++# read from buf2. ++setup_xfail "*-*-sunos*" "*-*-aix*" ++gdb_test "x/8bd buf2" \ ++ ".*:.*0.*1.*2.*3.*4.*5.*6.*7.*" \ ++ "accessing mmapped data in core file with coremmap.data removed" ++ ++gdb_test "x/8bd buf2ro" \ ++ "$hex\[^:\]*:\\s+Cannot access memory at address $hex" \ ++ "accessing read-only mmapped data in core file with coremmap.data removed" ++ ++# Restore the coremmap.data file so later tests don't give warnings ++# when the core file is reloaded. ++remote_exec host "mv ${coremmap_data_backup_filename} \ ++ ${coremmap_data_filename}" ++ + # Test that we can unload the core with the "detach" command. + + proc_with_prefix corefile_detach {} { +diff --git a/gdb/testsuite/gdb.base/solib-search.exp b/gdb/testsuite/gdb.base/solib-search.exp +--- a/gdb/testsuite/gdb.base/solib-search.exp ++++ b/gdb/testsuite/gdb.base/solib-search.exp +@@ -43,7 +43,11 @@ set right_binfile2_lib \ + set binfile1_lib [standard_output_file ${libname1}.so] + set binfile2_lib [standard_output_file ${libname2}.so] + +-set lib_flags [list debug ldflags=-Wl,-Bsymbolic] ++# When this test was written, GDB's ability to track down shared ++# libraries for a core file based on the build-id much poorer. As GDB ++# has improved we now need to disable build-ids in order for this test ++# to function as expected. ++set lib_flags [list debug no-build-id ldflags=-Wl,-Bsymbolic] + set wrong_lib_flags "$lib_flags additional_flags=-DARRAY_SIZE=1" + set right_lib_flags "$lib_flags additional_flags=-DARRAY_SIZE=8192 additional_flags=-DRIGHT" + +diff --git a/gdb/testsuite/gdb.base/sysroot-debug-lookup.exp b/gdb/testsuite/gdb.base/sysroot-debug-lookup.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/sysroot-debug-lookup.exp +@@ -0,0 +1,184 @@ ++# Copyright 2024 Free Software Foundation, Inc. ++# ++# 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 . ++ ++# Test GDB's ability to find debug information by looking within the ++# sysroot. ++# ++# We compile a static binary (to reduce what we need to copy into the ++# sysroot), split the debug information from the binary, and setup a ++# sysroot. ++# ++# The debug-file-directory is set to just '/debug', but we're ++# expecting GDB to actually look in '$SYSROOT/debug'. ++# ++# There's a test for using .build-id based lookup, and a test for ++# gnu_debuglink based lookup. ++ ++require {!is_remote host} ++ ++standard_testfile main.c ++ ++# Create a copy of BINFILE, split out the debug information, and then ++# setup a sysroot. Hide (by moving) the actual debug information file ++# and create a symlink to the hidden debug information from within the ++# sysroot. ++# ++# Start GDB, set the sysroot, and then load the executable, ensure GDB ++# finds the debug information, which must have happened by lookin in ++# the sysroot. ++proc_with_prefix lookup_via_build_id {} { ++ set filename ${::binfile}_1 ++ if { [build_executable "build exec" ${filename} $::srcfile \ ++ {additional_flags=-static debug build-id}] } { ++ return ++ } ++ ++ # Split debug information into a .debug file, remove debug ++ # information from FILENAME. Don't add a .gnu_debuglink to ++ # FILENAME, we rely on the build-id. ++ if {[gdb_gnu_strip_debug $filename { no-debuglink }] != 0} { ++ unsupported "cannot split debug information from executable" ++ return ++ } ++ ++ set sysroot [standard_output_file "sysroot1"] ++ set debug_dir "/debug" ++ ++ set debug_symlink \ ++ ${sysroot}${debug_dir}/[build_id_debug_filename_get $filename] ++ ++ set build_id_dir [file dirname $debug_symlink] ++ ++ set debug_filename ${filename}_hidden_debug ++ ++ remote_exec build "mkdir -p $build_id_dir" ++ remote_exec build "mv $filename.debug $debug_filename" ++ remote_exec build "ln -sf $debug_filename $debug_symlink" ++ ++ foreach_with_prefix sysroot_prefix { "" "target:" } { ++ clean_restart ++ ++ gdb_test_no_output "set sysroot ${sysroot_prefix}$sysroot" "set sysroot" ++ gdb_test_no_output "set debug-file-directory $debug_dir" ++ ++ gdb_file_cmd $filename ++ ++ gdb_assert { $::gdb_file_cmd_debug_info eq "debug" } \ ++ "ensure debug information was found" ++ ++ if { $sysroot_prefix eq "target:" ++ && [target_info gdb_protocol] == "extended-remote"} { ++ # Only when using the extended-remote board will we have ++ # started a remote target by this point. In this case GDB ++ # will see the 'target:' prefix as remote, and so the ++ # reported filename will include the 'target:' prefix. ++ # ++ # In all other cases we will still be using the default, ++ # initial target, in which case GDB considers the ++ # 'target:' prefix to indicate the local filesystem. ++ set lookup_filename $sysroot_prefix$debug_symlink ++ } else { ++ set lookup_filename $debug_filename ++ } ++ set re [string_to_regexp "Reading symbols from $lookup_filename..."] ++ gdb_assert {[regexp $re $::gdb_file_cmd_msg]} \ ++ "debug symbols read from correct file" ++ } ++} ++ ++# Create a copy of BINFILE, split out the debug information, and then ++# setup a sysroot. Hide (by moving) the actual debug information file ++# and create a symlink to the hidden debug information from within the ++# sysroot. ++# ++# Copy the executable into the sysroot and then start GDB, set the ++# sysroot, and load the executable. Check that GDB finds the debug ++# information, which must have happened by lookin in the sysroot. ++proc_with_prefix lookup_via_debuglink {} { ++ set filename ${::binfile}_2 ++ if { [build_executable "build exec" ${filename} $::srcfile \ ++ {additional_flags=-static debug no-build-id}] } { ++ return ++ } ++ ++ # Split debug information into a .debug file, remove debug ++ # information from FILENAME. ++ if {[gdb_gnu_strip_debug $filename] != 0} { ++ unsupported "cannot split debug information from executable" ++ return ++ } ++ ++ # We're going to setup the sysroot like this: ++ # ++ # sysroot2/ ++ # bin/ ++ # $FILENAME ++ # debug/ ++ # bin/ ++ # $FILENAME.debug ++ # ++ # When looking up debug information via the debuglink, GDB will ++ # only search in the sysroot if the original objfile was in the ++ # sysroot. And GDB will resolve symlinks, so if the objfile is ++ # symlinked to outside the sysroot, GDB will not search in the ++ # sysroot for the debug information. ++ # ++ # So we have to copy the executable into the sysroot. ++ # ++ # We are OK to symlink the debug information to a file outside the ++ # sysroot though. ++ ++ set sysroot [standard_output_file "sysroot2"] ++ ++ foreach path { bin debug/bin } { ++ remote_exec build "mkdir -p $sysroot/$path" ++ } ++ ++ # Copy the executable into the sysroot. ++ set file_basename [file tail $filename] ++ set exec_in_sysroot ${sysroot}/bin/${file_basename} ++ remote_exec build "cp $filename $exec_in_sysroot" ++ ++ # Rename the debug file outside of the sysroot, this should stop ++ # GDB finding this file "by accident". ++ set debug_filename ${filename}_hidden_debug ++ remote_exec build "mv $filename.debug $debug_filename" ++ ++ # Symlink the debug information into the sysroot. ++ set debug_symlink \ ++ ${sysroot}/debug/bin/${file_basename}.debug ++ remote_exec build "ln -sf $debug_filename $debug_symlink" ++ ++ foreach_with_prefix sysroot_prefix { "" "target:" } { ++ # Restart GDB and setup the sysroot and debug directory. ++ clean_restart ++ gdb_test_no_output "set sysroot ${sysroot_prefix}$sysroot" "set sysroot" ++ gdb_test_no_output "set debug-file-directory /debug" ++ ++ # Load the executable, we expect GDB to find the debug information ++ # in the sysroot. ++ gdb_file_cmd ${sysroot_prefix}$exec_in_sysroot ++ ++ gdb_assert { $::gdb_file_cmd_debug_info eq "debug" } \ ++ "ensure debug information was found" ++ ++ set re [string_to_regexp "Reading symbols from ${sysroot_prefix}$debug_symlink..."] ++ gdb_assert {[regexp $re $::gdb_file_cmd_msg]} \ ++ "debug symbols read from correct file" ++ } ++} ++ ++lookup_via_build_id ++lookup_via_debuglink +diff --git a/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp b/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp +--- a/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp ++++ b/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp +@@ -30,14 +30,11 @@ if {[build_executable "build executable" ${testfile} ${srcfile} \ + return -1 + } + +-# Split BINFILE into BINFILE.stripped and BINFILE.debug, the first is +-# the executable with the debug information removed, and the second is +-# the debug information. ++# Split debug information from BINFILE into BINFILE.debug. + # +-# However, by passing the "no-debuglink" flag we prevent this proc +-# from adding a .gnu_debuglink section to the executable. Any lookup +-# of the debug information by GDB will need to be done based on the +-# build-id. ++# By passing the "no-debuglink" flag we prevent this proc from adding ++# a .gnu_debuglink section to BINFILE. Any lookup of the debug ++# information by GDB will need to be done based on the build-id. + if {[gdb_gnu_strip_debug $binfile no-debuglink]} { + unsupported "cannot produce separate debug info files" + return -1 +@@ -59,12 +56,6 @@ set debuginfod_debugdir [standard_output_file "debug"] + remote_exec build "mkdir $debuginfod_debugdir" + remote_exec build "mv $debugfile $debuginfod_debugdir" + +-# This is BINFILE with the debug information removed. We are going to +-# place this in the BUILD_ID_DEBUG_FILE location, this would usually +-# represent a mistake by the user, and will trigger a warning from +-# GDB, this is the warning we are checking for. +-set stripped_binfile [standard_output_file "${binfile}.stripped"] +- + # Create the .build-id/PREFIX directory name from + # .build-id/PREFIX/SUFFIX.debug filename. + set debugdir [file dirname ${build_id_debug_file}] +@@ -76,7 +67,7 @@ remote_exec build "mkdir -p $debugdir" + # information, which will point back at this file, which also doesn't + # have debug information, which could cause a loop. But GDB will spot + # this and give a warning. +-remote_exec build "mv ${stripped_binfile} ${build_id_debug_file}" ++remote_exec build "mv ${binfile} ${build_id_debug_file}" + + # Now start GDB. + clean_restart +diff --git a/gdb/testsuite/gdb.debuginfod/corefile-mapped-file-1.c b/gdb/testsuite/gdb.debuginfod/corefile-mapped-file-1.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.debuginfod/corefile-mapped-file-1.c +@@ -0,0 +1,24 @@ ++/* Copyright 2024 Free Software Foundation, Inc. ++ ++ 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 . */ ++ ++/* This is in the shared library. */ ++extern int foo (void); ++ ++int ++main (void) ++{ ++ int res = foo (); ++ return res; ++} +diff --git a/gdb/testsuite/gdb.debuginfod/corefile-mapped-file-2.c b/gdb/testsuite/gdb.debuginfod/corefile-mapped-file-2.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.debuginfod/corefile-mapped-file-2.c +@@ -0,0 +1,22 @@ ++/* Copyright 2024 Free Software Foundation, Inc. ++ ++ 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 . */ ++ ++volatile int *library_ptr = (int *) POINTER_VALUE; ++ ++int ++foo (void) ++{ ++ return *library_ptr; ++} +diff --git a/gdb/testsuite/gdb.debuginfod/corefile-mapped-file-3.c b/gdb/testsuite/gdb.debuginfod/corefile-mapped-file-3.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.debuginfod/corefile-mapped-file-3.c +@@ -0,0 +1,45 @@ ++/* Copyright 2024 Free Software Foundation, Inc. ++ ++ 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 . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++volatile void* library_base_address = 0; ++volatile int *ptr = 0; ++ ++int ++main () ++{ ++ struct stat buf; ++ int res; ++ ++ int fd = open (SHLIB_FILENAME, O_RDONLY); ++ assert (fd != -1); ++ ++ res = fstat (fd, &buf); ++ assert (res == 0); ++ ++ library_base_address ++ = mmap (NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); ++ ++ res = *ptr; /* Undefined behaviour here. */ ++ ++ return 0; ++} +diff --git a/gdb/testsuite/gdb.debuginfod/corefile-mapped-file.exp b/gdb/testsuite/gdb.debuginfod/corefile-mapped-file.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.debuginfod/corefile-mapped-file.exp +@@ -0,0 +1,380 @@ ++# Copyright 2024 Free Software Foundation, Inc. ++# ++# 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 . */ ++ ++# This test checks GDB's ability to use build-ids when setting up file backed ++# mappings as part of reading a core-file. ++# ++# A core-file contains a list of the files that were mapped into the process ++# at the time of the core-file creation. If the file was mapped read-only ++# then the file contents will not be present in the core-file, but instead GDB ++# is expected to open the mapped file and read the contents from there if ++# needed. And this is what GDB does. ++# ++# GDB (via the BFD library) will also spot if a mapped looks like a valid ELF ++# and contains a build-id, this build-id is passed back to GDB so that GDB can ++# validate the on-disk file it finds matches the file that was mapped when the ++# core-file was created. ++# ++# In addition, if the on-disk file is found to have a non-matching build-id ++# then GDB can use debuginfod to (try) and download a suitable file. ++# ++# This test is about checking that this file backed mapping mechanism works ++# correctly; that GDB will spot when the build-ids fail to match and will ++# refuse to load an incorrect file. Additionally we check that the correct ++# file can be downloaded from debuginfod. ++# ++# The test is rather contrived though. Instead of relying on having a shared ++# library mapped at the time of crash we mmap a shared library into the ++# process and then check this mapping within the test. ++# ++# The problem with using a normal shared library load for this test is that ++# the shared library list is processed as part of a separate step when opening ++# the core file. Right now this separate step doesn't check the build-ids ++# correctly, so GDB will potentially open the wrong shared library file. The ++# sections of this incorrect shared library are then added to GDB's list of ++# target sections, and are used to satisfy memory reads, which can give the ++# wrong results. ++# ++# This obviously needs fixing, but is a separate problem from the one being ++# tested here, so this test deliberately checks the mapping using a file that ++# is mmaped rather than loaded as a shared library, as such the file is in the ++# core-files list of mapped files, but is not in the shared library list. ++# ++# Despite this test living in the gdb.debuginfod/ directory, only the last ++# part of this test actually uses debuginfod, everything up to that point is ++# pretty generic. ++ ++require {!is_remote host} ++require {!is_remote target} ++ ++load_lib debuginfod-support.exp ++ ++require allow_shlib_tests ++ ++standard_testfile -1.c -2.c -3.c ++ ++# Compile an executable that loads the shared library as an actual ++# shared library, then use GDB to figure out the offset of the ++# variable 'library_ptr' within the library. ++set library_filename [standard_output_file "libfoo.so"] ++set binfile2 [standard_output_file "library_loader"] ++ ++if {[prepare_for_testing_full "build exec which loads the shared library" \ ++ [list $library_filename \ ++ { debug shlib build-id \ ++ additional_flags=-DPOINTER_VALUE=0x12345678 } \ ++ $srcfile2 {}] \ ++ [list $binfile2 [list debug shlib=$library_filename ] \ ++ $srcfile { debug }]] != 0} { ++ return ++} ++ ++if {![runto_main]} { ++ return ++} ++ ++if { [is_address_zero_readable] } { ++ return ++} ++ ++set ptr_address [get_hexadecimal_valueof "&library_ptr" "unknown"] ++ ++set ptr_offset "unknown" ++gdb_test_multiple "info proc mappings" "" { ++ -re "^\\s+($hex)\\s+($hex)\\s+$hex\\s+($hex)\[^\r\n\]+$library_filename\r\n" { ++ set low_addr $expect_out(1,string) ++ set high_addr $expect_out(2,string) ++ set file_offset $expect_out(3,string) ++ ++ if {[expr $ptr_address >= $low_addr] && [expr $ptr_address < $high_addr]} { ++ set mapping_offset [expr $ptr_address - $low_addr] ++ set ptr_offset [format 0x%x [expr $file_offset + $mapping_offset]] ++ } ++ ++ exp_continue ++ } ++ ++ -re "^$gdb_prompt $" { ++ } ++ ++ -re "(^\[^\r\n\]*)\r\n" { ++ set tmp $expect_out(1,string) ++ exp_continue ++ } ++} ++ ++gdb_assert { $ptr_offset ne "unknown" } \ ++ "found pointer offset" ++ ++set ptr_size [get_integer_valueof "sizeof (library_ptr)" "unknown"] ++set ptr_format_char "" ++if { $ptr_size == 2 } { ++ set ptr_format_char "b" ++} elseif { $ptr_size == 4 } { ++ set ptr_format_char "w" ++} elseif { $ptr_size == 8 } { ++ set ptr_format_char "g" ++} ++if { $ptr_format_char eq "" } { ++ untested "could not figure out size of library_ptr variable" ++ return ++} ++ ++# Helper proc to read a value from inferior memory. Reads at address held in ++# global PTR_ADDRESS, and use PTR_FORMAT_CHAR for the size of the read. ++proc read_ptr_value { } { ++ set value "" ++ gdb_test_multiple "x/1${::ptr_format_char}x ${::ptr_address}" "" { ++ -re -wrap "^${::hex}(?:\\s+<\[^>\]+>)?:\\s+($::hex)" { ++ set value $expect_out(1,string) ++ } ++ -re -wrap "^${::hex}(?:\\s+<\[^>\]+>)?:\\s+Cannot access memory at address ${::hex}" { ++ set value "unavailable" ++ } ++ } ++ return $value ++} ++ ++set ptr_expected_value [read_ptr_value] ++if { $ptr_expected_value eq "" } { ++ untested "could not find expected value for library_ptr" ++ return ++} ++ ++# Now compile a second executable. This one doesn't load the shared ++# library as an actual shared library, but instead mmaps the library ++# into the executable. ++# ++# Load this executable within GDB and confirm that we can use the ++# offset we calculated previously to view the value of 'library_ptr'. ++set opts [list debug additional_flags=-DSHLIB_FILENAME=\"$library_filename\"] ++if {[prepare_for_testing "prepare second executable" $binfile \ ++ $srcfile3 $opts] != 0} { ++ return ++} ++ ++if {![runto_main]} { ++ return ++} ++ ++gdb_breakpoint [gdb_get_line_number "Undefined behaviour here" $srcfile3] ++gdb_continue_to_breakpoint "run to breakpoint" ++ ++set library_base_address \ ++ [get_hexadecimal_valueof "library_base_address" "unknown"] ++set ptr_address [format 0x%x [expr $library_base_address + $ptr_offset]] ++ ++set ptr_value [read_ptr_value] ++gdb_assert { $ptr_value == $ptr_expected_value } \ ++ "check value of pointer variable" ++ ++# Now rerun the second executable outside of GDB. The executable should crash ++# and generate a corefile. ++set corefile [core_find $binfile] ++if {$corefile eq ""} { ++ untested "could not generate core file" ++ return ++} ++ ++# Load a core file from the global COREFILE. Use TESTNAME as the name ++# of the test. ++# ++# If LINE_RE is not the empty string then this is a regexp for a line ++# that we expect to see in the output when loading the core file, if ++# the line is not present then this test will fail. ++# ++# Any lines beginning with 'warning: ' will cause this test to fail. ++# ++# A couple of other standard lines that are produced when loading a ++# core file are also checked for, just to make sure the core file ++# loading has progressed as expected. ++proc load_core_file { testname { line_re "" } } { ++ set code {} ++ ++ if { $line_re ne "" } { ++ append code { ++ -re "^$line_re\r\n" { ++ set saw_expected_line true ++ exp_continue ++ } ++ } ++ set saw_expected_line false ++ } else { ++ set saw_expected_line true ++ } ++ ++ set saw_unknown_warning false ++ set saw_generated_by_line false ++ set saw_prog_terminated_line false ++ ++ append code { ++ -re "^warning: \[^\r\n\]+\r\n" { ++ set saw_unknown_warning true ++ exp_continue ++ } ++ ++ -re "^Core was generated by \[^\r\n\]+\r\n" { ++ set saw_generated_by_line true ++ exp_continue ++ } ++ ++ -re "^Program terminated with signal SIGSEGV, Segmentation fault\\.\r\n" { ++ set saw_prog_terminated_line true ++ exp_continue ++ } ++ ++ -re "^$::gdb_prompt $" { ++ gdb_assert {$saw_generated_by_line \ ++ && $saw_prog_terminated_line \ ++ && $saw_expected_line \ ++ && !$saw_unknown_warning} \ ++ $gdb_test_name ++ } ++ ++ -re "^\[^\r\n\]*\r\n" { ++ exp_continue ++ } ++ } ++ ++ set res [catch { return [gdb_test_multiple "core-file $::corefile" \ ++ "$testname" $code] } string] ++ ++ if {$res == 1} { ++ global errorInfo errorCode ++ return -code error -errorinfo $errorInfo -errorcode $errorCode $string ++ } elseif {$res == 2} { ++ return $string ++ } else { ++ # We expect RES to be 2 (TCL_RETURN) or 1 (TCL_ERROR). If we get ++ # here then somehow the 'catch' above finished without hitting ++ # either of those cases, which is .... weird. ++ perror "unexepcted return value, code = $res, value = $string" ++ return -1 ++ } ++} ++ ++# And now restart GDB, load the core-file and check that the library shows as ++# being mapped in, and that we can still read the library_ptr value from ++# memory. ++clean_restart $binfile ++ ++load_core_file "load core file" ++ ++set library_base_address [get_hexadecimal_valueof "library_base_address" \ ++ "unknown" "get library_base_address in core-file"] ++set ptr_address [format 0x%x [expr $library_base_address + $ptr_offset]] ++ ++set ptr_value [read_ptr_value] ++gdb_assert { $ptr_value == $ptr_expected_value } \ ++ "check value of pointer variable from core-file" ++ ++# Now move the shared library file away and restart GDB. This time when we ++# load the core-file we should see a warning that GDB has failed to map in the ++# library file. An attempt to read the variable from the library file should ++# fail / give a warning. ++set library_backup_filename [standard_output_file "libfoo.so.backup"] ++remote_exec build "mv \"$library_filename\" \"$library_backup_filename\"" ++ ++clean_restart $binfile ++ ++load_core_file "load corefile with library file missing" \ ++ "warning: Can't open file [string_to_regexp $library_filename] during file-backed mapping note processing" ++ ++set ptr_value [read_ptr_value] ++gdb_assert { $ptr_value eq "unavailable" } \ ++ "check value of pointer is unavailable with library file missing" ++ ++# Now symlink the .build-id/xx/xxx...xxx filename within the debug ++# directory to library we just moved aside. Restart GDB and setup the ++# debug-file-directory before loading the core file. ++# ++# GDB should lookup the file to map via the build-id link in the ++# .build-id/ directory. ++set debugdir [standard_output_file "debugdir"] ++set build_id_filename \ ++ $debugdir/[build_id_debug_filename_get $library_backup_filename ""] ++ ++remote_exec build "mkdir -p [file dirname $build_id_filename]" ++remote_exec build "ln -sf $library_backup_filename $build_id_filename" ++ ++clean_restart $binfile ++ ++gdb_test_no_output "set debug-file-directory $debugdir" \ ++ "set debug-file-directory" ++ ++load_core_file "load corefile, lookup in debug-file-directory" ++ ++set ptr_value [read_ptr_value] ++gdb_assert { $ptr_value == $ptr_expected_value } \ ++ "check value of pointer variable from core-file, lookup in debug-file-directory" ++ ++# Build a new version of the shared library, keep the library the same size, ++# but change the contents so the build-id changes. Then restart GDB and load ++# the core-file again. GDB should spot that the build-id for the shared ++# library is not as expected, and should refuse to map in the shared library. ++if {[build_executable "build second version of shared library" \ ++ $library_filename $srcfile2 \ ++ { debug shlib build-id \ ++ additional_flags=-DPOINTER_VALUE=0x11223344 }] != 0} { ++ return ++} ++ ++clean_restart $binfile ++ ++load_core_file "load corefile with wrong library in place" \ ++ "warning: File [string_to_regexp $library_filename] doesn't match build-id from core-file during file-backed mapping processing" ++ ++set ptr_value [read_ptr_value] ++gdb_assert { $ptr_value eq "unavailable" } \ ++ "check value of pointer is unavailable with wrong library in place" ++ ++# Setup a debuginfod server which can serve the original shared library file. ++# Then restart GDB and load the core-file. GDB should download the original ++# shared library from debuginfod and use that to provide the file backed ++# mapping. ++if {![allow_debuginfod_tests]} { ++ untested "skippig debuginfod parts of this test" ++ return ++} ++ ++set server_dir [standard_output_file "debuginfod.server"] ++file mkdir $server_dir ++file rename -force $library_backup_filename $server_dir ++ ++prepare_for_debuginfod cache db ++ ++set url [start_debuginfod $db $server_dir] ++if { $url eq "" } { ++ unresolved "failed to start debuginfod server" ++ return ++} ++ ++with_debuginfod_env $cache { ++ setenv DEBUGINFOD_URLS $url ++ ++ clean_restart ++ gdb_test_no_output "set debuginfod enabled on" \ ++ "enabled debuginfod for initial test" ++ gdb_load $binfile ++ ++ load_core_file "load corefile, download library from debuginfod" \ ++ "Downloading\[^\r\n\]* file [string_to_regexp $library_filename]\\.\\.\\." ++ ++ set ptr_value [read_ptr_value] ++ gdb_assert { $ptr_value == $ptr_expected_value } \ ++ "check value of pointer variable after downloading library file" ++} ++ ++stop_debuginfod +diff --git a/gdb/testsuite/gdb.debuginfod/solib-with-soname-1.c b/gdb/testsuite/gdb.debuginfod/solib-with-soname-1.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.debuginfod/solib-with-soname-1.c +@@ -0,0 +1,39 @@ ++/* Copyright 2024 Free Software Foundation, Inc. ++ ++ 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 . */ ++ ++#include ++ ++/* It is important that these two variables have names of the same length ++ so that the debug information in the two library versions is laid out ++ the same. If they differ then the .dynamic section might move, which ++ will trigger a different check within GDB than the one we actually want ++ to check. */ ++ ++#if LIB_VERSION == 1 ++volatile int *library_1_var = (volatile int *) 0x12345678; ++#elif LIB_VERSION == 2 ++volatile int *library_2_var = (volatile int *) 0x11223344; ++#else ++# error Unknown library version ++#endif ++ ++int ++foo (void) ++{ ++ /* This should trigger a core dump. */ ++ abort (); ++ ++ return 0; ++} +diff --git a/gdb/testsuite/gdb.debuginfod/solib-with-soname-2.c b/gdb/testsuite/gdb.debuginfod/solib-with-soname-2.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.debuginfod/solib-with-soname-2.c +@@ -0,0 +1,41 @@ ++/* Copyright 2024 Free Software Foundation, Inc. ++ ++ 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 . */ ++ ++#include ++#include ++#include ++ ++/* This is in the shared library. */ ++extern int foo (void); ++ ++/* This is updated by the .exp file. */ ++char *libname = "libfoo_2.so"; ++ ++int ++main (void) ++{ ++ void *handle; ++ int res, tmp; ++ ++ handle = dlopen (libname, RTLD_LAZY); ++ assert (handle != NULL); ++ ++ res = foo (); ++ ++ tmp = dlclose (handle); ++ assert (tmp == 0); ++ ++ return res; ++} +diff --git a/gdb/testsuite/gdb.debuginfod/solib-with-soname.exp b/gdb/testsuite/gdb.debuginfod/solib-with-soname.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.debuginfod/solib-with-soname.exp +@@ -0,0 +1,290 @@ ++# Copyright 2024 Free Software Foundation, Inc. ++# ++# 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 . */ ++ ++# This test exercises GDB's ability to validate build-ids when loading ++# shared libraries for a core file. ++# ++# The test creates two "versions" of a shared library, sets up a ++# symlink to point to one version of the library, and creates a core file. ++# ++# We then try re-loading the core file and executable and check that ++# GDB is able to correctly load the shared library. To confuse things ++# we retarget the library symlink at the other version of the library. ++# ++# After that we repeat the test, but this time deleting the symlink ++# completely. ++# ++# Then we remove the version of the library completely, at this point ++# we do expect GDB to give a warning about being unable to load the library. ++# ++# And finally, we setup debuginfod and have it serve the missing ++# library file, GDB should correctly download the library file. ++# ++# Despite this test living in the gdb.debuginfod/ directory, only the last ++# part of this test actually uses debuginfod, everything up to that point is ++# pretty generic. ++ ++load_lib debuginfod-support.exp ++ ++require allow_shlib_tests ++require {istarget "*-linux*"} ++require {!is_remote host} ++require {!using_fission} ++ ++standard_testfile -1.c -2.c ++ ++# Build two similar, but slightly different versions of the shared ++# library. Both libraries have DT_SONAME set to the generic ++# libfoo.so, we'll create a symlink with that name later. ++set library_1_filename [standard_output_file "libfoo_1.so"] ++set library_2_filename [standard_output_file "libfoo_2.so"] ++ ++# The generic name for the library. ++set library_filename [standard_output_file "libfoo.so"] ++ ++# When compiling a shared library the -Wl,-soname,NAME option is ++# automatically added based on the final name of the library. We want ++# to compile libfoo_1.so, but set the soname to libfoo.so. To achieve ++# this we first compile into libfoo.so, and then rename the library to ++# libfoo_1.so. ++if {[build_executable "build libfoo_1.so" $library_filename \ ++ $srcfile \ ++ { debug shlib build-id \ ++ additional_flags=-DLIB_VERSION=1 }] == -1} { ++ return ++} ++remote_exec build "mv ${library_filename} ${library_1_filename}" ++ ++# See the comment above, but this time we rename to libfoo_2.so. ++if {[build_executable "build libfoo_2.so" $library_filename \ ++ $srcfile \ ++ { debug shlib build-id \ ++ additional_flags=-DLIB_VERSION=2 }] == -1} { ++ return ++} ++remote_exec build "mv ${library_filename} ${library_2_filename}" ++ ++# Create libfoo.so symlink to the libfoo_1.so library. If this ++# symlink creation fails then we assume we can't create symlinks on ++# this host. If this succeeds then later symlink creation is required ++# to succeed, and will trigger an FAIL if it doesn't. ++set status \ ++ [remote_exec build \ ++ "ln -sf ${library_1_filename} ${library_filename}"] ++if {[lindex $status 0] != 0} { ++ unsupported "host does not support symbolic links" ++ return ++} ++ ++# Build the executable. This links against libfoo.so, which is ++# poining at libfoo_1.so. Just to confuse things even more, this ++# executable uses dlopen to load libfoo_2.so. Weird! ++if { [build_executable "build executable" ${binfile} ${srcfile2} \ ++ [list debug shlib=${library_filename} shlib_load]] == -1 } { ++ return ++} ++ ++# If the board file is automatically splitting the debug information ++# into a separate file (e.g. the cc-with-gnu-debuglink.exp board) then ++# this test isn't going to work. ++clean_restart ++gdb_file_cmd $binfile ++if {$gdb_file_cmd_debug_info ne "debug"} { ++ unsupported "failed to find debug information" ++ return ++} ++if {[regexp "${testfile}.debug" $gdb_file_cmd_msg]} { ++ unsupported "debug information has been split to a separate file" ++ return ++} ++ ++# Run BINFILE which will generate a corefile. ++set corefile [core_find $binfile] ++if {$corefile eq ""} { ++ untested "could not generate core file" ++ return ++} ++ ++# Helper proc to load global BINFILE and then load global COREFILE. ++# ++# If EXPECT_WARNING is true then we require a warning about being ++# unable to load the shared library symbols, otherwise, EXPECT_WARNING ++# is false and we require no warning. ++# ++# If EXPECT_DOWNLOAD is true then we require a line indicating that ++# the shared library is being downloaded from debuginfod, otherwise ++# the shared library should not be downloaded. ++# ++# If DEBUGDIR is not the empty string then 'debug-file-directory' is ++# set to the value of DEBUGDIR. ++proc load_exec_and_core_file { expect_warning expect_download testname \ ++ {debugdir ""} } { ++ with_test_prefix $testname { ++ clean_restart $::binfile ++ ++ if { $debugdir ne "" } { ++ gdb_test_no_output "set debug-file-directory $debugdir" \ ++ "set debug directory" ++ } ++ ++ set saw_warning false ++ set saw_download false ++ set saw_generated false ++ set saw_terminated false ++ ++ gdb_test_multiple "core-file $::corefile" "load core file" { ++ -re "^Core was generated by \[^\r\n\]+\r\n" { ++ set saw_generated true ++ exp_continue ++ } ++ -re "^Program terminated with signal \[^\r\n\]+\r\n" { ++ set saw_terminated true ++ exp_continue ++ } ++ -re "^warning: Can't open file \[^\r\n\]+ during file-backed mapping note processing\r\n" { ++ # Ignore warnings from the file backed mapping phase. ++ exp_continue ++ } ++ -re "^warning: Could not load shared library symbols for \[^\r\n\]+/libfoo\\.so\\.\r\n" { ++ set saw_warning true ++ exp_continue ++ } ++ -re "^Downloading file \[^\r\n\]+/libfoo_1\\.so\\.\\.\\.\r\n" { ++ set saw_download true ++ exp_continue ++ } ++ -re "^$::gdb_prompt $" { ++ gdb_assert { $saw_generated && $saw_terminated \ ++ && $saw_warning == $expect_warning \ ++ && $saw_download == $expect_download } \ ++ $gdb_test_name ++ } ++ -re "^\[^\r\n\]*\r\n" { ++ exp_continue ++ } ++ } ++ ++ # If we don't expect a warning then debug symbols from the ++ # shared library should be available. Confirm we can read a ++ # variable from the shared library. If we do expect a warning ++ # then the shared library debug symbols have not loaded, and ++ # the library variable should not be available. ++ if { !$expect_warning } { ++ gdb_test "print/x library_1_var" " = 0x12345678" \ ++ "check library_1_var can be read" ++ } else { ++ gdb_test "print/x library_1_var" \ ++ "^No symbol \"library_1_var\" in current context\\." \ ++ "check library_1_var cannot be read" ++ } ++ } ++} ++ ++# Initial test, just load the executable and core file. At this point ++# everything should load fine as everything is where we expect to find ++# it. ++load_exec_and_core_file false false \ ++ "load core file, all libraries as expected" ++ ++# Update libfoo.so symlink to point at the second library then reload ++# the core file. GDB should spot that the symlink points to the wrong ++# file, but should be able to figure out the correct file to load as ++# the right file will be in the mapped file list. ++set status [remote_exec build \ ++ "ln -sf ${library_2_filename} ${library_filename}"] ++gdb_assert { [lindex $status 0] == 0 } \ ++ "update library symlink to point to the wrong file" ++ ++load_exec_and_core_file false false \ ++ "load core file, symlink points to wrong file" ++ ++# Remove libfoo.so symlink and reload the core file. As in the ++# previous test GDB should be able to figure out the correct file to ++# load as the correct file will still appear in the mapped file list. ++set status [remote_exec build "rm -f ${library_filename}"] ++gdb_assert { [lindex $status 0] == 0 } "remove library symlink" ++ ++load_exec_and_core_file false false \ ++ "load core file, symlink removed" ++ ++# Remove LIBRARY_1_FILENAME. We'll now see a warning that the mapped ++# file can't be loaded (we ignore that warning), and we'll see a ++# warning that the shared library can't be loaded. ++set library_1_backup_filename ${library_1_filename}.backup ++set status \ ++ [remote_exec build \ ++ "mv ${library_1_filename} ${library_1_backup_filename}"] ++gdb_assert { [lindex $status 0] == 0 } \ ++ "remove libfoo_1.so" ++ ++load_exec_and_core_file true false \ ++ "load core file, libfoo_1.so removed" ++ ++# Symlink the .build-id/xx/xxx...xxx filename within the debug ++# directory to LIBRARY_1_BACKUP_FILENAME, now when we restart GDB it ++# should find the missing library within the debug directory. ++set debugdir [standard_output_file "debugdir"] ++set build_id_filename \ ++ $debugdir/[build_id_debug_filename_get $library_1_backup_filename ""] ++set status \ ++ [remote_exec build \ ++ "mkdir -p [file dirname $build_id_filename]"] ++gdb_assert { [lindex $status 0] == 0 } \ ++ "create sub-directory within the debug directory" ++set status \ ++ [remote_exec build \ ++ "ln -sf $library_1_backup_filename $build_id_filename"] ++gdb_assert { [lindex $status 0] == 0 } \ ++ "create symlink within the debug directory " ++ ++load_exec_and_core_file false false \ ++ "load core file, find libfoo_1.so through debug-file-directory" \ ++ $debugdir ++ ++# Setup a debuginfod server which can serve the original shared ++# library file. ++if {![allow_debuginfod_tests]} { ++ untested "skippig debuginfod parts of this test" ++ return ++} ++ ++set server_dir [standard_output_file "debuginfod.server"] ++file mkdir $server_dir ++file rename -force $library_1_backup_filename $server_dir ++ ++prepare_for_debuginfod cache db ++ ++set url [start_debuginfod $db $server_dir] ++if { $url eq "" } { ++ unresolved "failed to start debuginfod server" ++ return ++} ++ ++with_debuginfod_env $cache { ++ setenv DEBUGINFOD_URLS $url ++ ++ save_vars { GDBFLAGS } { ++ append GDBFLAGS " -ex \"set debuginfod enabled on\"" ++ ++ # Reload the executable and core file. GDB should download ++ # the file libfoo_1.so using debuginfod during the mapped file ++ # phase, but should then reuse that download during the shared ++ # library phase. ++ load_exec_and_core_file false true \ ++ "load core file, use debuginfod" ++ } ++} ++ ++stop_debuginfod +diff --git a/gdb/testsuite/gdb.dwarf2/short-build-id.exp b/gdb/testsuite/gdb.dwarf2/short-build-id.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.dwarf2/short-build-id.exp +@@ -0,0 +1,119 @@ ++# Copyright 2024 Free Software Foundation, Inc. ++# ++# 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 . ++ ++# Create a file with an artificially short (1-byte) build-id, and ++# check that GDB doesn't try to load debug information. If we do try ++# then we end up loading from: `debug-directory/.build-id/xx/.debug` ++# which isn't right. ++ ++load_lib dwarf.exp ++ ++# This test can only be run on targets which support DWARF-2 and use gas. ++require dwarf2_support ++ ++# No remote host testing either. ++require {!is_remote host} ++ ++standard_testfile main.c ++ ++# Create an assembler file which encodes BUILDID as the build-id. Compile ++# this along with the global SRCFILE to create a test executable. ++# ++# Split the debug information out from the newly created executable and place ++# it into the debug file directory. ++# ++# Load the executable into GDB and check to see if the debug information was ++# loaded or not. For this test we are expecting that the debug information ++# was not loaded. The reason is that, with short values for BUILDID, GDB ends ++# up looking for the debug information in weird locations. ++proc run_test { buildid } { ++ set len [string length $buildid] ++ ++ set asm_file [standard_output_file "$::testfile.$len.S"] ++ Dwarf::assemble $asm_file { ++ declare_labels int_label int_label2 ++ ++ upvar buildid buildid ++ ++ build_id $buildid ++ ++ cu { label cu_start } { ++ compile_unit {{language @DW_LANG_C}} { ++ int_label2: base_type { ++ {name int} ++ {byte_size 4 sdata} ++ {encoding @DW_ATE_signed} ++ } ++ ++ constant { ++ {name the_int} ++ {type :$int_label2} ++ {const_value 99 data1} ++ } ++ } ++ } ++ ++ aranges {} cu_start { ++ arange {} 0 0 ++ } ++ } ++ ++ set execfile [standard_output_file $::testfile.$len] ++ ++ if { [build_executable_from_specs "failed to build" \ ++ $execfile {debug no-build-id} \ ++ $::srcfile debug \ ++ $asm_file {}] } { ++ return ++ } ++ ++ # Create the debug directory. ++ set debugdir [standard_output_file "debugdir.$len"] ++ set build_id_dir $debugdir/.build-id/$buildid ++ remote_exec host "mkdir -p $build_id_dir" ++ ++ # Split out the debug information. ++ if {[gdb_gnu_strip_debug $execfile no-debuglink]} { ++ unresolved "failed to split out debug information" ++ return ++ } ++ ++ # Move the debug information into the debug directory. We place the debug ++ # information into a file called just '.debug'. GDB should not check this ++ # file, but at one point GDB would check this file, even though this ++ # doesn't make much sense. ++ set execfile_debug ${execfile}.debug ++ remote_exec host "mv $execfile_debug $build_id_dir/.debug" ++ ++ # Start GDB, set the debug-file-directory, and try loading the file. ++ clean_restart ++ ++ gdb_test_no_output "set debug-file-directory $debugdir" \ ++ "set debug-file-directory" ++ ++ gdb_file_cmd $execfile ++ ++ gdb_assert { $::gdb_file_cmd_debug_info eq "nodebug" } \ ++ "no debug should be loaded" ++ ++ # For sanity, read something that was encoded in the debug ++ # information, this should fail. ++ gdb_test "print the_int" \ ++ "(?:No symbol table is loaded|No symbol \"the_int\" in current context).*" ++} ++ ++foreach_with_prefix buildid { a4 "" } { ++ run_test $buildid ++} +diff --git a/gdb/testsuite/gdb.python/py-missing-objfile-lib.c b/gdb/testsuite/gdb.python/py-missing-objfile-lib.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.python/py-missing-objfile-lib.c +@@ -0,0 +1,35 @@ ++/* This test program is part of GDB, the GNU debugger. ++ ++ Copyright 2024 Free Software Foundation, Inc. ++ ++ 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 . */ ++ ++struct lib_type ++{ ++ int a; ++ int b; ++}; ++ ++volatile struct lib_type global_lib_var = { 0, 0 }; ++ ++int ++foo (void) ++{ ++ int res = 0; ++ ++ res += global_lib_var.a; ++ res += global_lib_var.b; ++ ++ return 0; ++} +diff --git a/gdb/testsuite/gdb.python/py-missing-objfile.c b/gdb/testsuite/gdb.python/py-missing-objfile.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.python/py-missing-objfile.c +@@ -0,0 +1,49 @@ ++/* This test program is part of GDB, the GNU debugger. ++ ++ Copyright 2024 Free Software Foundation, Inc. ++ ++ 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 . */ ++ ++#include ++ ++struct exec_type ++{ ++ int a; ++ int b; ++ int c; ++}; ++ ++volatile struct exec_type global_exec_var = { 0, 0, 0 }; ++ ++extern int foo (void); ++ ++void ++dump_core (void) ++{ ++ abort (); ++} ++ ++int ++main (void) ++{ ++ int res = foo (); ++ ++ res += global_exec_var.a; ++ res += global_exec_var.b; ++ res += global_exec_var.c; ++ ++ dump_core (); ++ ++ return res; ++} +diff --git a/gdb/testsuite/gdb.python/py-missing-objfile.exp b/gdb/testsuite/gdb.python/py-missing-objfile.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.python/py-missing-objfile.exp +@@ -0,0 +1,565 @@ ++# Copyright (C) 2024 Free Software Foundation, Inc. ++ ++# 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 . ++ ++load_lib gdb-python.exp ++ ++require allow_python_tests ++require {!is_remote host} ++ ++standard_testfile .c -lib.c ++ ++# Build the library. ++set libname ${testfile}-lib ++set libfile [standard_output_file $libname] ++if { [build_executable "build shlib" $libfile $srcfile2 \ ++ {debug shlib build-id}] == -1} { ++ return ++} ++ ++# Build the executable. ++set opts [list debug build-id shlib=${libfile}] ++if { [build_executable "build exec" $binfile $srcfile $opts] == -1} { ++ return ++} ++ ++# The cc-with-gnu-debuglink board will split the debug out into the ++# .debug directory. This test script relies on having GDB lookup the ++# objfile and debug via the build-id, which this test sets up. Trying ++# to do that, while also supporting the cc-with-gnu-debuglink board is ++# just too complicated. ++if {[file isdirectory [standard_output_file ".debug"]]} { ++ unsupported "split debug testing not supported" ++ return ++} ++ ++set remote_python_file \ ++ [gdb_remote_download host ${srcdir}/${subdir}/${testfile}.py] ++ ++# Generate a core file. ++set corefile [core_find $binfile {}] ++if {$corefile == ""} { ++ unsupported "core file not generated" ++ return 0 ++} ++ ++# Create a directory named DIRNAME for use as the ++# debug-file-directory. Populate the directory with links (based on ++# the build-ids) to each file in the list FILES. ++# ++# Return the full filename of DIRNAME on the host. ++proc setup_debugdir { dirname files } { ++ set debugdir [host_standard_output_file $dirname] ++ ++ # Create basic empty directory structure (in case FILES is empty). ++ remote_exec host "mkdir -p $debugdir/.build-id/" ++ ++ foreach file $files { ++ set build_id_filename [build_id_debug_filename_get $file ""] ++ ++ remote_exec host "mkdir -p $debugdir/[file dirname $build_id_filename]" ++ remote_exec host "ln -s $file $debugdir/$build_id_filename" ++ } ++ ++ return $debugdir ++} ++ ++# Query some symbols in the inferior to see if GDB managed to find the ++# executable (when EXEC_LOADED is true) and/or the library (when LIB_LOADED ++# is true). ++proc check_loaded_debug { exec_loaded lib_loaded } { ++ if { $exec_loaded } { ++ gdb_test "whatis global_exec_var" "^type = volatile struct exec_type" ++ ++ if { $lib_loaded } { ++ gdb_test "whatis global_lib_var" "^type = volatile struct lib_type" ++ } else { ++ gdb_test "whatis global_lib_var" \ ++ "^No symbol \"global_lib_var\" in current context\\." ++ } ++ } else { ++ gdb_test "whatis global_exec_var" \ ++ "^No symbol table is loaded\\. Use the \"file\" command\\." ++ gdb_test "whatis global_lib_var" \ ++ "^No symbol table is loaded\\. Use the \"file\" command\\." ++ } ++} ++ ++# Load the global corefile. The EXTRA_RE is checked for prior to GDB ++# announcing that the core-file has been loaded. ++proc load_core_file { {extra_re ".*"} } { ++ gdb_test "core-file $::corefile" \ ++ [multi_line \ ++ "$extra_re" \ ++ "Core was generated by \[^\r\n\]+" \ ++ "Program terminated with signal SIGABRT, Aborted\\." \ ++ "\[^\r\n\]+(?:\r\n\[^\r\n\]+)?"] \ ++ "loaded the core file" ++} ++ ++# Set the debug-file-directory to DIRNAME. ++proc set_debug_file_dir { dirname } { ++ gdb_test_no_output "set debug-file-directory $dirname" \ ++ "set debug-file-directory" ++} ++ ++# Restart GDB and load the support Python script. ++proc clean_restart_load_python {} { ++ clean_restart ++ gdb_test "source $::remote_python_file" "^Success" \ ++ "load python script" ++} ++ ++# For sanity, lets check that we can load the specify the executable ++# and then load the core-file the easy way. ++with_test_prefix "initial sanity check" { ++ clean_restart $binfile ++ load_core_file ++ check_loaded_debug true true ++} ++ ++# Move the executable and library into a location that the core-file ++# can't possibly know about. After this the only way GDB can track ++# down these files will be by looking in the debug-file-directory. ++set hidden_dir [host_standard_output_file "hidden"] ++set hidden_binfile "$hidden_dir/$testfile" ++set hidden_libfile "$hidden_dir/$libname" ++remote_exec host "mkdir -p $hidden_dir" ++remote_exec host "mv $libfile $hidden_libfile" ++remote_exec host "mv $binfile $hidden_binfile" ++ ++# If using the fission-dwp board then we'll have .dwp files that also ++# need to be moved. ++if {[remote_file host exists ${libfile}.dwp]} { ++ remote_exec host "mv ${libfile}.dwp ${hidden_libfile}.dwp" ++} ++ ++if {[remote_file host exists ${binfile}.dwp]} { ++ remote_exec host "mv ${binfile}.dwp ${hidden_binfile}.dwp" ++} ++ ++with_test_prefix "no objfiles, no debug-file-directory" { ++ clean_restart ++ load_core_file ++ check_loaded_debug false false ++} ++ ++# Setup some debug-file-directories. ++set debugdir_no_lib \ ++ [setup_debugdir "debugdir.no-lib" [list "$hidden_binfile"]] ++set debugdir_empty \ ++ [setup_debugdir "debugdir.empty" {}] ++set debugdir_all \ ++ [setup_debugdir "debugdir.all" [list "$hidden_libfile" \ ++ "$hidden_binfile"]] ++ ++with_test_prefix "no objfiles available" { ++ # Another sanity check that GDB can find the files via the ++ # debug-file-directory. ++ clean_restart ++ set_debug_file_dir $debugdir_empty ++ load_core_file ++ check_loaded_debug false false ++} ++ ++with_test_prefix "all objfiles available" { ++ # Another sanity check that GDB can find the files via the ++ # debug-file-directory. ++ set_debug_file_dir $debugdir_all ++ load_core_file ++ check_loaded_debug true true ++} ++ ++with_test_prefix "lib objfile missing" { ++ # Another sanity check that GDB can find the files via the ++ # debug-file-directory. ++ set_debug_file_dir $debugdir_no_lib ++ load_core_file ++ check_loaded_debug true false ++} ++ ++with_test_prefix "all objfiles missing, handler returns None" { ++ clean_restart_load_python ++ gdb_test_no_output \ ++ "python gdb.missing_objfile.register_handler(None, handler_obj)" \ ++ "register initial handler" ++ load_core_file ++ ++ check_loaded_debug false false ++ ++ # The handler should be called three times, once for the ++ # mapped-file, once for the core-file's exec, and once for the ++ # shared library. ++ gdb_test "python print(handler_obj.call_count)" "^3" \ ++ "check handler was called three times" ++} ++ ++with_test_prefix "lib objfile missing, handler returns None" { ++ # Reset handler_obj. ++ gdb_test_no_output "python handler_obj.set_mode(Mode.RETURN_NONE)" ++ ++ set_debug_file_dir $debugdir_no_lib ++ load_core_file ++ check_loaded_debug true false ++ ++ # The handler will be called twice, once when GDB tries to ++ # load the shared library during the memory-mapped file phase, ++ # then again for the shared library loading. ++ gdb_test "python print(handler_obj.call_count)" "^2" \ ++ "check handler was called three times" ++} ++ ++with_test_prefix "handler installs lib objfile" { ++ set build_id_filename [build_id_debug_filename_get \ ++ $hidden_libfile ""] ++ remote_exec host \ ++ "mkdir -p $debugdir_no_lib/[file dirname $build_id_filename]" ++ gdb_test_no_output "python handler_obj.set_mode(Mode.RETURN_TRUE, \ ++ \"$hidden_libfile\", \"$debugdir_no_lib/$build_id_filename\")" \ ++ "configure handler" ++ ++ load_core_file ++ check_loaded_debug true true ++ ++ # Cleanup so the test can be reproduced again later if needed. ++ remote_exec host "rm $debugdir_no_lib/$build_id_filename" ++} ++ ++with_test_prefix "handler points to lib objfile" { ++ set build_id_filename [build_id_debug_filename_get \ ++ $hidden_libfile ""] ++ remote_exec host \ ++ "mkdir -p $debugdir_no_lib/[file dirname $build_id_filename]" ++ gdb_test_no_output "python handler_obj.set_mode(Mode.RETURN_STRING, \ ++ \"$hidden_libfile\")" \ ++ "configure handler" ++ ++ load_core_file ++ check_loaded_debug true true ++ ++ # Cleanup so the test can be reproduced again later if needed. ++ remote_exec host "rm $debugdir_no_lib/$build_id_filename" ++ ++ # The handler will only have been called once when loading the ++ # memory-mapped file. GDB is smart enough to reuse the previously ++ # discovered BFD object as the shared library. ++ gdb_test "python print(handler_obj.call_count)" "^1" \ ++ "check good handler hasn't been called again" ++ ++ # Validate the filename and build-id arguments passed to the handler. ++ set expected_buildid [get_build_id $hidden_libfile] ++ gdb_test "python print(handler_last_buildid)" "^$expected_buildid" ++ gdb_test "python print(handler_last_filename)" \ ++ "^[string_to_regexp $libfile]" ++} ++ ++# Register another global handler, this one raises an exception. Reload the ++# core-file, the bad handler should be invoked first, which raises an ++# excetption, at which point GDB should skip further Python handlers. ++with_test_prefix "handler raises an exception" { ++ gdb_test_no_output \ ++ "python gdb.missing_objfile.register_handler(None, rhandler)" ++ ++ foreach_with_prefix exception_type {gdb.GdbError TypeError} { ++ gdb_test_no_output \ ++ "python rhandler.exception_type = $exception_type" ++ ++ # Load the core file. We expect the exception message to appear at ++ # least once in the output. ++ set re [string_to_regexp \ ++ "Python Exception : message"] ++ load_core_file "${re}.*" ++ ++ # Our original handler is still registered, but should not have been ++ # called again (as the exception occurs first). ++ gdb_test "python print(handler_obj.call_count)" "^1" \ ++ "check good handler hasn't been called again" ++ } ++} ++ ++# Re-start GDB. ++clean_restart_load_python ++ ++# Attempt to register a missing-debug-handler with NAME. The expectation is ++# that this should fail as NAME contains some invalid characters. ++proc check_bad_name {name} { ++ set name_re [string_to_regexp $name] ++ set re \ ++ [multi_line \ ++ "ValueError.*: invalid character '.' in handler name: $name_re" \ ++ "Error occurred in Python.*"] ++ ++ gdb_test "python register(\"$name\")" $re \ ++ "check that '$name' is not accepted" ++} ++ ++# We don't attempt to be exhaustive here, just check a few random examples ++# of invalid names. ++check_bad_name "!! Bad Name" ++check_bad_name "Bad Name" ++check_bad_name "(Bad Name)" ++check_bad_name "Bad \[Name\]" ++check_bad_name "Bad,Name" ++check_bad_name "Bad;Name" ++ ++# Check that there are no handlers registered. ++gdb_test_no_output "info missing-objfile-handlers" \ ++ "check no handlers are registered" ++ ++# Grab the current program space object, used for registering handler later. ++gdb_test_no_output "python pspace = gdb.selected_inferior().progspace" ++ ++# Now register some handlers. ++foreach hspec {{\"Foo\" None} ++ {\"-bar\" None} ++ {\"baz-\" pspace} ++ {\"abc-def\" pspace}} { ++ lassign $hspec name locus ++ gdb_test "python register($name, $locus)" ++} ++ ++with_test_prefix "all handlers enabled" { ++ gdb_test "info missing-objfile-handlers" \ ++ [multi_line \ ++ "Current Progspace:" \ ++ " abc-def" \ ++ " baz-" \ ++ "Global:" \ ++ " -bar" \ ++ " Foo"] ++ ++ set_debug_file_dir $debugdir_no_lib ++ load_core_file ++ ++ # As we perform two look ups, first for the mapped-file then for the ++ # shared library, each handler will be called twice. ++ gdb_test "python print(handler_call_log)" \ ++ [string_to_regexp {['abc-def', 'baz-', '-bar', 'Foo', 'abc-def', 'baz-', '-bar', 'Foo']}] ++ gdb_test_no_output "python handler_call_log = \[\]" \ ++ "reset call log" ++} ++ ++with_test_prefix "disable 'baz-'" { ++ gdb_test "disable missing-objfile-handler progspace baz-" \ ++ "^1 missing objfile handler disabled" ++ ++ gdb_test "info missing-objfile-handlers" \ ++ [multi_line \ ++ "Progspace \[^\r\n\]+:" \ ++ " abc-def" \ ++ " baz- \\\[disabled\\\]" \ ++ "Global:" \ ++ " -bar" \ ++ " Foo"] ++ ++ load_core_file ++ gdb_test "python print(handler_call_log)" \ ++ [string_to_regexp {['abc-def', '-bar', 'Foo', 'abc-def', '-bar', 'Foo']}] ++ gdb_test_no_output "python handler_call_log = \[\]" \ ++ "reset call log" ++} ++ ++with_test_prefix "disable 'Foo'" { ++ gdb_test "disable missing-objfile-handler .* Foo" \ ++ "^1 missing objfile handler disabled" ++ ++ gdb_test "info missing-objfile-handlers" \ ++ [multi_line \ ++ "Progspace \[^\r\n\]+:" \ ++ " abc-def" \ ++ " baz- \\\[disabled\\\]" \ ++ "Global:" \ ++ " -bar" \ ++ " Foo \\\[disabled\\\]"] ++ ++ load_core_file ++ gdb_test "python print(handler_call_log)" \ ++ [string_to_regexp {['abc-def', '-bar', 'abc-def', '-bar']}] ++ gdb_test_no_output "python handler_call_log = \[\]" \ ++ "reset call log" ++} ++ ++with_test_prefix "disable everything" { ++ gdb_test "disable missing-objfile-handler .* .*" \ ++ "^2 missing objfile handlers disabled" ++ ++ gdb_test "info missing-objfile-handlers" \ ++ [multi_line \ ++ "Progspace \[^\r\n\]+:" \ ++ " abc-def \\\[disabled\\\]" \ ++ " baz- \\\[disabled\\\]" \ ++ "Global:" \ ++ " -bar \\\[disabled\\\]" \ ++ " Foo \\\[disabled\\\]"] ++ ++ load_core_file ++ gdb_test "python print(handler_call_log)" \ ++ [string_to_regexp {[]}] ++ gdb_test_no_output "python handler_call_log = \[\]" \ ++ "reset call log" ++} ++ ++with_test_prefix "enable 'abc-def'" { ++ set re [string_to_regexp $hidden_binfile] ++ ++ gdb_test "enable missing-objfile-handler \"$re\" abc-def" \ ++ "^1 missing objfile handler enabled" \ ++ "enable missing-objfile-handler" ++ ++ gdb_test "info missing-objfile-handlers" \ ++ [multi_line \ ++ "Progspace \[^\r\n\]+:" \ ++ " abc-def" \ ++ " baz- \\\[disabled\\\]" \ ++ "Global:" \ ++ " -bar \\\[disabled\\\]" \ ++ " Foo \\\[disabled\\\]"] ++ ++ load_core_file ++ gdb_test "python print(handler_call_log)" \ ++ [string_to_regexp {['abc-def', 'abc-def']}] ++ gdb_test_no_output "python handler_call_log = \[\]" \ ++ "reset call log" ++} ++ ++with_test_prefix "enable global handlers" { ++ gdb_test "enable missing-objfile-handler global" \ ++ "^2 missing objfile handlers enabled" ++ ++ gdb_test "info missing-objfile-handlers" \ ++ [multi_line \ ++ "Progspace \[^\r\n\]+:" \ ++ " abc-def" \ ++ " baz- \\\[disabled\\\]" \ ++ "Global:" \ ++ " -bar" \ ++ " Foo"] ++ ++ load_core_file ++ gdb_test "python print(handler_call_log)" \ ++ [string_to_regexp {['abc-def', '-bar', 'Foo', 'abc-def', '-bar', 'Foo']}] ++ gdb_test_no_output "python handler_call_log = \[\]" \ ++ "reset call log" ++} ++ ++# Add handler_obj to the global handler list, and configure it to ++# return False. We should call all of the program space specific ++# handlers (which return None), and then call handler_obj from the ++# global list, which returns False, at which point we shouldn't call ++# anyone else. ++with_test_prefix "return False handler in global list" { ++ gdb_test "enable missing-objfile-handler progspace" \ ++ "^1 missing objfile handler enabled" ++ ++ gdb_test_no_output \ ++ "python gdb.missing_objfile.register_handler(None, handler_obj)" \ ++ "register handler_obj in global list" ++ ++ gdb_test "info missing-objfile-handlers" \ ++ [multi_line \ ++ "Progspace \[^\r\n\]+:" \ ++ " abc-def" \ ++ " baz-" \ ++ "Global:" \ ++ " handler" \ ++ " -bar" \ ++ " Foo"] ++ ++ gdb_test_no_output "python handler_obj.set_mode(Mode.RETURN_FALSE)" \ ++ "confirgure handler" ++ ++ load_core_file ++ gdb_test "python print(handler_call_log)" \ ++ [string_to_regexp {['abc-def', 'baz-', 'handler', 'abc-def', 'baz-', 'handler']}] ++ gdb_test_no_output "python handler_call_log = \[\]" \ ++ "reset call log" ++} ++ ++# Now add handler_obj to the current program space's handler list. We ++# use the same handler object here, that's fine. We should only see a ++# call to the first handler object in the call log. ++with_test_prefix "return False handler in progspace list" { ++ gdb_test_no_output \ ++ "python gdb.missing_objfile.register_handler(pspace, handler_obj)" \ ++ "register handler_obj in progspace list" ++ ++ gdb_test "info missing-objfile-handlers" \ ++ [multi_line \ ++ "Progspace \[^\r\n\]+:" \ ++ " handler" \ ++ " abc-def" \ ++ " baz-" \ ++ "Global:" \ ++ " handler" \ ++ " -bar" \ ++ " Foo"] ++ ++ load_core_file ++ gdb_test "python print(handler_call_log)" \ ++ [string_to_regexp {['handler', 'handler']}] ++ gdb_test_no_output "python handler_call_log = \[\]" \ ++ "reset call log" ++} ++ ++with_test_prefix "check handler replacement" { ++ # First, check we can have the same name appear in both program ++ # space and global lists without giving an error. ++ gdb_test_no_output "python register(\"Foo\", pspace)" ++ ++ gdb_test "info missing-objfile-handlers" \ ++ [multi_line \ ++ "Progspace \[^\r\n\]+:" \ ++ " Foo" \ ++ " handler" \ ++ " abc-def" \ ++ " baz-" \ ++ "Global:" \ ++ " handler" \ ++ " -bar" \ ++ " Foo"] ++ ++ # Now check that we get an error if we try to add a handler with ++ # the same name. ++ gdb_test "python gdb.missing_objfile.register_handler(pspace, log_handler(\"Foo\"))" \ ++ [multi_line \ ++ "RuntimeError.*: Handler Foo already exists\\." \ ++ "Error occurred in Python.*"] ++ ++ gdb_test "python gdb.missing_objfile.register_handler(handler=log_handler(\"Foo\"), locus=pspace)" \ ++ [multi_line \ ++ "RuntimeError.*: Handler Foo already exists\\." \ ++ "Error occurred in Python.*"] ++ ++ # And now try again, but this time with 'replace=True', we ++ # shouldn't get an error in this case. ++ gdb_test_no_output \ ++ "python gdb.missing_objfile.register_handler(pspace, log_handler(\"Foo\"), replace=True)" ++ ++ gdb_test_no_output \ ++ "python gdb.missing_objfile.register_handler(handler=log_handler(\"Foo\"), locus=None, replace=True)" ++ ++ # Now disable a handler and check we still need to use 'replace=True'. ++ gdb_test "disable missing-objfile-handler progspace Foo" \ ++ "^1 missing objfile handler disabled" ++ ++ gdb_test "python gdb.missing_objfile.register_handler(pspace, log_handler(\"Foo\"))" \ ++ [multi_line \ ++ "RuntimeError.*: Handler Foo already exists\\." \ ++ "Error occurred in Python.*"] \ ++ "still get an error when handler is disabled" ++ ++ gdb_test_no_output \ ++ "python gdb.missing_objfile.register_handler(pspace, log_handler(\"Foo\"), replace=True)" \ ++ "can replace a disabled handler" ++} +diff --git a/gdb/testsuite/gdb.python/py-missing-objfile.py b/gdb/testsuite/gdb.python/py-missing-objfile.py +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.python/py-missing-objfile.py +@@ -0,0 +1,167 @@ ++# Copyright (C) 2024 Free Software Foundation, Inc. ++ ++# 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 . ++ ++import shutil ++import os ++from enum import Enum ++ ++import gdb ++from gdb.missing_objfile import MissingObjfileHandler ++ ++# A global log that is filled in by instances of the LOG_HANDLER class ++# when they are called. ++handler_call_log = [] ++ ++# A global holding a string, the build-id of the last missing objfile ++# which triggered the 'handler' class below. This is set in the ++# __call__ method of the 'handler' class and then checked from the ++# expect script. ++handler_last_buildid = None ++ ++ ++# A global holding a string, the filename of the last missing objfile ++# which triggered the 'handler' class below. This is set in the ++# __call__ method of the 'handler' class and then checked from the ++# expect script. ++handler_last_filename = None ++ ++ ++# A helper function that makes some assertions about the arguments ++# passed to a MissingObjfileHandler.__call__() method. ++def check_args(pspace, buildid, filename): ++ assert type(filename) == str ++ assert filename != "" ++ assert type(pspace) == gdb.Progspace ++ assert type(buildid) == str ++ assert buildid != "" ++ ++ ++# Enum used to configure the 'handler' class from the test script. ++class Mode(Enum): ++ RETURN_NONE = 0 ++ RETURN_TRUE = 1 ++ RETURN_FALSE = 2 ++ RETURN_STRING = 3 ++ ++ ++# A missing objfile handler which can be configured to return each of ++# the different possible return types. ++class handler(MissingObjfileHandler): ++ def __init__(self): ++ super().__init__("handler") ++ self._call_count = 0 ++ self._mode = Mode.RETURN_NONE ++ ++ def __call__(self, pspace, buildid, filename): ++ global handler_call_log, handler_last_buildid, handler_last_filename ++ check_args(pspace, buildid, filename) ++ handler_call_log.append(self.name) ++ handler_last_buildid = buildid ++ handler_last_filename = filename ++ self._call_count += 1 ++ if self._mode == Mode.RETURN_NONE: ++ return None ++ ++ if self._mode == Mode.RETURN_TRUE: ++ shutil.copy(self._src, self._dest) ++ ++ # If we're using the fission-dwp board then there will ++ # also be a .dwp file that needs to be copied. ++ dwp_src = self._src + ".dwp" ++ if os.path.exists(dwp_src): ++ dwp_dest = self._dest + ".dwp" ++ shutil.copy(dwp_src, dwp_dest) ++ ++ return True ++ ++ if self._mode == Mode.RETURN_FALSE: ++ return False ++ ++ if self._mode == Mode.RETURN_STRING: ++ return self._dest ++ ++ assert False ++ ++ @property ++ def call_count(self): ++ """Return a count, the number of calls to __call__ since the last ++ call to set_mode. ++ """ ++ return self._call_count ++ ++ def set_mode(self, mode, *args): ++ self._call_count = 0 ++ self._mode = mode ++ ++ if mode == Mode.RETURN_NONE: ++ assert len(args) == 0 ++ return ++ ++ if mode == Mode.RETURN_TRUE: ++ assert len(args) == 2 ++ self._src = args[0] ++ self._dest = args[1] ++ return ++ ++ if mode == Mode.RETURN_FALSE: ++ assert len(args) == 0 ++ return ++ ++ if mode == Mode.RETURN_STRING: ++ assert len(args) == 1 ++ self._dest = args[0] ++ return ++ ++ assert False ++ ++ ++# A missing objfile handler which raises an exception. The type of ++# exception to be raised is configured from the test script. ++class exception_handler(MissingObjfileHandler): ++ def __init__(self): ++ super().__init__("exception_handler") ++ self.exception_type = None ++ ++ def __call__(self, pspace, buildid, filename): ++ global handler_call_log ++ check_args(pspace, buildid, filename) ++ handler_call_log.append(self.name) ++ assert self.exception_type is not None ++ raise self.exception_type("message") ++ ++ ++# A very simple logging missing objfile handler. Always returns None ++# so that GDB will try any other registered handlers, but first logs ++# the name of this handler into the global HANDLER_CALL_LOG, which can ++# then be checked from the test script. ++class log_handler(MissingObjfileHandler): ++ def __call__(self, pspace, buildid, filename): ++ global handler_call_log ++ check_args(pspace, buildid, filename) ++ handler_call_log.append(self.name) ++ return None ++ ++ ++# A basic helper function, this keeps lines shorter in the TCL script. ++def register(name, locus=None): ++ gdb.missing_objfile.register_handler(locus, log_handler(name)) ++ ++ ++# Create instances of the handlers, but don't install any. We install ++# these as needed from the TCL script. ++rhandler = exception_handler() ++handler_obj = handler() ++ ++print("Success") +diff --git a/gdb/testsuite/gdb.server/build-id-seqno.c b/gdb/testsuite/gdb.server/build-id-seqno.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.server/build-id-seqno.c +@@ -0,0 +1,22 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++ Copyright 2024 Free Software Foundation, Inc. ++ ++ 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 . */ ++ ++int ++main (void) ++{ ++ return 0; ++} +diff --git a/gdb/testsuite/gdb.server/build-id-seqno.exp b/gdb/testsuite/gdb.server/build-id-seqno.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.server/build-id-seqno.exp +@@ -0,0 +1,198 @@ ++# This testcase is part of GDB, the GNU debugger. ++# ++# Copyright 2024 Free Software Foundation, Inc. ++# ++# 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 . ++ ++# Setup a .build-id/ based debug directory containing multiple entries ++# for the same build-id, with each entry given a different sequence ++# number. ++# ++# Ensure that GDB will scan over broken symlinks for the same build-id ++# (but different sequence number) to find later working symlinks. ++# ++# This test places the build-id files within a directory next to where ++# gdbserver is started, and places a relative address in the ++# debug-file-directory, in this way we require GDB to find the debug ++# information via gdbserver. ++ ++require {!is_remote host} ++ ++load_lib gdbserver-support.exp ++ ++standard_testfile ++ ++if {[build_executable "failed to prepare" $testfile $srcfile] == -1} { ++ return -1 ++} ++ ++# Split out BINFILE.debug. Remove debug from BINFILE. ++if {[gdb_gnu_strip_debug $binfile] != 0} { ++ return -1 ++} ++ ++# Get the '.build-id/xx/xxx...xxx' part of the filename. ++set build_id_filename [build_id_debug_filename_get $binfile] ++ ++# Hide (rename) BINFILE.debug, this should ensure GDB can't find it ++# directly but needs to look for the build-id based file in the debug ++# directory. ++set hidden_debuginfo [standard_output_file "hidden_$testfile.debug"] ++remote_exec build "mv ${binfile}.debug $hidden_debuginfo" ++ ++# A filename that doesn't exist. Some symlinks will point at this ++# file. ++set missing_debuginfo "missing_debuginfo" ++ ++# Helper called from gdb_finish when the 'target' is remote. Ensure the ++# debug directory we create is deleted. ++proc cleanup_remote_target {} { ++ remote_exec target "rm -fr debug/" ++} ++ ++if { ![is_remote target] } { ++ set gdbserver_dir [standard_output_file "gdbserver-dir"]/ ++} else { ++ lappend gdb_finish_hooks cleanup_remote_target ++ set gdbserver_dir "" ++} ++ ++# Copy files to the target (if needed). ++set target_binfile [gdb_remote_download target $binfile] ++set target_debuginfo [gdb_remote_download target $hidden_debuginfo] ++ ++# Setup the debug information on the target. ++set debugdir "${gdbserver_dir}debug" ++remote_exec target \ ++ "mkdir -p $debugdir/[file dirname $build_id_filename]" ++remote_exec target \ ++ "ln -sf $target_debuginfo $debugdir/$build_id_filename" ++ ++# Start GDB and load global BINFILE. If DEBUGINFO_FILE is not the ++# empty string then this contains the '.build-id/xx/xxx....xxxx' part ++# of the filename which we expect GDB to read from the remote target. ++# If DEBUGINFO_FILE is the empty string then we don't expect GDB to ++# find any debug information. ++proc load_binfile_check_debug_is_found { debuginfo_file testname } { ++ with_test_prefix "$testname" { ++ with_timeout_factor 5 { ++ # Probing for .build-id based debug files on remote ++ # targets uses the vFile:stat packet by default, though ++ # there is a work around that avoids this which can be ++ # used if GDB is connected to an older gdbserver without ++ # 'stat' support. ++ # ++ # Check the work around works by disabling use of the ++ # vFile:stat packet. ++ foreach_with_prefix stat_pkt {auto off} { ++ clean_restart ++ ++ gdb_test_no_output "set debug-file-directory debug" \ ++ "set debug-file-directory" ++ ++ gdb_test_no_output "set sysroot target:" ++ ++ gdb_test "set remote hostio-stat-packet $stat_pkt" ++ ++ # Make sure we're disconnected, in case we're testing with an ++ # extended-remote board, therefore already connected. ++ gdb_test "disconnect" ".*" ++ ++ # Start gdbserver. This needs to be done after starting GDB. When ++ # gdbserver is running local to GDB, start gdbserver in a sub-directory, ++ # this prevents GDB from finding the debug information itself. ++ if { ![is_remote target] } { ++ with_cwd $::gdbserver_dir { ++ set res [gdbserver_start "" $::target_binfile] ++ } ++ } else { ++ set res [gdbserver_start "" $::target_binfile] ++ } ++ set gdbserver_protocol [lindex $res 0] ++ set gdbserver_gdbport [lindex $res 1] ++ ++ # Connect to gdbserver. The output will be placed into the global ++ # GDB_TARGET_REMOTE_CMD_MSG, and we'll match against this below. ++ gdb_assert {[gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport] == 0} \ ++ "connect to gdbserver" ++ ++ if { $debuginfo_file ne "" } { ++ gdb_assert { [regexp "Reading symbols from target:debug/[string_to_regexp $debuginfo_file]\\.\\.\\." \ ++ $::gdb_target_remote_cmd_msg] } \ ++ "debuginfo was read via build-id" ++ gdb_assert { [regexp "Reading debug/[string_to_regexp $debuginfo_file] from remote target\\.\\.\\." \ ++ $::gdb_target_remote_cmd_msg] } \ ++ "debuginfo was read from remote target" ++ } else { ++ gdb_assert { [regexp "\\(No debugging symbols found in \[^\r\n\]+/$::testfile\\)" \ ++ $::gdb_target_remote_cmd_msg] } ++ } ++ } ++ } ++ } ++} ++ ++# Return a copy of FILENAME, which should end '.debug', with NUMBER ++# added, e.g. add_seqno 1 "foo.debug" --> "foo.1.debug". ++proc add_seqno { number filename } { ++ return [regsub "\.debug\$" $filename ".${number}.debug"] ++} ++ ++# Precompute sequence numbered build-id filenames. ++set build_id_1_filename [add_seqno 1 $build_id_filename] ++set build_id_2_filename [add_seqno 2 $build_id_filename] ++set build_id_3_filename [add_seqno 3 $build_id_filename] ++ ++load_binfile_check_debug_is_found $build_id_filename \ ++ "find debuginfo with a single build-id file" ++ ++remote_exec target "ln -fs $target_debuginfo \ ++ $debugdir/$build_id_1_filename" ++remote_exec target "ln -fs $target_debuginfo \ ++ $debugdir/$build_id_2_filename" ++remote_exec target "ln -fs $target_debuginfo \ ++ $debugdir/$build_id_3_filename" ++ ++load_binfile_check_debug_is_found $build_id_filename \ ++ "find debuginfo with 4 build-id files" ++ ++remote_exec target "ln -fs $missing_debuginfo $debugdir/$build_id_filename" ++ ++load_binfile_check_debug_is_found $build_id_1_filename \ ++ "find debuginfo, first build-id file is bad" ++ ++remote_exec target "ln -fs $missing_debuginfo \ ++ $debugdir/$build_id_1_filename" ++remote_exec target "ln -fs $missing_debuginfo \ ++ $debugdir/$build_id_3_filename" ++ ++load_binfile_check_debug_is_found $build_id_2_filename \ ++ "find debuginfo, first 2 build-id files are bad" ++ ++remote_exec target "ln -fs $missing_debuginfo \ ++ $debugdir/$build_id_2_filename" ++ ++load_binfile_check_debug_is_found "" \ ++ "cannot find debuginfo, all build-id files are bad" ++ ++remote_exec target "ln -fs $target_debuginfo \ ++ $debugdir/$build_id_3_filename" ++ ++load_binfile_check_debug_is_found $build_id_3_filename \ ++ "find debuginfo, last build-id file is good" ++ ++remote_exec target "rm -f $debugdir/$build_id_1_filename" ++ ++load_binfile_check_debug_is_found "" \ ++ "cannot find debuginfo, file with seqno 1 is missing" +diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp +--- a/gdb/testsuite/lib/dwarf.exp ++++ b/gdb/testsuite/lib/dwarf.exp +@@ -2993,25 +2993,32 @@ namespace eval Dwarf { + + proc _note {type name hexdata} { + set namelen [expr [string length $name] + 1] ++ set datalen [expr [string length $hexdata] / 2] + + # Name size. + _op .4byte $namelen + # Data size. +- _op .4byte [expr [string length $hexdata] / 2] ++ _op .4byte $datalen + # Type. + _op .4byte $type + # The name. + _op .ascii [_quote $name] +- # Alignment. ++ # Alignment (to 4-byte boundary). + set align 2 + set total [expr {($namelen + (1 << $align) - 1) & -(1 << $align)}] + for {set i $namelen} {$i < $total} {incr i} { +- _op .byte 0 ++ _op .byte 0 padding + } + # The data. + foreach {a b} [split $hexdata {}] { + _op .byte 0x$a$b + } ++ # Alignment (to 4-byte boundary). ++ set align 2 ++ set total [expr {($datalen + (1 << $align) - 1) & -(1 << $align)}] ++ for {set i $datalen} {$i < $total} {incr i} { ++ _op .byte 0 padding ++ } + } + + # Emit a note section holding the given build-id. +diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp +--- a/gdb/testsuite/lib/gdb.exp ++++ b/gdb/testsuite/lib/gdb.exp +@@ -5337,6 +5337,7 @@ proc quote_for_host { args } { + # debug information + # - text_segment=addr: Tell the linker to place the text segment at ADDR. + # - build-id: Ensure the final binary includes a build-id. ++# - no-build-id: Ensure the final binary does not include a build-id. + # - column-info/no-column-info: Enable/Disable generation of column table + # information. + # +@@ -5448,6 +5449,18 @@ proc gdb_compile {source dest type options} { + lappend new_options "additional_flags=-Wl,--build-id" + } + ++ # If the 'no-build-id' option is used then disable the build-id. ++ if {[lsearch -exact $options no-build-id] > 0} { ++ lappend new_options "additional_flags=-Wl,--build-id=none" ++ } ++ ++ # Sanity check. If both 'build-id' and 'no-build-id' are used ++ # then what is expected from us! ++ if {[lsearch -exact $options build-id] > 0 ++ && [lsearch -exact $options no-build-id] > 0} { ++ error "cannot use build-id and no-build-id options" ++ } ++ + # Treating .c input files as C++ is deprecated in Clang, so + # explicitly force C++ language. + if { !$getting_compiler_info +@@ -8144,21 +8157,25 @@ proc get_build_id { filename } { + + # Return the build-id hex string (usually 160 bits as 40 hex characters) + # converted to the form: .build-id/ab/cdef1234...89.debug ++# ++# The '.debug' suffix can be changed by passing the SUFFIX argument. ++# + # Return "" if no build-id found. +-proc build_id_debug_filename_get { filename } { ++proc build_id_debug_filename_get { filename {suffix ".debug"} } { + set data [get_build_id $filename] + if { $data == "" } { + return "" + } + regsub {^..} $data {\0/} data +- return ".build-id/${data}.debug" ++ return ".build-id/${data}${suffix}" + } + + # DEST should be a file compiled with debug information. This proc +-# creates two new files DEST.debug which contains the debug +-# information extracted from DEST, and DEST.stripped, which is a copy +-# of DEST with the debug information removed. A '.gnu_debuglink' +-# section will be added to DEST.stripped that points to DEST.debug. ++# creates DEST.debug which contains the debug information extracted ++# from DEST, and DEST is updated with the debug information removed. ++# ++# By default a '.gnu_debuglink' section will be added to DEST that ++# points to DEST.debug. + # + # If ARGS is passed, it is a list of optional flags. The currently + # supported flags are: +@@ -8166,7 +8183,7 @@ proc build_id_debug_filename_get { filename } { + # - no-main : remove the symbol entry for main from the separate + # debug file DEST.debug, + # - no-debuglink : don't add the '.gnu_debuglink' section to +-# DEST.stripped. ++# DEST. + # + # Function returns zero on success. Function will return non-zero failure code + # on some targets not supporting separate debug info (such as i386-msdos). +@@ -8225,20 +8242,26 @@ proc gdb_gnu_strip_debug { dest args } { + # Unless the "no-debuglink" flag is passed, then link the two + # previous output files together, adding the .gnu_debuglink + # section to the stripped_file, containing a pointer to the +- # debug_file, save the new file in dest. ++ # debug_file. + if {[lsearch -exact $args "no-debuglink"] == -1} { +- set result [catch "exec $objcopy_program --add-gnu-debuglink=${debug_file} ${stripped_file} ${dest}" output] ++ set result [catch "exec $objcopy_program --add-gnu-debuglink=${debug_file} ${stripped_file} ${stripped_file}-tmp" output] + verbose "result is $result" + verbose "output is $output" + if {$result == 1} { + return 1 + } ++ file delete "${stripped_file}" ++ file rename "${stripped_file}-tmp" "${stripped_file}" + } + + # Workaround PR binutils/10802: + # Preserve the 'x' bit also for PIEs (Position Independent Executables). +- set perm [file attributes ${stripped_file} -permissions] +- file attributes ${dest} -permissions $perm ++ set perm [file attributes ${dest} -permissions] ++ file attributes ${stripped_file} -permissions $perm ++ ++ # Move the stripped_file back into dest. ++ file delete ${dest} ++ file rename ${stripped_file} ${dest} + + return 0 + } +diff --git a/gdbserver/hostio.cc b/gdbserver/hostio.cc +--- a/gdbserver/hostio.cc ++++ b/gdbserver/hostio.cc +@@ -486,6 +486,42 @@ handle_fstat (char *own_buf, int *new_packet_len) + write_enn (own_buf); + } + ++static void ++handle_stat (char *own_buf, int *new_packet_len) ++{ ++ int bytes_sent; ++ char *p; ++ struct stat st; ++ struct fio_stat fst; ++ char filename[HOSTIO_PATH_MAX]; ++ ++ p = own_buf + strlen ("vFile:stat:"); ++ ++ if (require_filename (&p, filename) ++ || require_end (p)) ++ { ++ hostio_packet_error (own_buf); ++ return; ++ } ++ ++ if (lstat (filename, &st) == -1) ++ { ++ hostio_error (own_buf); ++ return; ++ } ++ ++ host_to_fileio_stat (&st, &fst); ++ ++ bytes_sent = hostio_reply_with_data (own_buf, ++ (char *) &fst, sizeof (fst), ++ new_packet_len); ++ ++ /* If the response does not fit into a single packet, do not attempt ++ to return a partial response, but simply fail. */ ++ if (bytes_sent < sizeof (fst)) ++ write_enn (own_buf); ++} ++ + static void + handle_close (char *own_buf) + { +@@ -603,6 +639,8 @@ handle_vFile (char *own_buf, int packet_len, int *new_packet_len) + handle_pwrite (own_buf, packet_len); + else if (startswith (own_buf, "vFile:fstat:")) + handle_fstat (own_buf, new_packet_len); ++ else if (startswith (own_buf, "vFile:stat:")) ++ handle_stat (own_buf, new_packet_len); + else if (startswith (own_buf, "vFile:close:")) + handle_close (own_buf); + else if (startswith (own_buf, "vFile:unlink:")) +diff --git a/gdbsupport/pathstuff.cc b/gdbsupport/pathstuff.cc +--- a/gdbsupport/pathstuff.cc ++++ b/gdbsupport/pathstuff.cc +@@ -198,11 +198,17 @@ path_join (gdb::array_view paths) + { + const char *path = paths[i]; + +- if (i > 0) +- gdb_assert (strlen (path) == 0 || !IS_ABSOLUTE_PATH (path)); +- +- if (!ret.empty () && !IS_DIR_SEPARATOR (ret.back ())) +- ret += '/'; ++ if (!ret.empty ()) ++ { ++ /* If RET doesn't already end with a separator then add one. */ ++ if (!IS_DIR_SEPARATOR (ret.back ())) ++ ret += '/'; ++ ++ /* Now that RET ends with a separator, ignore any at the start of ++ PATH. */ ++ while (IS_DIR_SEPARATOR (path[0])) ++ ++path; ++ } + + ret.append (path); + } +diff --git a/gdbsupport/pathstuff.h b/gdbsupport/pathstuff.h +--- a/gdbsupport/pathstuff.h ++++ b/gdbsupport/pathstuff.h +@@ -64,8 +64,10 @@ extern const char *child_path (const char *parent, const char *child); + + /* Join elements in PATHS into a single path. + +- The first element can be absolute or relative. All the others must be +- relative. */ ++ The first element can be absolute or relative. Only a single directory ++ separator will be placed between elements of PATHS, if one element ends ++ with a directory separator, or an element starts with a directory ++ separator, then these will be collapsed into a single separator. */ + + extern std::string path_join (gdb::array_view paths); + diff --git a/gdb-build-fix-gdbserver-linux-aarch64-low.cc-build.patch b/gdb-build-fix-gdbserver-linux-aarch64-low.cc-build.patch deleted file mode 100644 index 8edcbe7..0000000 --- a/gdb-build-fix-gdbserver-linux-aarch64-low.cc-build.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0397481ff25b76d43b123f3d51828982ceb92834 Mon Sep 17 00:00:00 2001 -From: Mark Wielaard -Date: Fri, 3 May 2024 15:17:42 +0200 -Subject: [PATCH] [gdb/build] Fix gdbserver/linux-aarch64-low.cc build - -Commit 0ee25f97d21e ("Fix regression on aarch64-linux gdbserver") -removed the last use of i in gdbserver/linux-aarch64-low.cc -(aarch64_target::low_stopped_data_address). Breaking the build on -aarch64 with: - -gdbserver/linux-aarch64-low.cc: In member function ?virtual CORE_ADDR aarch64_target::low_stopped_data_address()?: -gdbserver/linux-aarch64-low.cc:557:12: error: unused variable ?i? [-Werror=unused-variable] - 557 | int pid, i; - | ^ -cc1plus: all warnings being treated as errors - -Fix this by removing the variable i completely. - -Fixes: 0ee25f97d21e ("Fix regression on aarch64-linux gdbserver") ---- - gdbserver/linux-aarch64-low.cc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gdbserver/linux-aarch64-low.cc b/gdbserver/linux-aarch64-low.cc -index 14346b89822..ce0029b885f 100644 ---- a/gdbserver/linux-aarch64-low.cc -+++ b/gdbserver/linux-aarch64-low.cc -@@ -555,7 +555,7 @@ CORE_ADDR - aarch64_target::low_stopped_data_address () - { - siginfo_t siginfo; -- int pid, i; -+ int pid; - struct aarch64_debug_reg_state *state; - - pid = lwpid_of (current_thread); - -base-commit: b33811a85ff53af77cdad995ad8cb50431c8c362 --- -2.35.3 - diff --git a/gdb-build-fix-unused-var-in-corelow.c.patch b/gdb-build-fix-unused-var-in-corelow.c.patch new file mode 100644 index 0000000..f4dbd0f --- /dev/null +++ b/gdb-build-fix-unused-var-in-corelow.c.patch @@ -0,0 +1,46 @@ +From c179fc89cf61d3d9c58db571d709969bfa566289 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Tue, 10 Sep 2024 10:08:29 +0200 +Subject: [PATCH] [gdb/build] Fix unused var in corelow.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +On x86_64-linux, with gcc 7.5.0 and CFLAGS/CXXFLAGS="-O0 -g -Wall" I ran into +a build breaker: +... +gdb/corelow.c: In member function ‘void mapped_file_info::add(const char*, const char*, const char*, std::vector&&, const bfd_build_id*)’: +gdb/corelow.c:1822:27: error: unused variable ‘it’ [-Werror=unused-variable] + const auto [it, inserted] + ^ +... + +Fix this by dropping the variable it. + +Tested on x86_64-linux. + +Reviewed-By: Lancelot Six +--- + gdb/corelow.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/gdb/corelow.c b/gdb/corelow.c +index 1884075ec67..30b98c2865d 100644 +--- a/gdb/corelow.c ++++ b/gdb/corelow.c +@@ -1872,8 +1872,8 @@ mapped_file_info::add (const char *soname, + parsed, we group the build-id information based on the file name. As + a consequence, we should see each EXPECTED_FILENAME value exactly + once. This means that each insertion should always succeed. */ +- const auto [it, inserted] +- = m_filename_to_build_id_map.emplace (expected_filename, build_id); ++ const auto inserted ++ = m_filename_to_build_id_map.emplace (expected_filename, build_id).second; + gdb_assert (inserted); + + /* Setup the reverse build-id to file name map. */ + +base-commit: a7d9abecbc24e3d68746ea5b905eba11913980e1 +-- +2.43.0 + diff --git a/gdb-bz634108-solib_address.patch b/gdb-bz634108-solib_address.patch deleted file mode 100644 index bc7ef8a..0000000 --- a/gdb-bz634108-solib_address.patch +++ /dev/null @@ -1,41 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Fedora GDB patches -Date: Fri, 27 Oct 2017 21:07:50 +0200 -Subject: gdb-bz634108-solib_address.patch - -;; Verify GDB Python built-in function gdb.solib_address exists (BZ # 634108). -;;=fedoratest - -Fix gdb.solib_address (fix by Phil Muldoon). - -s/solib_address/solib_name/ during upstreaming. - -diff --git a/gdb/testsuite/gdb.python/rh634108-solib_address.exp b/gdb/testsuite/gdb.python/rh634108-solib_address.exp -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.python/rh634108-solib_address.exp -@@ -0,0 +1,24 @@ -+# Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. -+ -+# 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 . -+ -+# https://bugzilla.redhat.com/show_bug.cgi?id=634108 -+ -+gdb_exit -+gdb_start -+ -+# Skip all tests if Python scripting is not enabled. -+if { [skip_python_tests] } { continue } -+ -+gdb_test "python print (gdb.solib_name(-1))" "None" "gdb.solib_name exists" diff --git a/gdb-catchpoint-re-set.patch b/gdb-catchpoint-re-set.patch new file mode 100644 index 0000000..b8e9eda --- /dev/null +++ b/gdb-catchpoint-re-set.patch @@ -0,0 +1,575 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Andrew Burgess +Date: Wed, 14 Aug 2024 15:16:46 +0100 +Subject: gdb-catchpoint-re-set.patch + + ;; Backport upstream commit a92e943014f to fix rhbz2304296. + +gdb: implement ::re_set method for catchpoint class + +It is possible to attach a condition to a catchpoint. This can't be +done when the catchpoint is created, but can be done with the +'condition' command, this is documented in the GDB manual: + + You can also use the 'if' keyword with the 'watch' command. The + 'catch' command does not recognize the 'if' keyword; 'condition' is the + only way to impose a further condition on a catchpoint. + +A GDB crash was reported against Fedora GDB where a user had attached +a condition to a catchpoint and then restarted the inferior. When the +catchpoint was hit GDB would immediately segfault. I was able to +reproduce the failure on upstream GDB: + + (gdb) file ./some/binary + (gdb) catch syscall write + (gdb) run + ... + Catchpoint 1 (returned from syscall write), 0x00007ffff7b594a7 in write () from /lib64/libc.so.6 + (gdb) condition 1 $_streq((char *) $rsi, "foobar") == 0 + (gdb) run + ... + Fatal signal: Segmentation fault + ... + +What happened here is that on the system in question we had debug +information available for both the main application and also for +libc. + +When the condition was attached GDB was stopped inside libc and as the +debug information was available GDB found a reference to the 'char' +type (for the cast) inside libc's debug information. + +When the inferior is restarted GDB discards all of the objfiles +associated with shared libraries, and this includes libc. As such the +'char' type, which is objfile owned, is discarded and the reference to +it from the catchpoint's condition expression becomes invalid. + +Now, if it were a breakpoint instead of a catchpoint, what would +happen is that after the shared library objfiles had been discarded +we'd call the virtual breakpoint::re_set method on the breakpoint, and +this would update the breakpoint's condition expression. This is +because user breakpoints are actually instances of the code_breakpoint +class and the code_breakpoint::re_set method contains the code to +recompute the breakpoint's condition expression. + +However, catchpoints are instances of the catchpoint class which +inherits from the base breakpoint class. The catchpoint class does +not override breakpoint::re_set, and breakpoint::re_set is empty! + +The consequence of this is that catchpoint condition expressions are +never recomputed, and the dangling pointer to the now deleted, objfile +owned type 'char' is left around, and, when the catchpoint is hit, the +invalid pointer is used when GDB tries to evaluate the condition +expression. + +In this commit I have implemented catchpoint::re_set. This is pretty +simple and just recomputes the condition expression as you'd expect. +If the condition doesn't evaluate then the catchpoint is marked as +disabled_by_cond. + +I have also made breakpoint::re_set pure virtual. With the addition +of catchpoint::re_set every sub-class of breakpoint now implements the +::re_set method, and if new sub-classes are added in the future I +think that they _must_ implement ::re_set in order to avoid this +problem. As such falling back to an empty breakpoint::re_set doesn't +seem helpful. + +For testing I have not relied on stopping in libc and having libc +debug information available, this doesn't seem like a good idea for +the GDB testsuite. Instead I create a (rather pointless) condition +check that uses a type defined only within a shared library. When the +inferior is restarted the catchpoint will temporarily be marked as +disabled_by_cond (due to the type not being available), but once the +shared library is loaded again the catchpoint will be re-enabled. +Without the fixes above then the same crashing behaviour can be +observed. + +One point of note: the dangling pointer of course exposes undefined +behaviour, with no guarantee of a crash. Though a crash is what I +usually see I have see GDB throw random errors from the expression +evaluation code, and once, I saw no problem at all! If you recompile +GDB with the address sanitizer, or run under valgrind, then the bug +will be exposed every time. + +After fixing this bug I checked bugzilla and found PR gdb/29960 which +is the same bug. I was able to reproduce the bug before this commit, +and after this commit GDB is no longer crashing. + +Before: + + (gdb) file /tmp/hello.x + Reading symbols from /tmp/hello.x... + (gdb) run + Starting program: /tmp/hello.x + Hello World + [Inferior 1 (process 1101855) exited normally] + (gdb) catch syscall 1 + Catchpoint 1 (syscall 'write' [1]) + (gdb) condition 1 write.fd == 1 + (gdb) run + Starting program: /tmp/hello.x + + Fatal signal: Segmentation fault + ... + +And after: + + (gdb) file /tmp/hello.x + Reading symbols from /tmp/hello.x... + (gdb) run + Starting program: /tmp/hello.x + Hello World + Args: ( 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ) + [Inferior 1 (process 1102373) exited normally] + (gdb) catch syscall 1 + Catchpoint 1 (syscall 'write' [1]) + (gdb) condition 1 write.fd == 1 + (gdb) r + Starting program: /tmp/hello.x + Error in testing condition for breakpoint 1: + Attempt to extract a component of a value that is not a structure. + + Catchpoint 1 (call to syscall write), 0x00007ffff7eb94a7 in write () + from /lib64/libc.so.6 + (gdb) ptype write + type = () + (gdb) + +Notice we get the error now when the condition fails to evaluate. +This seems reasonable given that 'write' will be a function, and +indeed the final 'ptype' shows that it's a function, not a struct. + +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29960 + +Reviewed-By: Tom de Vries + +diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c +--- a/gdb/breakpoint.c ++++ b/gdb/breakpoint.c +@@ -8146,6 +8146,60 @@ catchpoint::catchpoint (struct gdbarch *gdbarch, bool temp, + pspace = current_program_space; + } + ++/* See breakpoint.h. */ ++ ++void ++catchpoint::re_set () ++{ ++ /* All catchpoints are associated with a specific program_space. */ ++ gdb_assert (pspace != nullptr); ++ ++ /* Catchpoints have a single dummy location. */ ++ gdb_assert (locations ().size () == 1); ++ bp_location &bl = m_locations.front (); ++ ++ if (cond_string == nullptr) ++ { ++ /* It shouldn't be possible to have a parsed condition expression ++ cached on this location if the catchpoint doesn't have a condition ++ string set. */ ++ gdb_assert (bl.cond == nullptr); ++ ++ /* Nothing to re-compute, and the catchpoint cannot change. */ ++ return; ++ } ++ ++ bool previous_disabled_by_cond = bl.disabled_by_cond; ++ ++ /* Start by marking the location disabled and discarding the previously ++ computed condition expression. Now if we get an exception, even if ++ it's a quit exception, we'll leave the location disabled and there ++ will be no (possibly invalid) expression cached. */ ++ bl.disabled_by_cond = true; ++ bl.cond = nullptr; ++ ++ const char *s = cond_string.get (); ++ try ++ { ++ switch_to_program_space_and_thread (pspace); ++ ++ bl.cond = parse_exp_1 (&s, bl.address, block_for_pc (bl.address), ++ nullptr); ++ bl.disabled_by_cond = false; ++ } ++ catch (const gdb_exception_error &e) ++ { ++ /* Any exception thrown must be from either the parse_exp_1 or ++ earlier in the try block. As such the following two asserts ++ should be true. */ ++ gdb_assert (bl.disabled_by_cond); ++ gdb_assert (bl.cond == nullptr); ++ } ++ ++ if (previous_disabled_by_cond != bl.disabled_by_cond) ++ notify_breakpoint_modified (this); ++} ++ + /* Notify interpreters and observers that breakpoint B was created. */ + + static void +diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h +--- a/gdb/breakpoint.h ++++ b/gdb/breakpoint.h +@@ -702,11 +702,10 @@ struct breakpoint : public intrusive_list_node + + /* Reevaluate a breakpoint. This is necessary after symbols change + (e.g., an executable or DSO was loaded, or the inferior just +- started). */ +- virtual void re_set () +- { +- /* Nothing to re-set. */ +- } ++ started). This is pure virtual as, at a minimum, each sub-class must ++ recompute any cached condition expressions based off of the ++ cond_string member variable. */ ++ virtual void re_set () = 0; + + /* Insert the breakpoint or watchpoint or activate the catchpoint. + Return 0 for success, 1 if the breakpoint, watchpoint or +@@ -1120,6 +1119,10 @@ struct catchpoint : public breakpoint + catchpoint (struct gdbarch *gdbarch, bool temp, const char *cond_string); + + ~catchpoint () override = 0; ++ ++ /* If the catchpoint has a condition set then recompute the cached ++ expression within the single dummy location. */ ++ void re_set () override; + }; + + +diff --git a/gdb/testsuite/gdb.base/reset-catchpoint-cond-lib.c b/gdb/testsuite/gdb.base/reset-catchpoint-cond-lib.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/reset-catchpoint-cond-lib.c +@@ -0,0 +1,76 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++ Copyright 2024 Free Software Foundation, Inc. ++ ++ 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 . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* This type is used by GDB. */ ++struct lib_type ++{ ++ int a; ++ int b; ++ int c; ++}; ++ ++/* Ensure the type above is used. */ ++volatile struct lib_type global_lib_object = { 1, 2, 3 }; ++ ++/* This pointer is checked by GDB. */ ++volatile void *opaque_ptr = 0; ++ ++void ++lib_func_test_syscall (void) ++{ ++ puts ("Inside library\n"); ++ fflush (stdout); ++} ++ ++static void ++sig_handler (int signo) ++{ ++ /* Nothing. */ ++} ++ ++void ++lib_func_test_signal (void) ++{ ++ signal (SIGUSR1, sig_handler); ++ ++ kill (getpid (), SIGUSR1); ++} ++ ++void ++lib_func_test_fork (void) ++{ ++ pid_t pid = fork (); ++ assert (pid != -1); ++ ++ if (pid == 0) ++ { ++ /* Child: just exit. */ ++ exit (0); ++ } ++ ++ /* Parent. */ ++ waitpid (pid, NULL, 0); ++} +diff --git a/gdb/testsuite/gdb.base/reset-catchpoint-cond.c b/gdb/testsuite/gdb.base/reset-catchpoint-cond.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/reset-catchpoint-cond.c +@@ -0,0 +1,50 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++ Copyright 2024 Free Software Foundation, Inc. ++ ++ 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 . */ ++ ++extern void lib_func_test_syscall (void); ++extern void lib_func_test_signal (void); ++extern void lib_func_test_fork (void); ++ ++/* We use this to perform some filler work. */ ++volatile int global_var = 0; ++ ++/* Just somewhere for GDB to put a breakpoint. */ ++void ++breakpt_before_exit (void) ++{ ++ /* Nothing. */ ++} ++ ++int ++main (void) ++{ ++#if defined TEST_SYSCALL ++ lib_func_test_syscall (); ++#elif defined TEST_SIGNAL ++ lib_func_test_signal (); ++#elif defined TEST_FORK ++ lib_func_test_fork (); ++#else ++# error compile with suitable -DTEST_xxx macro defined ++#endif ++ ++ ++global_var; ++ ++ breakpt_before_exit (); ++ ++ return 0; ++} +diff --git a/gdb/testsuite/gdb.base/reset-catchpoint-cond.exp b/gdb/testsuite/gdb.base/reset-catchpoint-cond.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/reset-catchpoint-cond.exp +@@ -0,0 +1,169 @@ ++# Copyright 2024 Free Software Foundation, Inc. ++ ++# 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 . ++ ++# Test that the condition for a catchpoint is correctly reset after ++# shared libraries are unloaded, as happens when an inferior is ++# restarted. ++# ++# If this is not done then, when the catchpoint is hit on the second ++# run, we'll evaluate the parsed expression from the first run, which ++# might include references to types owned by the now deleted objfile ++# (for the shared library loaded in the first run). ++# ++# This scripts tests a number of different catchpoint types. Inside ++# GDB these are all sub-classes of the 'catchpoint' type, which is ++# where the fix for the above issue resides, so all catchpoint types ++# should work correctly. ++ ++standard_testfile .c -lib.c ++ ++set libfile $binfile-lib.so ++ ++set pyfile [gdb_remote_download host ${srcdir}/${subdir}/${testfile}.py] ++ ++if {[build_executable "build shared library" $libfile $srcfile2 \ ++ {debug shlib}] == -1} { ++ return ++} ++ ++# Depending on whether or not libc debug info is installed, when we ++# hit a syscall catchpoint inside libc there might be a source line ++# included in the output. ++# ++# This regexp will match an optional line and can be added to the ++# expected catchpoint output to ignore the (possibly missing) source ++# line. ++set libc_src_line_re "(?:\r\n\[^\r\n\]+)?" ++ ++# Check the Python bp_modified_list and then reset the list back to ++# empty. TESTNAME is just a string. BP_NUM is a list of breakpoint ++# numbers that are expected to appear (in the given order) in the ++# bp_modified_list. ++ ++proc check_modified_bp_list { testname bp_num } { ++ if { [allow_python_tests] } { ++ set expected [join $bp_num ", "] ++ ++ gdb_test "python print(bp_modified_list)" "\\\[$expected\\\]" \ ++ $testname ++ gdb_test_no_output -nopass "python bp_modified_list=\[\]" \ ++ "reset bp_modified_list after $testname" ++ } ++} ++ ++# Build an executable and run tests on 'catch MODE'. ++ ++proc run_test { mode } { ++ set exec_name ${::binfile}-${mode} ++ ++ set macro TEST_[string toupper $mode] ++ ++ if {[build_executable "build test executable" $exec_name $::srcfile \ ++ [list debug shlib=$::libfile additional_flags=-D${macro}]] == -1} { ++ return ++ } ++ ++ clean_restart $exec_name ++ gdb_load_shlib $::libfile ++ ++ if {![runto_main]} { ++ return ++ } ++ ++ if { $mode eq "syscall" } { ++ gdb_test "catch syscall write" \ ++ "Catchpoint $::decimal \\(syscall 'write' \[^)\]+\\)" ++ set catch_re "call to syscall write" ++ } elseif { $mode eq "signal" } { ++ gdb_test "catch signal SIGUSR1" \ ++ "Catchpoint $::decimal \\(signal SIGUSR1\\)" ++ set catch_re "signal SIGUSR1" ++ } elseif { $mode eq "fork" } { ++ gdb_test "catch fork" \ ++ "Catchpoint $::decimal \\(fork\\)" ++ set catch_re "forked process $::decimal" ++ } else { ++ error "unknown mode $mode" ++ } ++ set cp_num [get_integer_valueof "\$bpnum" "*UNKNOWN*"] ++ ++ gdb_breakpoint "breakpt_before_exit" ++ ++ gdb_test "continue" \ ++ "Catchpoint ${cp_num} \[^\r\n\]+$::libc_src_line_re" ++ ++ if { [allow_python_tests] } { ++ gdb_test_no_output "source $::pyfile" "import python scripts" ++ check_modified_bp_list \ ++ "check b/p modified observer has not yet triggered" {} ++ } ++ ++ with_test_prefix "with false condition" { ++ gdb_test_no_output "condition $cp_num ((struct lib_type *) opaque_ptr) != 0" \ ++ "set catchpoint condition" ++ ++ check_modified_bp_list \ ++ "catchpoint modified once by setting condition" \ ++ [list $cp_num] ++ ++ gdb_run_cmd ++ gdb_test "" [multi_line \ ++ "Breakpoint $::decimal, main \\(\\) \[^\r\n\]+" \ ++ "$::decimal\\s+\[^\r\n\]+"] ++ ++ check_modified_bp_list "catchpoint modified twice at startup" \ ++ [list $cp_num $cp_num "$::decimal"] ++ ++ gdb_test "continue" \ ++ [multi_line \ ++ "Breakpoint $::decimal, breakpt_before_exit \\(\\) at \[^\r\n\]+" \ ++ "$::decimal\\s+\[^\r\n\]+"] \ ++ "continue to breakpt_before_exit" ++ } ++ ++ # Check the bp_modified_list against '.*'. We don't care at this ++ # point what's in the list (nothing relevant has happened since we ++ # last checked), but this has the side effect of clearing the list. ++ check_modified_bp_list "clear bp modified list" { .* } ++ ++ with_test_prefix "with true condition" { ++ gdb_test_no_output "condition $cp_num ((struct lib_type *) opaque_ptr) == 0" \ ++ "set catchpoint condition" ++ ++ check_modified_bp_list \ ++ "catchpoint modified once by setting condition" \ ++ [list $cp_num] ++ ++ gdb_run_cmd ++ gdb_test "" [multi_line \ ++ "Breakpoint $::decimal, main \\(\\) \[^\r\n\]+" \ ++ "$::decimal\\s+\[^\r\n\]+"] ++ ++ check_modified_bp_list "catchpoint modified twice at startup" \ ++ [list $cp_num $cp_num "$::decimal"] ++ ++ gdb_test "continue" \ ++ "Catchpoint $cp_num \\($catch_re\\), \[^\r\n\]+$::libc_src_line_re" \ ++ "continue until catchpoint hit" ++ ++ check_modified_bp_list "catchpoint modified again when hit" \ ++ [list $cp_num] ++ } ++} ++ ++# Run the tests. ++foreach_with_prefix mode { syscall signal fork } { ++ run_test $mode ++} +diff --git a/gdb/testsuite/gdb.base/reset-catchpoint-cond.py b/gdb/testsuite/gdb.base/reset-catchpoint-cond.py +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.base/reset-catchpoint-cond.py +@@ -0,0 +1,21 @@ ++# Copyright (C) 2024 Free Software Foundation, Inc. ++ ++# 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 . ++ ++bp_modified_list = [] ++ ++def bp_modified(bp): ++ bp_modified_list.append (bp.number) ++ ++gdb.events.breakpoint_modified.connect(bp_modified) diff --git a/gdb-cli-print-at_hwcap3-and-at_hwcap4.patch b/gdb-cli-print-at_hwcap3-and-at_hwcap4.patch new file mode 100644 index 0000000..81e2fa7 --- /dev/null +++ b/gdb-cli-print-at_hwcap3-and-at_hwcap4.patch @@ -0,0 +1,41 @@ +From 442c996a4de355459eeabd280649ddb282d7de41 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Sat, 25 Jan 2025 10:08:53 +0100 +Subject: [PATCH 2/2] [gdb/cli] Print AT_HWCAP3 and AT_HWCAP4 + +PR cli/32590 +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32590 +--- + gdb/auxv.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/gdb/auxv.c b/gdb/auxv.c +index 8cda0b687b4..bb4c7ea70a0 100644 +--- a/gdb/auxv.c ++++ b/gdb/auxv.c +@@ -453,6 +453,13 @@ fprint_auxv_entry (struct ui_file *file, const char *name, + } + } + ++#ifndef AT_HWCAP3 ++#define AT_HWCAP3 29 ++#endif ++#ifndef AT_HWCAP4 ++#define AT_HWCAP4 30 ++#endif ++ + /* The default implementation of gdbarch_print_auxv_entry. */ + + void +@@ -495,6 +502,8 @@ default_print_auxv_entry (struct gdbarch *gdbarch, struct ui_file *file, + AUXV_FORMAT_STR); + TAG (AT_RANDOM, _("Address of 16 random bytes"), AUXV_FORMAT_HEX); + TAG (AT_HWCAP2, _("Extension of AT_HWCAP"), AUXV_FORMAT_HEX); ++ TAG (AT_HWCAP3, _("Extension of AT_HWCAP"), AUXV_FORMAT_HEX); ++ TAG (AT_HWCAP4, _("Extension of AT_HWCAP"), AUXV_FORMAT_HEX); + TAG (AT_RSEQ_FEATURE_SIZE, _("rseq supported feature size"), + AUXV_FORMAT_DEC); + TAG (AT_RSEQ_ALIGN, _("rseq allocation alignment"), +-- +2.43.0 + diff --git a/gdb-core-open-vdso-warning.patch b/gdb-core-open-vdso-warning.patch deleted file mode 100644 index cc9910a..0000000 --- a/gdb-core-open-vdso-warning.patch +++ /dev/null @@ -1,58 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Fedora GDB patches -Date: Fri, 27 Oct 2017 21:07:50 +0200 -Subject: gdb-core-open-vdso-warning.patch - -;; Fix GNU/Linux core open: Can't read pathname for load map: Input/output error. -;; Fix regression of undisplayed missing shared libraries caused by a fix for. -;;=fedoratest: It should be in glibc: libc-alpha: <20091004161706.GA27450@.*> - -http://sourceware.org/ml/gdb-patches/2009-10/msg00142.html -Subject: [patch] Fix GNU/Linux core open: Can't read pathname for load map: Input/output error. - -[ New patch variant. ] - -commit 7d760051ffb8a23cdc51342d4e6243fbc462f73f -Author: Ulrich Weigand -Date: Wed Sep 25 11:52:50 2013 +0000 - -diff --git a/gdb/testsuite/gdb.base/solib-symbol.exp b/gdb/testsuite/gdb.base/solib-symbol.exp ---- a/gdb/testsuite/gdb.base/solib-symbol.exp -+++ b/gdb/testsuite/gdb.base/solib-symbol.exp -@@ -27,6 +27,7 @@ set testfile "solib-symbol-main" - set srcfile ${srcdir}/${subdir}/${testfile}.c - set binfile [standard_output_file ${testfile}] - set bin_flags [list debug shlib=${binfile_lib}] -+set executable ${testfile} - - if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $lib_flags] != "" - || [gdb_compile ${srcfile} ${binfile} executable $bin_flags] != "" } { -@@ -61,4 +62,28 @@ gdb_test "br foo2" \ - "Breakpoint.*: foo2. .2 locations..*" \ - "foo2 in mdlib" - -+# Test GDB warns for shared libraris which have not been found. -+ -+gdb_test "info sharedlibrary" "/${libname}.*" -+ -+clean_restart ${executable} -+gdb_breakpoint "main" -+gdb_run_cmd -+set test "no warning for missing libraries" -+gdb_test_multiple "" $test { -+ -re "warning: Could not load shared library symbols for \[0-9\]+ libraries,.*\r\n$gdb_prompt $" { -+ fail $test -+ } -+ -re "Breakpoint \[0-9\]+, main .*\r\n$gdb_prompt $" { -+ pass $test -+ } -+} -+ -+clean_restart ${executable} -+gdb_test_no_output "set solib-absolute-prefix /doESnotEXIST" -+gdb_breakpoint "main" -+gdb_run_cmd -+gdb_test "" "warning: Could not load shared library symbols for \[0-9\]+ libraries,.*\r\nBreakpoint \[0-9\]+, main .*" \ -+ "warning for missing libraries" -+ - gdb_exit diff --git a/gdb-doc-fix-gdb.unwinder-docs.patch b/gdb-doc-fix-gdb.unwinder-docs.patch new file mode 100644 index 0000000..b0f878e --- /dev/null +++ b/gdb-doc-fix-gdb.unwinder-docs.patch @@ -0,0 +1,61 @@ +From b57066d1eaafab3100a8d7d788feba5802c409b7 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Mon, 27 Jan 2025 10:33:28 +0100 +Subject: [PATCH] [gdb/doc] Fix gdb.unwinder docs + +When building gdb with an older makeinfo (4.13), I run into: +... +gdb/doc/python.texi:3015: warning: `(' follows defined name \ + `gdb.unwinder.Unwinder.__init__' instead of whitespace. +gdb/doc/python.texi:3041: warning: `(' follows defined name \ + `gdb.unwinder.FrameId.__init__' instead of whitespace. +... + +The warnings are related to these two lines: +... +@defun gdb.unwinder.Unwinder.__init__(name) + ... +@defun gdb.unwinder.FrameId.__init__(sp, pc, special = @code{None}) +... + +Indeed, when checking the command and variable index, we can see that it +contains an incorrect entry: +... + gdb.unwinder.FrameId.__init__(sp,: Unwinding Frames in Python +... + +Fix this by adding a space before the left parenthesis. + +Tested by rebuilding the documentation and checking the command and variable +index. +--- + gdb/doc/python.texi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi +index e49cc580b1b..58904298c71 100644 +--- a/gdb/doc/python.texi ++++ b/gdb/doc/python.texi +@@ -3011,7 +3011,7 @@ unwinders can derive, though it is not required that unwinders derive + from this class, so long as any user created unwinder has the required + @code{name} and @code{enabled} attributes. + +-@defun gdb.unwinder.Unwinder.__init__(name) ++@defun gdb.unwinder.Unwinder.__init__ (name) + The @var{name} is a string used to reference this unwinder within some + @value{GDBN} commands (@pxref{Managing Registered Unwinders}). + @end defun +@@ -3037,7 +3037,7 @@ most cases this class will be sufficient. + + @code{gdb.unwinder.FrameId} has the following method: + +-@defun gdb.unwinder.FrameId.__init__(sp, pc, special = @code{None}) ++@defun gdb.unwinder.FrameId.__init__ (sp, pc, special = @code{None}) + The @var{sp} and @var{pc} arguments are required and should be either + a @code{gdb.Value} object, or an integer. + + +base-commit: fe0e6edbcb65ab5eca50c1a0ad8ddc9844f8ea98 +-- +2.43.0 + diff --git a/gdb-doc-fix-qisaddresstagged-anchor.patch b/gdb-doc-fix-qisaddresstagged-anchor.patch new file mode 100644 index 0000000..e97af24 --- /dev/null +++ b/gdb-doc-fix-qisaddresstagged-anchor.patch @@ -0,0 +1,41 @@ +From c23182d85ad9b5b6a45ba74993de55eac00a71bc Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Mon, 27 Jan 2025 11:22:12 +0100 +Subject: [PATCH] [gdb/doc] Fix qIsAddressTagged anchor + +When building gdb with an older makeinfo (4.13), I run into: +... +gdb/doc/gdb.texinfo:44159: @anchor expected braces. +gdb/doc/gdb.texinfo:44159: ` {qIsAddressTagged} +... + +This is related to this line: +... +@anchor {qIsAddressTagged} +... + +Fix this by removing the space before the left brace. + +Tested by rebuilding the documentation. +--- + gdb/doc/gdb.texinfo | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo +index 6b08838862c..97508863776 100644 +--- a/gdb/doc/gdb.texinfo ++++ b/gdb/doc/gdb.texinfo +@@ -44156,7 +44156,7 @@ tags found in the requested memory range. + @cindex check if a given address is in a memory tagged region + @cindex @samp{qIsAddressTagged} packet + @item qIsAddressTagged:@var{address} +-@anchor {qIsAddressTagged} ++@anchor{qIsAddressTagged} + Check if address @var{address} is in a memory tagged region; if it is, it's + said to be @dfn{tagged}. The target is responsible for checking it, as this + is architecture-specific. + +base-commit: 3e2d8d7edd244dd5a82588c3e7145c47c7b539ab +-- +2.43.0 + diff --git a/gdb-doc-fix-standard-replies-xref.patch b/gdb-doc-fix-standard-replies-xref.patch new file mode 100644 index 0000000..39e16df --- /dev/null +++ b/gdb-doc-fix-standard-replies-xref.patch @@ -0,0 +1,44 @@ +From 2004e74e0e28ed0b762d98380972b1e6984b9c46 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Tue, 28 Jan 2025 08:01:46 +0100 +Subject: [PATCH] [gdb/doc] Fix "Standard Replies" xref + +When building gdb with an older makeinfo (4.13), I run into: +... +gdb/doc/gdb.texinfo:42613: warning: `.' or `,' must follow @xref, not `f'. +... + +This is related to this line: +... +@xref{Standard Replies} for standard error responses, and how to +respond indicating a command is not supported. +... + +Fix this by adding a comma. + +Tested by rebuilding the docs. + +Reviewed-By: Eli Zaretskii +Co-Authored-By: Eli Zaretskii +--- + gdb/doc/gdb.texinfo | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo +index e5d562c00b4..0bfe6be6126 100644 +--- a/gdb/doc/gdb.texinfo ++++ b/gdb/doc/gdb.texinfo +@@ -42610,7 +42610,7 @@ seven repeats (@samp{$}) can be expanded using a repeat count of only + five (@samp{"}). For example, @samp{00000000} can be encoded as + @samp{0*"00}. + +-@xref{Standard Replies} for standard error responses, and how to ++@xref{Standard Replies}, for standard error responses, and how to + respond indicating a command is not supported. + + In describing packets (commands and responses), each description has a + +base-commit: 7992b582e5a55bf2fd64f2f94b854d335c36c6a5 +-- +2.43.0 + diff --git a/gdb-exp-fix-cast-handling-for-indirection.patch b/gdb-exp-fix-cast-handling-for-indirection.patch deleted file mode 100644 index e174e2d..0000000 --- a/gdb-exp-fix-cast-handling-for-indirection.patch +++ /dev/null @@ -1,150 +0,0 @@ -From b96d3adafdb636898913710ec40ee86647665ae8 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Fri, 3 May 2024 09:37:19 +0200 -Subject: [PATCH 24/48] [gdb/exp] Fix cast handling for indirection - -Consider a test-case compiled without debug info, containing: -... -char a = 'a'; - -char * -a_loc (void) -{ - return &a; -} -... - -We get: -... -(gdb) p (char)*a_loc () -Cannot access memory at address 0x10 -... - -There's a bug in unop_ind_base_operation::evaluate that evaluates -"(char)*a_loc ()" the same as: -... -(gdb) p (char)*(char)a_loc () -Cannot access memory at address 0x10 -... - -Fix this by instead doing: -... -(gdb) p (char)*a_loc () -'a_loc' has unknown return type; cast the call to its declared return type -... - -Tested on x86_64-linux. - -PR exp/31693 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31693 ---- - gdb/expop.h | 5 +-- - gdb/testsuite/gdb.base/cast-indirection.c | 31 ++++++++++++++++ - gdb/testsuite/gdb.base/cast-indirection.exp | 41 +++++++++++++++++++++ - 3 files changed, 74 insertions(+), 3 deletions(-) - create mode 100644 gdb/testsuite/gdb.base/cast-indirection.c - create mode 100644 gdb/testsuite/gdb.base/cast-indirection.exp - -diff --git a/gdb/expop.h b/gdb/expop.h -index 25769d5b810..25d50fe00d0 100644 ---- a/gdb/expop.h -+++ b/gdb/expop.h -@@ -1513,9 +1513,8 @@ class unop_ind_base_operation - struct expression *exp, - enum noside noside) override - { -- if (expect_type != nullptr && expect_type->code () == TYPE_CODE_PTR) -- expect_type = check_typedef (expect_type)->target_type (); -- value *val = std::get<0> (m_storage)->evaluate (expect_type, exp, noside); -+ value *val -+ = std::get<0> (m_storage)->evaluate (nullptr, exp, noside); - return eval_op_ind (expect_type, exp, noside, val); - } - -diff --git a/gdb/testsuite/gdb.base/cast-indirection.c b/gdb/testsuite/gdb.base/cast-indirection.c -new file mode 100644 -index 00000000000..d59c66ead35 ---- /dev/null -+++ b/gdb/testsuite/gdb.base/cast-indirection.c -@@ -0,0 +1,31 @@ -+/* This testcase is part of GDB, the GNU debugger. -+ -+ Copyright 2024 Free Software Foundation, Inc. -+ -+ 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 . */ -+ -+char a = 'a'; -+ -+char * -+a_loc (void) -+{ -+ return &a; -+} -+ -+int -+main (void) -+{ -+ int res = *a_loc () == 'a'; -+ return !res; -+} -diff --git a/gdb/testsuite/gdb.base/cast-indirection.exp b/gdb/testsuite/gdb.base/cast-indirection.exp -new file mode 100644 -index 00000000000..f1fe4302d27 ---- /dev/null -+++ b/gdb/testsuite/gdb.base/cast-indirection.exp -@@ -0,0 +1,41 @@ -+# Copyright (C) 2024 Free Software Foundation, Inc. -+ -+# 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 . -+ -+# Check that "p (char)*a_loc ()" is handled as "p (char)*(char *)a_loc ()". -+ -+standard_testfile -+ -+if { [prepare_for_testing "failed to prepare" $testfile $srcfile \ -+ {nodebug}] == -1} { -+ return -1 -+} -+ -+if ![runto_main] { -+ return -1 -+} -+ -+gdb_test "p a_loc ()" \ -+ "'a_loc' has unknown return type; cast the call to its declared return type" -+ -+gdb_test "p *a_loc ()" \ -+ "'a_loc' has unknown return type; cast the call to its declared return type" -+ -+gdb_test "p *(char *)a_loc ()" " = 97 'a'" -+ -+gdb_test "p (char)*(char *)a_loc ()" " = 97 'a'" -+ -+# Regression test for PR31693. -+gdb_test "p (char)*a_loc ()" \ -+ "'a_loc' has unknown return type; cast the call to its declared return type" --- -2.35.3 - diff --git a/gdb-exp-fix-gdb.fortran-intrinsics.exp-fail-on-arm.patch b/gdb-exp-fix-gdb.fortran-intrinsics.exp-fail-on-arm.patch new file mode 100644 index 0000000..4ab4cd3 --- /dev/null +++ b/gdb-exp-fix-gdb.fortran-intrinsics.exp-fail-on-arm.patch @@ -0,0 +1,232 @@ +From 1e295ef5fa3a5a89e9ee08d6e60d971ddb9e6e46 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Wed, 31 Jul 2024 13:11:48 +0200 +Subject: [PATCH 13/46] [gdb/exp] Fix gdb.fortran/intrinsics.exp fail on arm + +When running test-case gdb.fortran/intrinsics.exp on arm-linux, I get: +... +(gdb) p cmplx (4,4,16)^M +/home/linux/gdb/src/gdb/f-lang.c:1002: internal-error: eval_op_f_cmplx: \ + Assertion `kind_arg->code () == TYPE_CODE_COMPLEX' failed.^M +A problem internal to GDB has been detected,^M +further debugging may prove unreliable.^M +----- Backtrace -----^M +FAIL: gdb.fortran/intrinsics.exp: p cmplx (4,4,16) (GDB internal error) +... + +The problem is that 16-byte floats are unsupported: +... +$ gfortran test.f90 +test.f90:2:17: + + 2 | REAL(kind=16) :: foo = 1 + | 1 +Error: Kind 16 not supported for type REAL at (1) +... +and consequently we end up with a builtin_real_s16 and builtin_complex_s16 with +code TYPE_CODE_ERROR. + +Fix this by bailing out asap when encountering such a type. + +Without this patch we're able to do the rather useless: +... +(gdb) ptype real*16 +type = real*16 +(gdb) ptype real_16 +type = real*16 +... +but with this patch we get: +... +(gdb) ptype real*16 +unsupported kind 16 for type real*4 +(gdb) ptype real_16 +unsupported type real*16 +... + +Tested on arm-linux. + +PR fortran/30537 +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30537 +--- + gdb/f-exp.y | 39 +++++++++++++++++------- + gdb/testsuite/gdb.fortran/intrinsics.exp | 8 +++-- + gdb/testsuite/gdb.fortran/type-kinds.exp | 22 ++++++++++--- + gdb/testsuite/gdb.fortran/types.exp | 19 +++++++++++- + 4 files changed, 70 insertions(+), 18 deletions(-) + +diff --git a/gdb/f-exp.y b/gdb/f-exp.y +index bdf9c32a81b..259f274d341 100644 +--- a/gdb/f-exp.y ++++ b/gdb/f-exp.y +@@ -754,7 +754,11 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */ + | REAL_S8_KEYWORD + { $$ = parse_f_type (pstate)->builtin_real_s8; } + | REAL_S16_KEYWORD +- { $$ = parse_f_type (pstate)->builtin_real_s16; } ++ { $$ = parse_f_type (pstate)->builtin_real_s16; ++ if ($$->code () == TYPE_CODE_ERROR) ++ error (_("unsupported type %s"), ++ TYPE_SAFE_NAME ($$)); ++ } + | COMPLEX_KEYWORD + { $$ = parse_f_type (pstate)->builtin_complex; } + | COMPLEX_S4_KEYWORD +@@ -762,7 +766,11 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */ + | COMPLEX_S8_KEYWORD + { $$ = parse_f_type (pstate)->builtin_complex_s8; } + | COMPLEX_S16_KEYWORD +- { $$ = parse_f_type (pstate)->builtin_complex_s16; } ++ { $$ = parse_f_type (pstate)->builtin_complex_s16; ++ if ($$->code () == TYPE_CODE_ERROR) ++ error (_("unsupported type %s"), ++ TYPE_SAFE_NAME ($$)); ++ } + | SINGLE PRECISION + { $$ = parse_f_type (pstate)->builtin_real;} + | DOUBLE PRECISION +@@ -1156,12 +1164,9 @@ push_kind_type (LONGEST val, struct type *type) + type_stack->push (tp_kind); + } + +-/* Called when a type has a '(kind=N)' modifier after it, for example +- 'character(kind=1)'. The BASETYPE is the type described by 'character' +- in our example, and KIND is the integer '1'. This function returns a +- new type that represents the basetype of a specific kind. */ ++/* Helper function for convert_to_kind_type. */ + static struct type * +-convert_to_kind_type (struct type *basetype, int kind) ++convert_to_kind_type_1 (struct type *basetype, int kind) + { + if (basetype == parse_f_type (pstate)->builtin_character) + { +@@ -1211,13 +1216,25 @@ convert_to_kind_type (struct type *basetype, int kind) + return parse_f_type (pstate)->builtin_integer_s8; + } + +- error (_("unsupported kind %d for type %s"), +- kind, TYPE_SAFE_NAME (basetype)); +- +- /* Should never get here. */ + return nullptr; + } + ++/* Called when a type has a '(kind=N)' modifier after it, for example ++ 'character(kind=1)'. The BASETYPE is the type described by 'character' ++ in our example, and KIND is the integer '1'. This function returns a ++ new type that represents the basetype of a specific kind. */ ++static struct type * ++convert_to_kind_type (struct type *basetype, int kind) ++{ ++ struct type *res = convert_to_kind_type_1 (basetype, kind); ++ ++ if (res == nullptr || res->code () == TYPE_CODE_ERROR) ++ error (_("unsupported kind %d for type %s"), ++ kind, TYPE_SAFE_NAME (basetype)); ++ ++ return res; ++} ++ + struct f_token + { + /* The string to match against. */ +diff --git a/gdb/testsuite/gdb.fortran/intrinsics.exp b/gdb/testsuite/gdb.fortran/intrinsics.exp +index 60c79f956dc..060bb53db97 100644 +--- a/gdb/testsuite/gdb.fortran/intrinsics.exp ++++ b/gdb/testsuite/gdb.fortran/intrinsics.exp +@@ -112,10 +112,14 @@ gdb_test "ptype cmplx (4,4)" "= complex\\*4" + gdb_test "p cmplx (-14,-4)" "= \\(-14,-4\\)" + gdb_test "p cmplx (4,4,4)" "\\(4,4\\)" + gdb_test "p cmplx (4,4,8)" "\\(4,4\\)" +-gdb_test "p cmplx (4,4,16)" "\\(4,4\\)" ++set re_unsupported_kind_16 \ ++ [string_to_regexp "unsupported kind 16 for type complex*4"] ++gdb_test "p cmplx (4,4,16)" \ ++ ([string_to_regexp " = (4,4)"]|$re_unsupported_kind_16) + gdb_test "ptype cmplx (4,4,4)" "= complex\\*4" + gdb_test "ptype cmplx (4,4,8)" "= complex\\*8" +-gdb_test "ptype cmplx (4,4,16)" "= complex\\*16" ++gdb_test "ptype cmplx (4,4,16)" \ ++ ([string_to_regexp " = complex*16"]|$re_unsupported_kind_16) + + gdb_test "p cmplx (4,4,1)" "unsupported kind 1 for type complex\\*4" + gdb_test "p cmplx (4,4,-1)" "unsupported kind -1 for type complex\\*4" +diff --git a/gdb/testsuite/gdb.fortran/type-kinds.exp b/gdb/testsuite/gdb.fortran/type-kinds.exp +index ab5f19f97a4..a6f2aa4e870 100644 +--- a/gdb/testsuite/gdb.fortran/type-kinds.exp ++++ b/gdb/testsuite/gdb.fortran/type-kinds.exp +@@ -43,12 +43,20 @@ proc test_basic_parsing_of_type_kinds {} { + test_cast_1_to_type_kind "complex" "" "\\(1,0\\)" "8" + test_cast_1_to_type_kind "complex" "4" "\\(1,0\\)" "8" + test_cast_1_to_type_kind "complex" "8" "\\(1,0\\)" "16" +- test_cast_1_to_type_kind "complex" "16" "\\(1,0\\)" "32" ++ set re_unsupported_kind \ ++ [string_to_regexp "unsupported kind 16 for type complex*4"] ++ test_cast_1_to_type_kind "complex" "16" \ ++ [string_to_regexp (1,0)]|$re_unsupported_kind \ ++ 32|$re_unsupported_kind + + test_cast_1_to_type_kind "real" "" "1" "4" + test_cast_1_to_type_kind "real" "4" "1" "4" + test_cast_1_to_type_kind "real" "8" "1" "8" +- test_cast_1_to_type_kind "real" "16" "1" "16" ++ set re_unsupported_kind \ ++ [string_to_regexp "unsupported kind 16 for type real*4"] ++ test_cast_1_to_type_kind "real" "16" \ ++ 1|$re_unsupported_kind \ ++ 16|$re_unsupported_kind + + test_cast_1_to_type_kind "logical" "" "\\.TRUE\\." "4" + test_cast_1_to_type_kind "logical" "1" "\\.TRUE\\." "1" +@@ -83,11 +91,17 @@ proc test_old_star_type_sizes {} { + + gdb_test "p ((complex*4) 1)" " = \\(1,0\\)" + gdb_test "p ((complex*8) 1)" " = \\(1,0\\)" +- gdb_test "p ((complex*16) 1)" " = \\(1,0\\)" ++ set re_unsupported_kind \ ++ [string_to_regexp "unsupported kind 16 for type complex*4"] ++ gdb_test "p ((complex*16) 1)" \ ++ [string_to_regexp " = (1,0)"]|$re_unsupported_kind + + gdb_test "p ((real*4) 1)" " = 1" + gdb_test "p ((real*8) 1)" " = 1" +- gdb_test "p ((real*16) 1)" " = 1" ++ set re_unsupported_kind \ ++ [string_to_regexp "unsupported kind 16 for type real*4"] ++ gdb_test "p ((real*16) 1)" \ ++ "( = 1|$re_unsupported_kind)" + + gdb_test "p ((logical*1) 1)" " = \\.TRUE\\." + gdb_test "p ((logical*4) 1)" " = \\.TRUE\\." +diff --git a/gdb/testsuite/gdb.fortran/types.exp b/gdb/testsuite/gdb.fortran/types.exp +index 83b109869e6..edbf5abee97 100644 +--- a/gdb/testsuite/gdb.fortran/types.exp ++++ b/gdb/testsuite/gdb.fortran/types.exp +@@ -94,7 +94,24 @@ proc test_primitive_types_known {} { + # While TYPE_KIND is allowed as input, GDB will always return the + # Fortran notation TYPE*KIND + regsub -all "_" $type "\*" type_res +- gdb_test "ptype $type" [string_to_regexp "type = $type_res"] ++ set re [string_to_regexp "type = $type_res"] ++ switch $type { ++ real*16 - complex*16 { ++ regexp {^[^*_]*} $type base ++ set re_unsupported \ ++ [string_to_regexp \ ++ "unsupported kind 16 for type $base*4"] ++ set re ($re|$re_unsupported) ++ } ++ real_16 - complex_16 { ++ set re_unsupported \ ++ [string_to_regexp \ ++ "unsupported type $type_res"] ++ set re ($re|$re_unsupported) ++ } ++ } ++ ++ gdb_test "ptype $type" $re + } + } + +-- +2.43.0 + diff --git a/gdb-exp-fix-printing-of-out-of-bounds-struct-members.patch b/gdb-exp-fix-printing-of-out-of-bounds-struct-members.patch deleted file mode 100644 index d036c43..0000000 --- a/gdb-exp-fix-printing-of-out-of-bounds-struct-members.patch +++ /dev/null @@ -1,365 +0,0 @@ -From 86e379aa22ba5e77ba0c6fa26588c5fd1d9e6abe Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Mon, 19 Feb 2024 09:59:15 +0100 -Subject: [PATCH 13/48] [gdb/exp] Fix printing of out of bounds struct members - -When building gdb with -O0 -fsanitize=address, and running test-case -gdb.ada/uninitialized_vars.exp, I run into: -... -(gdb) info locals -a = 0 -z = (a => 1, b => false, c => 2.0) -================================================================= -==66372==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000097f58 at pc 0xffff52c0da1c bp 0xffffc90a1d40 sp 0xffffc90a1d80 -READ of size 4 at 0x602000097f58 thread T0 - #0 0xffff52c0da18 in memmove (/lib64/libasan.so.8+0x6da18) - #1 0xbcab24 in unsigned char* std::__copy_move_backward::__copy_move_b(unsigned char const*, unsigned char const*, unsigned char*) /usr/include/c++/13/bits/stl_algobase.h:748 - #2 0xbc9bf4 in unsigned char* std::__copy_move_backward_a2(unsigned char const*, unsigned char const*, unsigned char*) /usr/include/c++/13/bits/stl_algobase.h:769 - #3 0xbc898c in unsigned char* std::__copy_move_backward_a1(unsigned char const*, unsigned char const*, unsigned char*) /usr/include/c++/13/bits/stl_algobase.h:778 - #4 0xbc715c in unsigned char* std::__copy_move_backward_a(unsigned char const*, unsigned char const*, unsigned char*) /usr/include/c++/13/bits/stl_algobase.h:807 - #5 0xbc4e6c in unsigned char* std::copy_backward(unsigned char const*, unsigned char const*, unsigned char*) /usr/include/c++/13/bits/stl_algobase.h:867 - #6 0xbc2934 in void gdb::copy(gdb::array_view, gdb::array_view) gdb/../gdbsupport/array-view.h:223 - #7 0x20e0100 in value::contents_copy_raw(value*, long, long, long) gdb/value.c:1239 - #8 0x20e9830 in value::primitive_field(long, int, type*) gdb/value.c:3078 - #9 0x20e98f8 in value_field(value*, int) gdb/value.c:3095 - #10 0xcafd64 in print_field_values gdb/ada-valprint.c:658 - #11 0xcb0fa0 in ada_val_print_struct_union gdb/ada-valprint.c:857 - #12 0xcb1bb4 in ada_value_print_inner(value*, ui_file*, int, value_print_options const*) gdb/ada-valprint.c:1042 - #13 0xc66e04 in ada_language::value_print_inner(value*, ui_file*, int, value_print_options const*) const (/home/vries/gdb/build/gdb/gdb+0xc66e04) - #14 0x20ca1e8 in common_val_print(value*, ui_file*, int, value_print_options const*, language_defn const*) gdb/valprint.c:1092 - #15 0x20caabc in common_val_print_checked(value*, ui_file*, int, value_print_options const*, language_defn const*) gdb/valprint.c:1184 - #16 0x196c524 in print_variable_and_value(char const*, symbol*, frame_info_ptr, ui_file*, int) gdb/printcmd.c:2355 - #17 0x1d99ca0 in print_variable_and_value_data::operator()(char const*, symbol*) gdb/stack.c:2308 - #18 0x1dabca0 in gdb::function_view::bind(print_variable_and_value_data&)::{lambda(gdb::fv_detail::erased_callable, char const*, symbol*)#1}::operator()(gdb::fv_detail::erased_callable, char const*, symbol*) const gdb/../gdbsupport/function-view.h:305 - #19 0x1dabd14 in gdb::function_view::bind(print_variable_and_value_data&)::{lambda(gdb::fv_detail::erased_callable, char const*, symbol*)#1}::_FUN(gdb::fv_detail::erased_callable, char const*, symbol*) gdb/../gdbsupport/function-view.h:299 - #20 0x1dab34c in gdb::function_view::operator()(char const*, symbol*) const gdb/../gdbsupport/function-view.h:289 - #21 0x1d9963c in iterate_over_block_locals gdb/stack.c:2240 - #22 0x1d99790 in iterate_over_block_local_vars(block const*, gdb::function_view) gdb/stack.c:2259 - #23 0x1d9a598 in print_frame_local_vars gdb/stack.c:2380 - #24 0x1d9afac in info_locals_command(char const*, int) gdb/stack.c:2458 - #25 0xfd7b30 in do_simple_func gdb/cli/cli-decode.c:95 - #26 0xfe5a2c in cmd_func(cmd_list_element*, char const*, int) gdb/cli/cli-decode.c:2735 - #27 0x1f03790 in execute_command(char const*, int) gdb/top.c:575 - #28 0x1384080 in command_handler(char const*) gdb/event-top.c:566 - #29 0x1384e2c in command_line_handler(std::unique_ptr >&&) gdb/event-top.c:802 - #30 0x1f731e4 in tui_command_line_handler gdb/tui/tui-interp.c:104 - #31 0x1382a58 in gdb_rl_callback_handler gdb/event-top.c:259 - #32 0x21dbb80 in rl_callback_read_char readline/readline/callback.c:290 - #33 0x1382510 in gdb_rl_callback_read_char_wrapper_noexcept gdb/event-top.c:195 - #34 0x138277c in gdb_rl_callback_read_char_wrapper gdb/event-top.c:234 - #35 0x1fe9b40 in stdin_event_handler gdb/ui.c:155 - #36 0x35ff1bc in handle_file_event gdbsupport/event-loop.cc:573 - #37 0x35ff9d8 in gdb_wait_for_event gdbsupport/event-loop.cc:694 - #38 0x35fd284 in gdb_do_one_event(int) gdbsupport/event-loop.cc:264 - #39 0x1768080 in start_event_loop gdb/main.c:408 - #40 0x17684c4 in captured_command_loop gdb/main.c:472 - #41 0x176cfc8 in captured_main gdb/main.c:1342 - #42 0x176d088 in gdb_main(captured_main_args*) gdb/main.c:1361 - #43 0xb73edc in main gdb/gdb.c:39 - #44 0xffff519b09d8 in __libc_start_call_main (/lib64/libc.so.6+0x309d8) - #45 0xffff519b0aac in __libc_start_main@@GLIBC_2.34 (/lib64/libc.so.6+0x30aac) - #46 0xb73c2c in _start (/home/vries/gdb/build/gdb/gdb+0xb73c2c) - -0x602000097f58 is located 0 bytes after 8-byte region [0x602000097f50,0x602000097f58) -allocated by thread T0 here: - #0 0xffff52c65218 in calloc (/lib64/libasan.so.8+0xc5218) - #1 0xcbc278 in xcalloc gdb/alloc.c:97 - #2 0x35f21e8 in xzalloc(unsigned long) gdbsupport/common-utils.cc:29 - #3 0x20de270 in value::allocate_contents(bool) gdb/value.c:937 - #4 0x20edc08 in value::fetch_lazy() gdb/value.c:4033 - #5 0x20dadc0 in value::entirely_covered_by_range_vector(std::vector > const&) gdb/value.c:229 - #6 0xcb2298 in value::entirely_optimized_out() gdb/value.h:560 - #7 0x20ca6fc in value_check_printable gdb/valprint.c:1133 - #8 0x20caa8c in common_val_print_checked(value*, ui_file*, int, value_print_options const*, language_defn const*) gdb/valprint.c:1182 - #9 0x196c524 in print_variable_and_value(char const*, symbol*, frame_info_ptr, ui_file*, int) gdb/printcmd.c:2355 - #10 0x1d99ca0 in print_variable_and_value_data::operator()(char const*, symbol*) gdb/stack.c:2308 - #11 0x1dabca0 in gdb::function_view::bind(print_variable_and_value_data&)::{lambda(gdb::fv_detail::erased_callable, char const*, symbol*)#1}::operator()(gdb::fv_detail::erased_callable, char const*, symbol*) const gdb/../gdbsupport/function-view.h:305 - #12 0x1dabd14 in gdb::function_view::bind(print_variable_and_value_data&)::{lambda(gdb::fv_detail::erased_callable, char const*, symbol*)#1}::_FUN(gdb::fv_detail::erased_callable, char const*, symbol*) gdb/../gdbsupport/function-view.h:299 - #13 0x1dab34c in gdb::function_view::operator()(char const*, symbol*) const gdb/../gdbsupport/function-view.h:289 - #14 0x1d9963c in iterate_over_block_locals gdb/stack.c:2240 - #15 0x1d99790 in iterate_over_block_local_vars(block const*, gdb::function_view) gdb/stack.c:2259 - #16 0x1d9a598 in print_frame_local_vars gdb/stack.c:2380 - #17 0x1d9afac in info_locals_command(char const*, int) gdb/stack.c:2458 - #18 0xfd7b30 in do_simple_func gdb/cli/cli-decode.c:95 - #19 0xfe5a2c in cmd_func(cmd_list_element*, char const*, int) gdb/cli/cli-decode.c:2735 - #20 0x1f03790 in execute_command(char const*, int) gdb/top.c:575 - #21 0x1384080 in command_handler(char const*) gdb/event-top.c:566 - #22 0x1384e2c in command_line_handler(std::unique_ptr >&&) gdb/event-top.c:802 - #23 0x1f731e4 in tui_command_line_handler gdb/tui/tui-interp.c:104 - #24 0x1382a58 in gdb_rl_callback_handler gdb/event-top.c:259 - #25 0x21dbb80 in rl_callback_read_char readline/readline/callback.c:290 - #26 0x1382510 in gdb_rl_callback_read_char_wrapper_noexcept gdb/event-top.c:195 - #27 0x138277c in gdb_rl_callback_read_char_wrapper gdb/event-top.c:234 - #28 0x1fe9b40 in stdin_event_handler gdb/ui.c:155 - #29 0x35ff1bc in handle_file_event gdbsupport/event-loop.cc:573 - -SUMMARY: AddressSanitizer: heap-buffer-overflow (/lib64/libasan.so.8+0x6da18) in memmove -... - -The error happens when trying to print either variable y or y2: -... - type Variable_Record (A : Boolean := True) is record - case A is - when True => - B : Integer; - when False => - C : Float; - D : Integer; - end case; - end record; - Y : Variable_Record := (A => True, B => 1); - Y2 : Variable_Record := (A => False, C => 1.0, D => 2); -... -when the variables are uninitialized. - -The error happens only when printing the entire variable: -... -(gdb) p y.a -$2 = 216 -(gdb) p y.b -There is no member named b. -(gdb) p y.c -$3 = 9.18340949e-41 -(gdb) p y.d -$4 = 1 -(gdb) p y - -... - -The error happens as follows: -- field a functions as discriminant, choosing either the b, or c+d variant. -- when y.a happens to be set to 216, as above, gdb interprets this as the - variable having the c+d variant (which is why trying to print y.b fails). -- when printing y, gdb allocates a value, copies the bytes into it from the - target, and then prints the value. -- gdb allocates the value using the type size, which is 8. It's 8 because - that's what the DW_AT_byte_size indicates. Note that for valid values of a, - it gives correct results: if a is 0 (c+d variant), size is 12, if a is 1 - (b variant), size is 8. -- gdb tries to print field d, which is at an 8 byte offset, and that results - in a out-of-bounds access for the allocated 8-byte value. - -Fix this by handling this case in value::contents_copy_raw, such that we have: -... -(gdb) p y -$1 = (a => 24, c => 9.18340949e-41, - d => ) -... - -An alternative (additional) fix could be this: in compute_variant_fields_inner -gdb reads the discriminant y.a to decide which variant is active. It would be -nice to detect that the value (y.a == 24) is not a valid Boolean, and give up -on choosing a variant altoghether. However, the situation regarding the -internal type CODE_TYPE_BOOL is currently ambiguous (see PR31282) and it's not -possible to reliably decide what valid values are. - -The test-case source file gdb.ada/uninitialized-variable-record/parse.adb is -a reduced version of gdb.ada/uninitialized_vars/parse.adb, so it copies the -copyright years. - -Note that the test-case needs gcc-12 or newer, it's unsupported for older gcc -versions. [ So, it would be nice to rewrite it into a dwarf assembly -test-case. ] - -The test-case loops over all languages. This is inherited from an earlier -attempt to fix this, which had language-specific fixes (in print_field_values, -cp_print_value_fields, pascal_object_print_value_fields and -f_language::value_print_inner). I've left this in, but I suppose it's not -strictly necessary anymore. - -Tested on x86_64-linux. - -PR exp/31258 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31258 ---- - .../gdb.ada/uninitialized-variable-record.exp | 122 ++++++++++++++++++ - .../uninitialized-variable-record/parse.adb | 33 +++++ - gdb/value.c | 3 + - 3 files changed, 158 insertions(+) - create mode 100644 gdb/testsuite/gdb.ada/uninitialized-variable-record.exp - create mode 100644 gdb/testsuite/gdb.ada/uninitialized-variable-record/parse.adb - -diff --git a/gdb/testsuite/gdb.ada/uninitialized-variable-record.exp b/gdb/testsuite/gdb.ada/uninitialized-variable-record.exp -new file mode 100644 -index 00000000000..7fc72395edf ---- /dev/null -+++ b/gdb/testsuite/gdb.ada/uninitialized-variable-record.exp -@@ -0,0 +1,122 @@ -+# Copyright 2024 Free Software Foundation, Inc. -+# -+# 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 . -+ -+load_lib "ada.exp" -+ -+require allow_ada_tests -+ -+standard_ada_testfile parse -+ -+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug}] != "" } { -+ return -1 -+} -+ -+clean_restart ${testfile} -+ -+set bp_location [gdb_get_line_number "START" ${testdir}/parse.adb] -+runto "parse.adb:$bp_location" -+ -+# Check that we have the expected value for variable y2. -+ -+gdb_test "p y2" [string_to_regexp " = (a => false, c => 1.0, d => 2)"] -+ -+# Shorthand. -+ -+proc set_lang { lang } { -+ gdb_test_multiple "set language $lang" "" { -+ -re -wrap "" { -+ } -+ } -+} -+ -+# Calculate the offset of y2.d. -+ -+set re_cast [string_to_regexp "(access integer)"] -+gdb_test_multiple "print &y2.d - &y2" "" { -+ -re -wrap " = $re_cast ($hex)" { -+ set offset_d $expect_out(1,string) -+ pass $gdb_test_name -+ } -+} -+ -+# Try to find a interesting discriminator value, such that at the same time: -+# - the d field is part of the variable, and -+# - the type size is too small to contain d. -+ -+set interesting_discriminator -1 -+set_lang c -+for { set i 0 } { $i < 256 } { incr i } { -+ with_test_prefix $i { -+ -+ # Patch in the discriminator value. -+ gdb_test_multiple "set var *(unsigned char *)(&y2.a)=$i" "" { -+ -re -wrap "" { -+ } -+ } -+ -+ # Check that we have the variant with fields c+d instead of b. -+ set have_b 0 -+ gdb_test_multiple "with language ada -- print y2.b" "" { -+ -re -wrap " = $decimal" { -+ set have_b 1 -+ } -+ -re -wrap "" { -+ } -+ } -+ if { $have_b } { -+ # This is the variant with field b. -+ continue -+ } -+ -+ set size 0 -+ gdb_test_multiple "print sizeof (y2)" "" { -+ -re -wrap " = (.*)" { -+ set size $expect_out(1,string) -+ } -+ } -+ -+ if { ! $size } { -+ continue -+ } -+ -+ if { [expr $size > $offset_d] } { -+ # Field d fits in the size. -+ continue -+ } -+ -+ set interesting_discriminator $i -+ break -+ } -+} -+ -+require {expr $interesting_discriminator != -1} -+ -+foreach lang [gdb_supported_languages] { -+ with_test_prefix $lang { -+ set_lang $lang -+ -+ gdb_test_multiple "print y2" "" { -+ -re -wrap ", d => $decimal.*" { -+ fail $gdb_test_name -+ } -+ -re -wrap ", d = $decimal.*" { -+ fail $gdb_test_name -+ } -+ -re -wrap "" { -+ pass $gdb_test_name -+ } -+ } -+ } -+} -diff --git a/gdb/testsuite/gdb.ada/uninitialized-variable-record/parse.adb b/gdb/testsuite/gdb.ada/uninitialized-variable-record/parse.adb -new file mode 100644 -index 00000000000..f00c75ca2dc ---- /dev/null -+++ b/gdb/testsuite/gdb.ada/uninitialized-variable-record/parse.adb -@@ -0,0 +1,33 @@ -+-- Copyright 2009-2024 Free Software Foundation, Inc. -+-- -+-- 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 . -+ -+-- Based on gdb.ada/uninitialized_vars/parse.adb. -+ -+procedure Parse is -+ -+ type Variable_Record (A : Boolean := True) is record -+ case A is -+ when True => -+ B : Integer; -+ when False => -+ C : Float; -+ D : Integer; -+ end case; -+ end record; -+ Y2 : Variable_Record := (A => False, C => 1.0, D => 2); -+ -+begin -+ null; -- START -+end Parse; -diff --git a/gdb/value.c b/gdb/value.c -index 1cc32625629..56ae9db6603 100644 ---- a/gdb/value.c -+++ b/gdb/value.c -@@ -1188,6 +1188,9 @@ value::contents_copy_raw (struct value *dst, LONGEST dst_offset, - gdb_assert (!dst->bits_any_optimized_out (TARGET_CHAR_BIT * dst_offset, - TARGET_CHAR_BIT * length)); - -+ if ((src_offset + copy_length) * unit_size > enclosing_type ()-> length ()) -+ error (_("access outside bounds of object")); -+ - /* Copy the data. */ - gdb::array_view dst_contents - = dst->contents_all_raw ().slice (dst_offset * unit_size, --- -2.35.3 - diff --git a/gdb-exp-redo-cast-handling-for-indirection.patch b/gdb-exp-redo-cast-handling-for-indirection.patch deleted file mode 100644 index 3000d9b..0000000 --- a/gdb-exp-redo-cast-handling-for-indirection.patch +++ /dev/null @@ -1,86 +0,0 @@ -From a6800d9c8145f25001dd39afc3571e3350573e81 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Mon, 6 May 2024 14:23:25 +0200 -Subject: [PATCH] [gdb/exp] Redo cast handling for indirection - -In commit ed8fd0a342f ("[gdb/exp] Fix cast handling for indirection"), I -introduced the behaviour that even though we have: -... -(gdb) p *a_loc () -'a_loc' has unknown return type; cast the call to its declared return type -... -we get: -... -(gdb) p (char)*a_loc () -$1 = 97 'a' -... - -In other words, the unknown return type of a_loc is inferred from the cast, -effectually evaluating: -... -(gdb) p (char)*(char *)a_loc () -... - -This is convient for the case that errno is defined as: -... - #define errno (*__errno_location ()) -... -and the return type of __errno_location is unknown but the macro definition is -known, such that we can use: -... -(gdb) p (int)errno -... -instead of -... -(gdb) p *(int *)__errno_location () -... - -However, as Pedro has pointed out in post-commit review [1], this makes it -harder to reason about the semantics of an expression. - -For instance, this: -... -(gdb) p (long long)*a_loc ()" -... -would be evaluated without debug info as: -... -(gdb) p (long long)*(long long *)a_loc ()" -... -but with debug info as: -... -(gdb) p (long long)*(char *)a_loc ()" -... - -Fix this by instead simply erroring out for this case: -... -(gdb) p (char)*a_loc () -'a_loc' has unknown return type; cast the call to its declared return type -... - -Tested on x86_64-linux. - -Approved-By: Pedro Alves - -[1] https://sourceware.org/pipermail/gdb-patches/2024-May/208821.html ---- - gdb/testsuite/gdb.base/cast-indirection.exp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gdb/testsuite/gdb.base/cast-indirection.exp b/gdb/testsuite/gdb.base/cast-indirection.exp -index f1fe4302d27..7b9b5a5d677 100644 ---- a/gdb/testsuite/gdb.base/cast-indirection.exp -+++ b/gdb/testsuite/gdb.base/cast-indirection.exp -@@ -13,7 +13,7 @@ - # You should have received a copy of the GNU General Public License - # along with this program. If not, see . - --# Check that "p (char)*a_loc ()" is handled as "p (char)*(char *)a_loc ()". -+# Check that "p (char)*a_loc ()" is handled correctly. - - standard_testfile - - -base-commit: fc73000faa1798573090994167b7e2d451c211db --- -2.35.3 - diff --git a/gdb-fedora-libncursesw.patch b/gdb-fedora-libncursesw.patch deleted file mode 100644 index 6bf6aa3..0000000 --- a/gdb-fedora-libncursesw.patch +++ /dev/null @@ -1,333 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Fedora GDB patches -Date: Fri, 27 Oct 2017 21:07:50 +0200 -Subject: gdb-fedora-libncursesw.patch - -;; Force libncursesw over libncurses to match the includes (RH BZ 1270534). -;;=push+jan - -Fedora: Force libncursesw over libncurses to match the includes. -https://bugzilla.redhat.com/show_bug.cgi?id=1270534 - -diff --git a/gdb/configure b/gdb/configure ---- a/gdb/configure -+++ b/gdb/configure -@@ -780,9 +780,6 @@ ENABLE_BFD_64_BIT_TRUE - subdirs - RPM_LIBS - RPM_CFLAGS --PKG_CONFIG_LIBDIR --PKG_CONFIG_PATH --PKG_CONFIG - GDB_DATADIR - DEBUGDIR - MAKEINFO_EXTRA_FLAGS -@@ -990,12 +987,12 @@ PKG_CONFIG_PATH - PKG_CONFIG_LIBDIR - MAKEINFO - MAKEINFOFLAGS -+RPM_CFLAGS -+RPM_LIBS - AMD_DBGAPI_CFLAGS - AMD_DBGAPI_LIBS - DEBUGINFOD_CFLAGS - DEBUGINFOD_LIBS --RPM_CFLAGS --RPM_LIBS - YACC - YFLAGS - ZSTD_CFLAGS -@@ -1684,11 +1681,11 @@ Optional Packages: - [--with-auto-load-dir] - --without-auto-load-safe-path - do not restrict auto-loaded files locations -+ --with-rpm query rpm database for missing debuginfos (yes/no, -+ def. auto=librpm.so) - --with-amd-dbgapi support for the amd-dbgapi target (yes / no / auto) - --with-debuginfod Enable debuginfo lookups with debuginfod - (auto/yes/no) -- --with-rpm query rpm database for missing debuginfos (yes/no, -- def. auto=librpm.so) - --with-libunwind-ia64 use libunwind frame unwinding for ia64 targets - --with-curses use the curses library instead of the termcap - library -@@ -1761,6 +1758,8 @@ Some influential environment variables: - MAKEINFO Parent configure detects if it is of sufficient version. - MAKEINFOFLAGS - Parameters for MAKEINFO. -+ RPM_CFLAGS C compiler flags for RPM, overriding pkg-config -+ RPM_LIBS linker flags for RPM, overriding pkg-config - AMD_DBGAPI_CFLAGS - C compiler flags for AMD_DBGAPI, overriding pkg-config - AMD_DBGAPI_LIBS -@@ -1769,8 +1768,6 @@ Some influential environment variables: - C compiler flags for DEBUGINFOD, overriding pkg-config - DEBUGINFOD_LIBS - linker flags for DEBUGINFOD, overriding pkg-config -- RPM_CFLAGS C compiler flags for RPM, overriding pkg-config -- RPM_LIBS linker flags for RPM, overriding pkg-config - YACC The `Yet Another Compiler Compiler' implementation to use. - Defaults to the first program found out of: `bison -y', `byacc', - `yacc'. -@@ -11495,7 +11492,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 11486 "configure" -+#line 11495 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -11601,7 +11598,7 @@ else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF --#line 11592 "configure" -+#line 11601 "configure" - #include "confdefs.h" - - #if HAVE_DLFCN_H -@@ -18102,8 +18099,8 @@ $as_echo_n "checking specific librpm version... " >&6; } - if test "$cross_compiling" = 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 "cannot run test program while cross compiling --See \`config.log' for more details." "$LINENO" 5; } -+as_fn_error $? "cannot run test program while cross compiling -+See \`config.log' for more details" "$LINENO" 5; } - else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext - /* end confdefs.h. */ -@@ -18275,132 +18272,12 @@ $as_echo "#define HAVE_LIBRPM 1" >>confdefs.h - $as_echo "no" >&6; } - LIBS="$save_LIBS" - if $DLOPEN_REQUIRE; then -- as_fn_error "Specific name $LIBRPM was requested but it could not be opened." "$LINENO" 5 -+ as_fn_error $? "Specific name $LIBRPM was requested but it could not be opened." "$LINENO" 5 - fi - -- -- -- -- -- -- --if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then -- if test -n "$ac_tool_prefix"; then -- # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. --set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 --$as_echo_n "checking for $ac_word... " >&6; } --if test "${ac_cv_path_PKG_CONFIG+set}" = set; then : -- $as_echo_n "(cached) " >&6 --else -- case $PKG_CONFIG in -- [\\/]* | ?:[\\/]*) -- ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. -- ;; -- *) -- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR --for as_dir in $PATH --do -- IFS=$as_save_IFS -- test -z "$as_dir" && as_dir=. -- for ac_exec_ext in '' $ac_executable_extensions; do -- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then -- ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" -- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -- break 2 -- fi --done -- done --IFS=$as_save_IFS -- -- ;; --esac --fi --PKG_CONFIG=$ac_cv_path_PKG_CONFIG --if test -n "$PKG_CONFIG"; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 --$as_echo "$PKG_CONFIG" >&6; } --else -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 --$as_echo "no" >&6; } --fi -- -- --fi --if test -z "$ac_cv_path_PKG_CONFIG"; then -- ac_pt_PKG_CONFIG=$PKG_CONFIG -- # Extract the first word of "pkg-config", so it can be a program name with args. --set dummy pkg-config; ac_word=$2 --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 --$as_echo_n "checking for $ac_word... " >&6; } --if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then : -- $as_echo_n "(cached) " >&6 --else -- case $ac_pt_PKG_CONFIG in -- [\\/]* | ?:[\\/]*) -- ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. -- ;; -- *) -- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR --for as_dir in $PATH --do -- IFS=$as_save_IFS -- test -z "$as_dir" && as_dir=. -- for ac_exec_ext in '' $ac_executable_extensions; do -- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then -- ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" -- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 -- break 2 -- fi --done -- done --IFS=$as_save_IFS -- -- ;; --esac --fi --ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG --if test -n "$ac_pt_PKG_CONFIG"; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 --$as_echo "$ac_pt_PKG_CONFIG" >&6; } --else -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 --$as_echo "no" >&6; } --fi -- -- if test "x$ac_pt_PKG_CONFIG" = x; then -- PKG_CONFIG="" -- else -- case $cross_compiling:$ac_tool_warned in --yes:) --{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 --$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} --ac_tool_warned=yes ;; --esac -- PKG_CONFIG=$ac_pt_PKG_CONFIG -- fi --else -- PKG_CONFIG="$ac_cv_path_PKG_CONFIG" --fi -- --fi --if test -n "$PKG_CONFIG"; then -- _pkg_min_version=0.9.0 -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 --$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } -- if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 --$as_echo "yes" >&6; } -- else -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 --$as_echo "no" >&6; } -- PKG_CONFIG="" -- fi --fi -- - pkg_failed=no --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for RPM" >&5 --$as_echo_n "checking for RPM... " >&6; } -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rpm" >&5 -+$as_echo_n "checking for rpm... " >&6; } - - if test -n "$RPM_CFLAGS"; then - pkg_cv_RPM_CFLAGS="$RPM_CFLAGS" -@@ -18437,6 +18314,30 @@ fi - pkg_failed=untried - fi - -+if test $pkg_failed = no; then -+ pkg_save_LDFLAGS="$LDFLAGS" -+ LDFLAGS="$LDFLAGS $pkg_cv_RPM_LIBS" -+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+ -+int -+main () -+{ -+ -+ ; -+ return 0; -+} -+_ACEOF -+if ac_fn_c_try_link "$LINENO"; then : -+ -+else -+ pkg_failed=yes -+fi -+rm -f core conftest.err conftest.$ac_objext \ -+ conftest$ac_exeext conftest.$ac_ext -+ LDFLAGS=$pkg_save_LDFLAGS -+fi -+ - - - if test $pkg_failed = yes; then -@@ -18531,7 +18432,7 @@ $as_echo "#define HAVE_LIBRPM 1" >>confdefs.h - LIBS="$LIBS $RPM_LIBS" - else - if $RPM_REQUIRE; then -- as_fn_error "$RPM_PKG_ERRORS" "$LINENO" 5 -+ as_fn_error $? "$RPM_PKG_ERRORS" "$LINENO" 5 - else - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $RPM_PKG_ERRORS" >&5 - $as_echo "$as_me: WARNING: $RPM_PKG_ERRORS" >&2;} -@@ -21164,6 +21065,7 @@ if test x"$prefer_curses" = xyes; then - # search /usr/local/include, if ncurses is installed in /usr/local. A - # default installation of ncurses on alpha*-dec-osf* will lead to such - # a situation. -+ # Fedora: Force libncursesw over libncurses to match the includes. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing waddstr" >&5 - $as_echo_n "checking for library containing waddstr... " >&6; } - if ${ac_cv_search_waddstr+:} false; then : -@@ -21188,7 +21090,7 @@ return waddstr (); - return 0; - } - _ACEOF --for ac_lib in '' ncursesw ncurses cursesX curses; do -+for ac_lib in '' ncursesw; do - if test -z "$ac_lib"; then - ac_res="none required" - else -@@ -21260,6 +21162,7 @@ case $host_os in - esac - - # These are the libraries checked by Readline. -+# Fedora: Force libncursesw over libncurses to match the includes. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing tgetent" >&5 - $as_echo_n "checking for library containing tgetent... " >&6; } - if ${ac_cv_search_tgetent+:} false; then : -@@ -21284,7 +21187,7 @@ return tgetent (); - return 0; - } - _ACEOF --for ac_lib in '' termcap tinfow tinfo curses ncursesw ncurses; do -+for ac_lib in '' ncursesw; do - if test -z "$ac_lib"; then - ac_res="none required" - else -diff --git a/gdb/configure.ac b/gdb/configure.ac ---- a/gdb/configure.ac -+++ b/gdb/configure.ac -@@ -749,7 +749,8 @@ if test x"$prefer_curses" = xyes; then - # search /usr/local/include, if ncurses is installed in /usr/local. A - # default installation of ncurses on alpha*-dec-osf* will lead to such - # a situation. -- AC_SEARCH_LIBS(waddstr, [ncursesw ncurses cursesX curses], -+ # Fedora: Force libncursesw over libncurses to match the includes. -+ AC_SEARCH_LIBS(waddstr, [ncursesw], - [curses_found=yes - AC_DEFINE([HAVE_LIBCURSES], [1], - [Define to 1 if curses is enabled.]) -@@ -789,7 +790,8 @@ case $host_os in - esac - - # These are the libraries checked by Readline. --AC_SEARCH_LIBS(tgetent, [termcap tinfow tinfo curses ncursesw ncurses]) -+# Fedora: Force libncursesw over libncurses to match the includes. -+AC_SEARCH_LIBS(tgetent, [ncursesw]) - - if test "$ac_cv_search_tgetent" = no; then - CONFIG_OBS="$CONFIG_OBS stub-termcap.o" diff --git a/gdb-fix-heap-use-after-free-in-select_event_lwp.patch b/gdb-fix-heap-use-after-free-in-select_event_lwp.patch deleted file mode 100644 index b362a6e..0000000 --- a/gdb-fix-heap-use-after-free-in-select_event_lwp.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 350172ea215c7074601e8424ff636563612f91e8 Mon Sep 17 00:00:00 2001 -From: Pedro Alves -Date: Wed, 21 Feb 2024 16:23:55 +0000 -Subject: [PATCH 14/48] [gdb] Fix heap-use-after-free in select_event_lwp - -PR gdb/31259 reveals one scenario where we run into a -heap-use-after-free reported by thread sanitizer, while running -gdb.base/vfork-follow-parent.exp. - -The heap-use-after-free happens during the following scenario: - - - linux_nat_wait_1 is about to return an event for T2. It stops all - other threads, and while doing so, stop_wait_callback -> wait_lwp - sees T1 exit, and decides to leave the exit event pending. It - should have set the lp->stopped flag too, but does not -- this is - the bug. - - - The event for T2 is reported, is processed by infrun, and we're - back at linux_nat_wait_1. - - - linux_nat_wait_1 selects LWP T1 with the pending exit status to - report. - - - it sets variable lp to point to the corresponding lwp_info. - - - it calls stop_callback and stop_wait_callback for all threads - (because !target_is_non_stop_p ()). - - - it calls select_event_lwp to maybe pick another thread than T1, to - prevent starvation. - -The problem is the following: - - - while calling stop_wait_callback for all threads, it also does this - for T1. While doing so, the corresponding lwp_info is deleted - (callstack stop_wait_callback -> wait_lwp -> exit_lwp -> - delete_lwp), leaving variable lp as a dangling pointer. - - - variable lp is passed to select_event_lwp, which derefences it, - which causes the heap-use-after-free. - -Note that the comment here mentions "all other LWP's": -... - /* Now stop all other LWP's ... */ - iterate_over_lwps (minus_one_ptid, stop_callback); - /* ... and wait until all of them have reported back that - they're no longer running. */ - iterate_over_lwps (minus_one_ptid, stop_wait_callback); -... - -The reason the comments say "all other LWP's", and doesn't bother -filtering out LP is that lp->stopped should be true at this point, and -the callbacks (both stop_callback and stop_wait_callback) check that -flag, and do nothing if set. I.e., they skip already-stopped threads, -so they should skip LP. - -In this particular scenario, though, we missed setting the stopped -flag right in the first step described above, so LP was iterated over -incorrectly. - -The fix is to make wait_lwp set the lp->stopped flag when it decides -to leave the exit event pending. However, going a bit further, -gdbserver has a mark_lwp_dead function to centralize setting up -various lwp flags such that the rest of the code doesn't mishandle -them, and it seems like a good idea to do a similar thing in gdb as -well. That is what this patch does. - -PR gdb/31259 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31259 -Co-Authored-By: Tom de Vries -Change-Id: I4a6169976f89bf714c478cbb2b7d4c32365e62a9 ---- - gdb/linux-nat.c | 34 +++++++++++++++++++++++++--------- - 1 file changed, 25 insertions(+), 9 deletions(-) - -diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c -index 7e36ced6292..ed445c5e5bb 100644 ---- a/gdb/linux-nat.c -+++ b/gdb/linux-nat.c -@@ -2029,6 +2029,27 @@ wait_for_signal () - } - } - -+/* Mark LWP dead, with STATUS as exit status pending to report -+ later. */ -+ -+static void -+mark_lwp_dead (lwp_info *lp, int status) -+{ -+ /* Store the exit status lp->waitstatus, because lp->status would be -+ ambiguous (W_EXITCODE(0,0) == 0). */ -+ lp->waitstatus = host_status_to_waitstatus (status); -+ -+ /* If we're processing LP's status, there should be no other event -+ already recorded as pending. */ -+ gdb_assert (lp->status == 0); -+ -+ /* Dead LWPs aren't expected to report a pending sigstop. */ -+ lp->signalled = 0; -+ -+ /* Prevent trying to stop it. */ -+ lp->stopped = 1; -+} -+ - /* Wait for LP to stop. Returns the wait status, or 0 if the LWP has - exited. */ - -@@ -2114,9 +2135,8 @@ wait_lwp (struct lwp_info *lp) - - /* If this is the leader exiting, it means the whole - process is gone. Store the status to report to the -- core. Store it in lp->waitstatus, because lp->status -- would be ambiguous (W_EXITCODE(0,0) == 0). */ -- lp->waitstatus = host_status_to_waitstatus (status); -+ core. */ -+ mark_lwp_dead (lp, status); - return 0; - } - -@@ -2908,12 +2928,7 @@ linux_nat_filter_event (int lwpid, int status) - linux_nat_debug_printf ("LWP %ld exited (resumed=%d)", - lp->ptid.lwp (), lp->resumed); - -- /* Dead LWP's aren't expected to reported a pending sigstop. */ -- lp->signalled = 0; -- -- /* Store the pending event in the waitstatus, because -- W_EXITCODE(0,0) == 0. */ -- lp->waitstatus = host_status_to_waitstatus (status); -+ mark_lwp_dead (lp, status); - return; - } - -@@ -3248,6 +3263,7 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus, - } - - gdb_assert (lp); -+ gdb_assert (lp->stopped); - - status = lp->status; - lp->status = 0; --- -2.35.3 - diff --git a/gdb-fix-segfault-in-for_each_block-part-1.patch b/gdb-fix-segfault-in-for_each_block-part-1.patch deleted file mode 100644 index 8dad7a1..0000000 --- a/gdb-fix-segfault-in-for_each_block-part-1.patch +++ /dev/null @@ -1,636 +0,0 @@ -From 1d02ba0f4adcba2595a67e88fb1ba6d35c7f8e5b Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Tue, 7 May 2024 11:33:57 +0200 -Subject: [PATCH] [gdb] Fix segfault in for_each_block, part 1 - -When running test-case gdb.base/vfork-follow-parent.exp on powerpc64 (likewise -on s390x), I run into: -... -(gdb) PASS: gdb.base/vfork-follow-parent.exp: \ - exec_file=vfork-follow-parent-exit: target-non-stop=on: non-stop=off: \ - resolution_method=schedule-multiple: print unblock_parent = 1 -continue^M -Continuing.^M -Reading symbols from vfork-follow-parent-exit...^M -^M -^M -Fatal signal: Segmentation fault^M ------ Backtrace -----^M -0x1027d3e7 gdb_internal_backtrace_1^M - src/gdb/bt-utils.c:122^M -0x1027d54f _Z22gdb_internal_backtracev^M - src/gdb/bt-utils.c:168^M -0x1057643f handle_fatal_signal^M - src/gdb/event-top.c:889^M -0x10576677 handle_sigsegv^M - src/gdb/event-top.c:962^M -0x3fffa7610477 ???^M -0x103f2144 for_each_block^M - src/gdb/dcache.c:199^M -0x103f235b _Z17dcache_invalidateP13dcache_struct^M - src/gdb/dcache.c:251^M -0x10bde8c7 _Z24target_dcache_invalidatev^M - src/gdb/target-dcache.c:50^M -... -or similar. - -The root cause for the segmentation fault is that linux_is_uclinux gives an -incorrect result: it should always return false, given that we're running on a -regular linux system, but instead it returns first true, then false. - -In more detail, the segmentation fault happens as follows: -- a program space with an address space is created -- a second program space is about to be created. maybe_new_address_space - is called, and because linux_is_uclinux returns true, maybe_new_address_space - returns false, and no new address space is created -- a second program space with the same address space is created -- a program space is deleted. Because linux_is_uclinux now returns false, - gdbarch_has_shared_address_space (current_inferior ()->arch ()) returns - false, and the address space is deleted -- when gdb uses the address space of the remaining program space, we run into - the segfault, because the address space is deleted. - -Hardcoding linux_is_uclinux to false makes the test-case pass. - -We leave addressing the root cause for the following commit in this series. - -For now, prevent the segmentation fault by making the address space a refcounted -object. - -This was already suggested here [1]: -... -A better solution might be to have the address spaces be reference counted -... - -Tested on top of trunk on x86_64-linux and ppc64le-linux. -Tested on top of gdb-14-branch on ppc64-linux. - -Co-Authored-By: Simon Marchi - -PR gdb/30547 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30547 - -[1] https://sourceware.org/pipermail/gdb-patches/2023-October/202928.html ---- - gdb/breakpoint.c | 29 ++++++++------- - gdb/inferior.c | 8 ++--- - gdb/inferior.h | 2 +- - gdb/infrun.c | 18 +++++----- - gdb/linux-nat.c | 2 +- - gdb/process-stratum-target.c | 2 +- - gdb/progspace.c | 22 +++++------- - gdb/progspace.h | 64 +++++++++++++++++++++------------- - gdb/record-btrace.c | 2 +- - gdb/regcache.c | 2 +- - gdb/scoped-mock-context.h | 2 +- - gdb/target-dcache.c | 11 +++--- - gdbsupport/refcounted-object.h | 17 +++++++++ - 13 files changed, 102 insertions(+), 79 deletions(-) - -diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c -index 01f187ca4fe..a22bdb091cd 100644 ---- a/gdb/breakpoint.c -+++ b/gdb/breakpoint.c -@@ -1723,7 +1723,7 @@ one_breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf, - int bptoffset = 0; - - if (!breakpoint_address_match (target_info->placed_address_space, 0, -- current_program_space->aspace, 0)) -+ current_program_space->aspace.get (), 0)) - { - /* The breakpoint is inserted in a different address space. */ - return; -@@ -2409,7 +2409,7 @@ should_be_inserted (struct bp_location *bl) - a breakpoint. */ - if ((bl->loc_type == bp_loc_software_breakpoint - || bl->loc_type == bp_loc_hardware_breakpoint) -- && stepping_past_instruction_at (bl->pspace->aspace, -+ && stepping_past_instruction_at (bl->pspace->aspace.get (), - bl->address) - /* The single-step breakpoint may be inserted at the location - we're trying to step if the instruction branches to itself. -@@ -2847,7 +2847,7 @@ insert_bp_location (struct bp_location *bl, - read the breakpoint instead of returning the data saved in - the breakpoint location's shadow contents. */ - bl->target_info.reqstd_address = bl->address; -- bl->target_info.placed_address_space = bl->pspace->aspace; -+ bl->target_info.placed_address_space = bl->pspace->aspace.get (); - bl->target_info.length = bl->length; - - /* When working with target-side conditions, we must pass all the conditions -@@ -4429,7 +4429,7 @@ bp_location_inserted_here_p (const struct bp_location *bl, - const address_space *aspace, CORE_ADDR pc) - { - if (bl->inserted -- && breakpoint_address_match (bl->pspace->aspace, bl->address, -+ && breakpoint_address_match (bl->pspace->aspace.get (), bl->address, - aspace, pc)) - { - /* An unmapped overlay can't be a match. */ -@@ -4508,7 +4508,7 @@ hardware_watchpoint_inserted_in_range (const address_space *aspace, - continue; - - for (bp_location &loc : bpt.locations ()) -- if (loc.pspace->aspace == aspace && loc.inserted) -+ if (loc.pspace->aspace.get () == aspace && loc.inserted) - { - CORE_ADDR l, h; - -@@ -7330,10 +7330,10 @@ breakpoint_location_address_match (struct bp_location *bl, - const address_space *aspace, - CORE_ADDR addr) - { -- return (breakpoint_address_match (bl->pspace->aspace, bl->address, -+ return (breakpoint_address_match (bl->pspace->aspace.get (), bl->address, - aspace, addr) - || (bl->length -- && breakpoint_address_match_range (bl->pspace->aspace, -+ && breakpoint_address_match_range (bl->pspace->aspace.get (), - bl->address, bl->length, - aspace, addr))); - } -@@ -7350,7 +7350,7 @@ breakpoint_location_address_range_overlap (struct bp_location *bl, - CORE_ADDR addr, int len) - { - if (gdbarch_has_global_breakpoints (target_gdbarch ()) -- || bl->pspace->aspace == aspace) -+ || bl->pspace->aspace.get () == aspace) - { - int bl_len = bl->length != 0 ? bl->length : 1; - -@@ -7407,8 +7407,10 @@ breakpoint_locations_match (const struct bp_location *loc1, - /* We compare bp_location.length in order to cover ranged - breakpoints. Keep this in sync with - bp_location_is_less_than. */ -- return (breakpoint_address_match (loc1->pspace->aspace, loc1->address, -- loc2->pspace->aspace, loc2->address) -+ return (breakpoint_address_match (loc1->pspace->aspace.get (), -+ loc1->address, -+ loc2->pspace->aspace.get (), -+ loc2->address) - && (loc1->loc_type == loc2->loc_type || sw_hw_bps_match) - && loc1->length == loc2->length); - } -@@ -9568,8 +9570,9 @@ ranged_breakpoint::breakpoint_hit (const struct bp_location *bl, - || ws.sig () != GDB_SIGNAL_TRAP) - return 0; - -- return breakpoint_address_match_range (bl->pspace->aspace, bl->address, -- bl->length, aspace, bp_addr); -+ return breakpoint_address_match_range (bl->pspace->aspace.get (), -+ bl->address, bl->length, aspace, -+ bp_addr); - } - - /* Implement the "resources_needed" method for ranged breakpoints. */ -@@ -12018,7 +12021,7 @@ code_breakpoint::breakpoint_hit (const struct bp_location *bl, - || ws.sig () != GDB_SIGNAL_TRAP) - return 0; - -- if (!breakpoint_address_match (bl->pspace->aspace, bl->address, -+ if (!breakpoint_address_match (bl->pspace->aspace.get (), bl->address, - aspace, bp_addr)) - return 0; - -diff --git a/gdb/inferior.c b/gdb/inferior.c -index 550bbd2827c..461f4fc076a 100644 ---- a/gdb/inferior.c -+++ b/gdb/inferior.c -@@ -831,15 +831,13 @@ remove_inferior_command (const char *args, int from_tty) - struct inferior * - add_inferior_with_spaces (void) - { -- struct address_space *aspace; - struct program_space *pspace; - struct inferior *inf; - - /* If all inferiors share an address space on this system, this - doesn't really return a new address space; otherwise, it - really does. */ -- aspace = maybe_new_address_space (); -- pspace = new program_space (aspace); -+ pspace = new program_space (maybe_new_address_space ()); - inf = add_inferior (0); - inf->pspace = pspace; - inf->aspace = pspace->aspace; -@@ -1002,15 +1000,13 @@ clone_inferior_command (const char *args, int from_tty) - - for (i = 0; i < copies; ++i) - { -- struct address_space *aspace; - struct program_space *pspace; - struct inferior *inf; - - /* If all inferiors share an address space on this system, this - doesn't really return a new address space; otherwise, it - really does. */ -- aspace = maybe_new_address_space (); -- pspace = new program_space (aspace); -+ pspace = new program_space (maybe_new_address_space ()); - inf = add_inferior (0); - inf->pspace = pspace; - inf->aspace = pspace->aspace; -diff --git a/gdb/inferior.h b/gdb/inferior.h -index 29c90d15efa..4139791740f 100644 ---- a/gdb/inferior.h -+++ b/gdb/inferior.h -@@ -577,7 +577,7 @@ class inferior : public refcounted_object, - bool removable = false; - - /* The address space bound to this inferior. */ -- struct address_space *aspace = NULL; -+ address_space_ref_ptr aspace; - - /* The program space bound to this inferior. */ - struct program_space *pspace = NULL; -diff --git a/gdb/infrun.c b/gdb/infrun.c -index 7be98cfc252..3854c66bf6c 100644 ---- a/gdb/infrun.c -+++ b/gdb/infrun.c -@@ -531,8 +531,8 @@ holding the child stopped. Try \"set detach-on-fork\" or \ - } - else - { -- child_inf->aspace = new address_space (); -- child_inf->pspace = new program_space (child_inf->aspace); -+ child_inf->pspace = new program_space (new_address_space ()); -+ child_inf->aspace = child_inf->pspace->aspace; - child_inf->removable = true; - clone_program_space (child_inf->pspace, parent_inf->pspace); - } -@@ -610,8 +610,8 @@ holding the child stopped. Try \"set detach-on-fork\" or \ - - child_inf->aspace = parent_inf->aspace; - child_inf->pspace = parent_inf->pspace; -- parent_inf->aspace = new address_space (); -- parent_inf->pspace = new program_space (parent_inf->aspace); -+ parent_inf->pspace = new program_space (new_address_space ()); -+ parent_inf->aspace = parent_inf->pspace->aspace; - clone_program_space (parent_inf->pspace, child_inf->pspace); - - /* The parent inferior is still the current one, so keep things -@@ -620,8 +620,8 @@ holding the child stopped. Try \"set detach-on-fork\" or \ - } - else - { -- child_inf->aspace = new address_space (); -- child_inf->pspace = new program_space (child_inf->aspace); -+ child_inf->pspace = new program_space (new_address_space ()); -+ child_inf->aspace = child_inf->pspace->aspace; - child_inf->removable = true; - child_inf->symfile_flags = SYMFILE_NO_READ; - clone_program_space (child_inf->pspace, parent_inf->pspace); -@@ -1031,7 +1031,6 @@ handle_vfork_child_exec_or_exit (int exec) - if (vfork_parent->pending_detach) - { - struct program_space *pspace; -- struct address_space *aspace; - - /* follow-fork child, detach-on-fork on. */ - -@@ -1056,9 +1055,8 @@ handle_vfork_child_exec_or_exit (int exec) - of" a hack. */ - - pspace = inf->pspace; -- aspace = inf->aspace; -- inf->aspace = nullptr; - inf->pspace = nullptr; -+ address_space_ref_ptr aspace = std::move (inf->aspace); - - if (print_inferior_events) - { -@@ -5906,7 +5904,7 @@ handle_inferior_event (struct execution_control_state *ecs) - = get_thread_arch_aspace_regcache (parent_inf, - ecs->ws.child_ptid (), - gdbarch, -- parent_inf->aspace); -+ parent_inf->aspace.get ()); - /* Read PC value of parent process. */ - parent_pc = regcache_read_pc (regcache); - -diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c -index ed445c5e5bb..c8991cc3da4 100644 ---- a/gdb/linux-nat.c -+++ b/gdb/linux-nat.c -@@ -4365,7 +4365,7 @@ linux_nat_target::thread_address_space (ptid_t ptid) - - inf = find_inferior_pid (this, pid); - gdb_assert (inf != NULL); -- return inf->aspace; -+ return inf->aspace.get (); - } - - /* Return the cached value of the processor core for thread PTID. */ -diff --git a/gdb/process-stratum-target.c b/gdb/process-stratum-target.c -index 5c031203e89..4bcca4f39c2 100644 ---- a/gdb/process-stratum-target.c -+++ b/gdb/process-stratum-target.c -@@ -37,7 +37,7 @@ process_stratum_target::thread_address_space (ptid_t ptid) - "address space of thread %s\n"), - target_pid_to_str (ptid).c_str ()); - -- return inf->aspace; -+ return inf->aspace.get (); - } - - struct gdbarch * -diff --git a/gdb/progspace.c b/gdb/progspace.c -index 1dbcd5875dd..b4d25ba6196 100644 ---- a/gdb/progspace.c -+++ b/gdb/progspace.c -@@ -55,8 +55,8 @@ address_space::address_space () - return a pointer to an existing address space, in case inferiors - share an address space on this target system. */ - --struct address_space * --maybe_new_address_space (void) -+address_space_ref_ptr -+maybe_new_address_space () - { - int shared_aspace = gdbarch_has_shared_address_space (target_gdbarch ()); - -@@ -66,7 +66,7 @@ maybe_new_address_space (void) - return program_spaces[0]->aspace; - } - -- return new address_space (); -+ return new_address_space (); - } - - /* Start counting over from scratch. */ -@@ -94,9 +94,9 @@ remove_program_space (program_space *pspace) - - /* See progspace.h. */ - --program_space::program_space (address_space *aspace_) -+program_space::program_space (address_space_ref_ptr aspace_) - : num (++last_program_space_num), -- aspace (aspace_) -+ aspace (std::move (aspace_)) - { - program_spaces.push_back (this); - gdb::observers::new_program_space.notify (this); -@@ -121,8 +121,6 @@ program_space::~program_space () - /* Defer breakpoint re-set because we don't want to create new - locations for this pspace which we're tearing down. */ - clear_symtab_users (SYMFILE_DEFER_BP_RESET); -- if (!gdbarch_has_shared_address_space (target_gdbarch ())) -- delete this->aspace; - } - - /* See progspace.h. */ -@@ -408,18 +406,14 @@ update_address_spaces (void) - - if (shared_aspace) - { -- struct address_space *aspace = new address_space (); -+ address_space_ref_ptr aspace = new_address_space (); - -- delete current_program_space->aspace; - for (struct program_space *pspace : program_spaces) - pspace->aspace = aspace; - } - else - for (struct program_space *pspace : program_spaces) -- { -- delete pspace->aspace; -- pspace->aspace = new address_space (); -- } -+ pspace->aspace = new_address_space (); - - for (inferior *inf : all_inferiors ()) - if (gdbarch_has_global_solist (target_gdbarch ())) -@@ -456,5 +450,5 @@ initialize_progspace (void) - modules have done that. Do this before - initialize_current_architecture, because that accesses the ebfd - of current_program_space. */ -- current_program_space = new program_space (new address_space ()); -+ current_program_space = new program_space (new_address_space ()); - } -diff --git a/gdb/progspace.h b/gdb/progspace.h -index ee12d89c173..12f113f6d9c 100644 ---- a/gdb/progspace.h -+++ b/gdb/progspace.h -@@ -28,6 +28,8 @@ - #include "solist.h" - #include "gdbsupport/next-iterator.h" - #include "gdbsupport/safe-iterator.h" -+#include "gdbsupport/refcounted-object.h" -+#include "gdbsupport/gdb_ref_ptr.h" - #include - #include - -@@ -42,6 +44,40 @@ struct so_list; - - typedef std::list> objfile_list; - -+/* An address space. It is used for comparing if -+ pspaces/inferior/threads see the same address space and for -+ associating caches to each address space. */ -+struct address_space : public refcounted_object -+{ -+ /* Create a new address space object, and add it to the list. */ -+ address_space (); -+ DISABLE_COPY_AND_ASSIGN (address_space); -+ -+ /* Returns the integer address space id of this address space. */ -+ int num () const -+ { -+ return m_num; -+ } -+ -+ /* Per aspace data-pointers required by other GDB modules. */ -+ registry registry_fields; -+ -+private: -+ int m_num; -+}; -+ -+using address_space_ref_ptr -+ = gdb::ref_ptr>; -+ -+/* Create a new address space. */ -+ -+static inline address_space_ref_ptr -+new_address_space () -+{ -+ return address_space_ref_ptr::new_reference (new address_space); -+} -+ - /* An iterator that wraps an iterator over std::unique_ptr, - and dereferences the returned object. This is useful for iterating - over a list of shared pointers and returning raw pointers -- which -@@ -191,7 +227,7 @@ struct program_space - { - /* Constructs a new empty program space, binds it to ASPACE, and - adds it to the program space list. */ -- explicit program_space (address_space *aspace); -+ explicit program_space (address_space_ref_ptr aspace); - - /* Releases a program space, and all its contents (shared libraries, - objfiles, and any other references to the program space in other -@@ -336,7 +372,7 @@ struct program_space - are global, then this field is ignored (we don't currently - support inferiors sharing a program space if the target doesn't - make breakpoints global). */ -- struct address_space *aspace = NULL; -+ address_space_ref_ptr aspace; - - /* True if this program space's section offsets don't yet represent - the final offsets of the "live" address space (that is, the -@@ -383,28 +419,6 @@ struct program_space - target_section_table m_target_sections; - }; - --/* An address space. It is used for comparing if -- pspaces/inferior/threads see the same address space and for -- associating caches to each address space. */ --struct address_space --{ -- /* Create a new address space object, and add it to the list. */ -- address_space (); -- DISABLE_COPY_AND_ASSIGN (address_space); -- -- /* Returns the integer address space id of this address space. */ -- int num () const -- { -- return m_num; -- } -- -- /* Per aspace data-pointers required by other GDB modules. */ -- registry registry_fields; -- --private: -- int m_num; --}; -- - /* The list of all program spaces. There's always at least one. */ - extern std::vectorprogram_spaces; - -@@ -447,7 +461,7 @@ class scoped_restore_current_program_space - /* Maybe create a new address space object, and add it to the list, or - return a pointer to an existing address space, in case inferiors - share an address space. */ --extern struct address_space *maybe_new_address_space (void); -+extern address_space_ref_ptr maybe_new_address_space (); - - /* Update all program spaces matching to address spaces. The user may - have created several program spaces, and loaded executables into -diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c -index 97447d3e8f8..a4d6c1b5bf2 100644 ---- a/gdb/record-btrace.c -+++ b/gdb/record-btrace.c -@@ -2321,7 +2321,7 @@ record_btrace_replay_at_breakpoint (struct thread_info *tp) - if (insn == NULL) - return 0; - -- return record_check_stopped_by_breakpoint (tp->inf->aspace, insn->pc, -+ return record_check_stopped_by_breakpoint (tp->inf->aspace.get (), insn->pc, - &btinfo->stop_reason); - } - -diff --git a/gdb/regcache.c b/gdb/regcache.c -index 91b20b7a2a2..a78fe0a80e7 100644 ---- a/gdb/regcache.c -+++ b/gdb/regcache.c -@@ -1628,7 +1628,7 @@ get_thread_arch_aspace_regcache_and_check (inferior *inf_for_target_calls, - the current inferior's gdbarch. Also use the current inferior's address - space. */ - gdbarch *arch = inf_for_target_calls->gdbarch; -- address_space *aspace = inf_for_target_calls->aspace; -+ address_space *aspace = inf_for_target_calls->aspace.get (); - regcache *regcache = get_thread_arch_aspace_regcache (inf_for_target_calls, - ptid, arch, aspace); - -diff --git a/gdb/scoped-mock-context.h b/gdb/scoped-mock-context.h -index 9ad7ebf5f0c..5f25dc7ed6b 100644 ---- a/gdb/scoped-mock-context.h -+++ b/gdb/scoped-mock-context.h -@@ -38,7 +38,7 @@ struct scoped_mock_context - - Target mock_target; - ptid_t mock_ptid {1, 1}; -- program_space mock_pspace {new address_space ()}; -+ program_space mock_pspace {new_address_space ()}; - inferior mock_inferior {mock_ptid.pid ()}; - thread_info mock_thread {&mock_inferior, mock_ptid}; - -diff --git a/gdb/target-dcache.c b/gdb/target-dcache.c -index 13c2888e7ea..b1b772ab76e 100644 ---- a/gdb/target-dcache.c -+++ b/gdb/target-dcache.c -@@ -33,7 +33,7 @@ int - target_dcache_init_p (void) - { - DCACHE *dcache -- = target_dcache_aspace_key.get (current_program_space->aspace); -+ = target_dcache_aspace_key.get (current_program_space->aspace.get ()); - - return (dcache != NULL); - } -@@ -44,7 +44,7 @@ void - target_dcache_invalidate (void) - { - DCACHE *dcache -- = target_dcache_aspace_key.get (current_program_space->aspace); -+ = target_dcache_aspace_key.get (current_program_space->aspace.get ()); - - if (dcache != NULL) - dcache_invalidate (dcache); -@@ -56,7 +56,7 @@ target_dcache_invalidate (void) - DCACHE * - target_dcache_get (void) - { -- return target_dcache_aspace_key.get (current_program_space->aspace); -+ return target_dcache_aspace_key.get (current_program_space->aspace.get ()); - } - - /* Return the target dcache. If it is not initialized yet, initialize -@@ -66,12 +66,13 @@ DCACHE * - target_dcache_get_or_init (void) - { - DCACHE *dcache -- = target_dcache_aspace_key.get (current_program_space->aspace); -+ = target_dcache_aspace_key.get (current_program_space->aspace.get ()); - - if (dcache == NULL) - { - dcache = dcache_init (); -- target_dcache_aspace_key.set (current_program_space->aspace, dcache); -+ target_dcache_aspace_key.set (current_program_space->aspace.get (), -+ dcache); - } - - return dcache; -diff --git a/gdbsupport/refcounted-object.h b/gdbsupport/refcounted-object.h -index d8fdb950043..294fd873df1 100644 ---- a/gdbsupport/refcounted-object.h -+++ b/gdbsupport/refcounted-object.h -@@ -67,4 +67,21 @@ struct refcounted_object_ref_policy - } - }; - -+/* A policy class to interface gdb::ref_ptr with a refcounted_object, that -+ deletes the object once the refcount reaches 0.. */ -+ -+template -+struct refcounted_object_delete_ref_policy -+{ -+ static void incref (T *obj) -+ { obj->incref (); } -+ -+ static void decref (T *obj) -+ { -+ obj->decref (); -+ if (obj->refcount () == 0) -+ delete obj; -+ } -+}; -+ - #endif /* COMMON_REFCOUNTED_OBJECT_H */ - -base-commit: 0bb6f49bb9ad577667075550ca2ad4cb49931078 --- -2.35.3 - diff --git a/gdb-fix-segfault-in-for_each_block-part-2.patch b/gdb-fix-segfault-in-for_each_block-part-2.patch deleted file mode 100644 index 00df214..0000000 --- a/gdb-fix-segfault-in-for_each_block-part-2.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 3490f51a80a10d46dc1885ba672d9390a8221170 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Thu, 2 Nov 2023 14:51:02 +0100 -Subject: [PATCH] Fix segfault in for_each_block, part 2 - -The previous commit describes PR gdb/30547, a segfault when running test-case -gdb.base/vfork-follow-parent.exp on powerpc64 (likewise on s390x). - -The root cause for the segmentation fault is that linux_is_uclinux gives an -incorrect result: it returns true instead of false. - -So, why does linux_is_uclinux: -... -int -linux_is_uclinux (void) -{ - CORE_ADDR dummy; - - return (target_auxv_search (AT_NULL, &dummy) > 0 - && target_auxv_search (AT_PAGESZ, &dummy) == 0); -... -return true? - -This is because ppc_linux_target_wordsize returns 4 instead of 8, causing -ppc_linux_nat_target::auxv_parse to misinterpret the auxv vector. - -So, why does ppc_linux_target_wordsize: -... -int -ppc_linux_target_wordsize (int tid) -{ - int wordsize = 4; - - /* Check for 64-bit inferior process. This is the case when the host is - 64-bit, and in addition the top bit of the MSR register is set. */ - long msr; - - errno = 0; - msr = (long) ptrace (PTRACE_PEEKUSER, tid, PT_MSR * 8, 0); - if (errno == 0 && ppc64_64bit_inferior_p (msr)) - wordsize = 8; - - return wordsize; -} -... -return 4? - -Specifically, we get this result because because tid == 0, so we get -errno == ESRCH. - -The tid == 0 is caused by the switch_to_no_thread in -handle_vfork_child_exec_or_exit: -... - /* Switch to no-thread while running clone_program_space, so - that clone_program_space doesn't want to read the - selected frame of a dead process. */ - scoped_restore_current_thread restore_thread; - switch_to_no_thread (); - - inf->pspace = new program_space (maybe_new_address_space ()); -... -but moving the maybe_new_address_space call to before that gives us the -same result. The tid is no longer 0, but we still get ESRCH because the -thread has exited. - -Fix this in handle_vfork_child_exec_or_exit by doing the -maybe_new_address_space call in the context of the vfork parent. - -Tested on top of trunk on x86_64-linux and ppc64le-linux. -Tested on top of gdb-14-branch on ppc64-linux. - -Co-Authored-By: Simon Marchi - -PR gdb/30547 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30547 ---- - gdb/infrun.c | 16 +++++++++++----- - gdb/nat/ppc-linux.c | 2 ++ - gdb/ppc-linux-nat.c | 2 ++ - gdb/s390-linux-nat.c | 5 ++++- - 4 files changed, 19 insertions(+), 6 deletions(-) - -diff --git a/gdb/infrun.c b/gdb/infrun.c -index 3854c66bf6c..d259e81df84 100644 ---- a/gdb/infrun.c -+++ b/gdb/infrun.c -@@ -1105,13 +1105,19 @@ handle_vfork_child_exec_or_exit (int exec) - go ahead and create a new one for this exiting - inferior. */ - -- /* Switch to no-thread while running clone_program_space, so -- that clone_program_space doesn't want to read the -- selected frame of a dead process. */ - scoped_restore_current_thread restore_thread; -- switch_to_no_thread (); - -- inf->pspace = new program_space (maybe_new_address_space ()); -+ /* Temporarily switch to the vfork parent, to facilitate ptrace -+ calls done during maybe_new_address_space. */ -+ switch_to_thread (any_live_thread_of_inferior (vfork_parent)); -+ address_space_ref_ptr aspace = maybe_new_address_space (); -+ -+ /* Switch back to the vfork child inferior. Switch to no-thread -+ while running clone_program_space, so that clone_program_space -+ doesn't want to read the selected frame of a dead process. */ -+ switch_to_inferior_no_thread (inf); -+ -+ inf->pspace = new program_space (std::move (aspace)); - inf->aspace = inf->pspace->aspace; - set_current_program_space (inf->pspace); - inf->removable = true; -diff --git a/gdb/nat/ppc-linux.c b/gdb/nat/ppc-linux.c -index 0957d1b58a7..74549754806 100644 ---- a/gdb/nat/ppc-linux.c -+++ b/gdb/nat/ppc-linux.c -@@ -78,6 +78,8 @@ ppc64_64bit_inferior_p (long msr) - int - ppc_linux_target_wordsize (int tid) - { -+ gdb_assert (tid != 0); -+ - int wordsize = 4; - - /* Check for 64-bit inferior process. This is the case when the host is -diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c -index d14aba694e5..817505ea73e 100644 ---- a/gdb/ppc-linux-nat.c -+++ b/gdb/ppc-linux-nat.c -@@ -1914,6 +1914,8 @@ ppc_linux_nat_target::auxv_parse (const gdb_byte **readptr, - const gdb_byte *endptr, CORE_ADDR *typep, - CORE_ADDR *valp) - { -+ gdb_assert (inferior_ptid != null_ptid); -+ - int tid = inferior_ptid.lwp (); - if (tid == 0) - tid = inferior_ptid.pid (); -diff --git a/gdb/s390-linux-nat.c b/gdb/s390-linux-nat.c -index 8f54e9f6322..54167f49480 100644 ---- a/gdb/s390-linux-nat.c -+++ b/gdb/s390-linux-nat.c -@@ -949,10 +949,12 @@ s390_target_wordsize (void) - /* Check for 64-bit inferior process. This is the case when the host is - 64-bit, and in addition bit 32 of the PSW mask is set. */ - #ifdef __s390x__ -+ int tid = s390_inferior_tid (); -+ gdb_assert (tid != 0); - long pswm; - - errno = 0; -- pswm = (long) ptrace (PTRACE_PEEKUSER, s390_inferior_tid (), PT_PSWMASK, 0); -+ pswm = (long) ptrace (PTRACE_PEEKUSER, tid, PT_PSWMASK, 0); - if (errno == 0 && (pswm & 0x100000000ul) != 0) - wordsize = 8; - #endif -@@ -965,6 +967,7 @@ s390_linux_nat_target::auxv_parse (const gdb_byte **readptr, - const gdb_byte *endptr, CORE_ADDR *typep, - CORE_ADDR *valp) - { -+ gdb_assert (inferior_ptid != null_ptid); - int sizeof_auxv_field = s390_target_wordsize (); - enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); - const gdb_byte *ptr = *readptr; - -base-commit: 1d02ba0f4adcba2595a67e88fb1ba6d35c7f8e5b --- -2.35.3 - diff --git a/gdb-ftbs-swapped-calloc-args.patch b/gdb-ftbs-swapped-calloc-args.patch deleted file mode 100644 index 30d4a4a..0000000 --- a/gdb-ftbs-swapped-calloc-args.patch +++ /dev/null @@ -1,42 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Kevin Buettner -Date: Wed, 17 Jan 2024 12:53:53 -0700 -Subject: gdb-ftbs-swapped-calloc-args.patch - -Backport upstream commit 54195469c18ec9873cc5ba6907f768509473fa9b -which fixes a build problem in which arguments to calloc were swapped. - -[opcodes] ARC + PPC: Fix -Walloc-size warnings - -Recently, -Walloc-size warnings started to kick in. Fix these two -calloc() calls to match the intended usage pattern. - -opcodes/ChangeLog: - - * arc-dis.c (init_arc_disasm_info): Fix calloc() call. - * ppc-dis.c (powerpc_init_dialect): Ditto. - -diff --git a/opcodes/arc-dis.c b/opcodes/arc-dis.c ---- a/opcodes/arc-dis.c -+++ b/opcodes/arc-dis.c -@@ -147,7 +147,7 @@ static bool - init_arc_disasm_info (struct disassemble_info *info) - { - struct arc_disassemble_info *arc_infop -- = calloc (sizeof (*arc_infop), 1); -+ = calloc (1, sizeof (*arc_infop)); - - if (arc_infop == NULL) - return false; -diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c ---- a/opcodes/ppc-dis.c -+++ b/opcodes/ppc-dis.c -@@ -348,7 +348,7 @@ powerpc_init_dialect (struct disassemble_info *info) - { - ppc_cpu_t dialect = 0; - ppc_cpu_t sticky = 0; -- struct dis_private *priv = calloc (sizeof (*priv), 1); -+ struct dis_private *priv = calloc (1, sizeof (*priv)); - - if (priv == NULL) - return; diff --git a/gdb-gcore-bash.patch b/gdb-gcore-bash.patch index 724b5ea..b2b14fd 100644 --- a/gdb-gcore-bash.patch +++ b/gdb-gcore-bash.patch @@ -6,5 +6,5 @@ index b9770ea415..3149f6e1fe 100644 -#!/usr/bin/env bash +#!/bin/bash - # Copyright (C) 2003-2023 Free Software Foundation, Inc. + # Copyright (C) 2003-2024 Free Software Foundation, Inc. diff --git a/gdb-glibc-strstr-workaround.patch b/gdb-glibc-strstr-workaround.patch deleted file mode 100644 index c2f50ff..0000000 --- a/gdb-glibc-strstr-workaround.patch +++ /dev/null @@ -1,132 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Fedora GDB patches -Date: Fri, 27 Oct 2017 21:07:50 +0200 -Subject: gdb-glibc-strstr-workaround.patch - -;; Workaround PR libc/14166 for inferior calls of strstr. -;;=fedoratest: Compatibility with RHELs (unchecked which ones). - -diff --git a/gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp b/gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp -@@ -0,0 +1,119 @@ -+# Copyright (C) 2012 Free Software Foundation, Inc. -+ -+# 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 . -+ -+# Workaround for: -+# invalid IFUNC DW_AT_linkage_name: memmove strstr time -+# http://sourceware.org/bugzilla/show_bug.cgi?id=14166 -+ -+if {[skip_shlib_tests]} { -+ return 0 -+} -+ -+set testfile "gnu-ifunc-strstr-workaround" -+set executable ${testfile} -+set srcfile start.c -+set binfile [standard_output_file ${executable}] -+ -+if [prepare_for_testing ${testfile}.exp $executable $srcfile] { -+ return -1 -+} -+ -+if ![runto_main] { -+ return 0 -+} -+ -+set test "ptype atoi" -+gdb_test_multiple $test $test { -+ -re "type = int \\(const char \\*\\)\r\n$gdb_prompt $" { -+ pass $test -+ } -+ -re "type = int \\(\\)\r\n$gdb_prompt $" { -+ untested "$test (no DWARF)" -+ return 0 -+ } -+ -re "type = \\(\\)\r\n$gdb_prompt $" { -+ untested "$test (no DWARF)" -+ return 0 -+ } -+} -+ -+set addr "" -+set test "print strstr" -+gdb_test_multiple $test $test { -+ -re " = {} (0x\[0-9a-f\]+) \r\n$gdb_prompt $" { -+ set addr $expect_out(1,string) -+ pass $test -+ } -+ -re " = {} (0x\[0-9a-f\]+) <__strstr>\r\n$gdb_prompt $" { -+ set addr $expect_out(1,string) -+ pass "$test (GDB workaround)" -+ } -+ -re " = {} (0x\[0-9a-f\]+) <__libc_strstr>\r\n$gdb_prompt $" { -+ set addr $expect_out(1,string) -+ pass "$test (fixed glibc)" -+ } -+ -re " = {} (0x\[0-9a-f\]+) <__libc_strstr_ifunc>\r\n$gdb_prompt $" { -+ set addr $expect_out(1,string) -+ pass "$test (fixed glibc)" -+ } -+ -re " = {char \\*\\(const char \\*, const char \\*\\)} 0x\[0-9a-f\]+ \r\n$gdb_prompt $" { -+ untested "$test (gnu-ifunc not in use by glibc)" -+ return 0 -+ } -+} -+ -+set test "info sym" -+gdb_test_multiple "info sym $addr" $test { -+ -re "strstr in section \\.text of /lib\[^/\]*/libc.so.6\r\n$gdb_prompt $" { -+ pass $test -+ } -+ -re " = {char \\*\\(const char \\*, const char \\*\\)} 0x\[0-9a-f\]+ \r\n$gdb_prompt $" { -+ # unexpected -+ xfail "$test (not in libc.so.6)" -+ return 0 -+ } -+} -+ -+set test "info addr strstr" -+gdb_test_multiple $test $test { -+ -re "Symbol \"strstr\" is a function at address $addr\\.\r\n$gdb_prompt $" { -+ fail "$test (DWARF for strstr)" -+ } -+ -re "Symbol \"strstr\" is at $addr in a file compiled without debugging\\.\r\n$gdb_prompt $" { -+ pass "$test" -+ } -+} -+ -+set test "print strstr second time" -+gdb_test_multiple "print strstr" $test { -+ -re " = {} $addr \r\n$gdb_prompt $" { -+ pass $test -+ } -+ -re " = {} $addr <__strstr>\r\n$gdb_prompt $" { -+ pass "$test (GDB workaround)" -+ } -+ -re " = {} $addr <__libc_strstr>\r\n$gdb_prompt $" { -+ pass "$test (fixed glibc)" -+ } -+ -re " = {} $addr <__libc_strstr_ifunc>\r\n$gdb_prompt $" { -+ pass "$test (fixed glibc)" -+ } -+ -re " = {void \\*\\(void\\)} 0x\[0-9a-f\]+ \r\n$gdb_prompt $" { -+ fail $test -+ } -+} -+ -+gdb_test {print (char *)strstr("abc","b")} { = 0x[0-9a-f]+ "bc"} -+gdb_test {print (char *)strstr("def","e")} { = 0x[0-9a-f]+ "ef"} diff --git a/gdb-guile-use-scm_debug_typing_strictness-0.patch b/gdb-guile-use-scm_debug_typing_strictness-0.patch new file mode 100644 index 0000000..ba84612 --- /dev/null +++ b/gdb-guile-use-scm_debug_typing_strictness-0.patch @@ -0,0 +1,68 @@ +From fe0e6edbcb65ab5eca50c1a0ad8ddc9844f8ea98 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Mon, 27 Jan 2025 09:23:18 +0100 +Subject: [PATCH] [gdb/guile] Use SCM_DEBUG_TYPING_STRICTNESS 0 + +I build gdb with libguile v2.0.9, and ran into: +... +In file included from /usr/include/guile/2.0/libguile.h:56, + from ../../gdb/guile/guile-internal.h:30, + from ../../gdb/guile/scm-arch.c:26: +/usr/include/guile/2.0/libguile/inline.h: In function 'int scm_is_pair(SCM)': +/usr/include/guile/2.0/libguile/tags.h:97:53: error: \ + operation on '*0' may be undefined [-Werror=sequence-point] + # define SCM_UNPACK(x) ((scm_t_bits) (0? (*(SCM*)0=(x)): x)) + ~~~~~~~~~^~~~~ +... + +Fix this by using SCM_DEBUG_TYPING_STRICTNESS 0. + +We were already using this for c++20 due to a Werror=volatile in SCM_UNPACK +when using libguile v2.0.10. + +Tested on x86_64-linux. +--- + gdb/guile/guile-internal.h | 22 +++++++++++++++++++++- + 1 file changed, 21 insertions(+), 1 deletion(-) + +diff --git a/gdb/guile/guile-internal.h b/gdb/guile/guile-internal.h +index be16fee0dd2..6665bfc7813 100644 +--- a/gdb/guile/guile-internal.h ++++ b/gdb/guile/guile-internal.h +@@ -27,10 +27,30 @@ + #include "hashtab.h" + #include "extension-priv.h" + #include "symtab.h" +-#include "libguile.h" + #include "objfiles.h" + #include "top.h" + ++/* For libguile v2.0.9 and SCM_DEBUG_TYPING_STRICTNESS == 1, SCM_UNPACK(x) is ++ defined as: ++ ++ ((scm_t_bits) (0? (*(SCM*)0=(x)): x)) ++ ++ and for v2.0.10 it's defined as: ++ ++ ((scm_t_bits) (0? (*(volatile SCM *)0=(x)): x)) ++ ++ The volatile was added to avoid a clang warning. ++ ++ The latter form causes a Werror=volatile with C++20. ++ This was reported upstream ( ++ https://debbugs.gnu.org/cgi/bugreport.cgi?bug=65333 ). ++ ++ The former form causes a Werror=sequence-point with gcc 7-14. ++ ++ Work around these problem by using SCM_DEBUG_TYPING_STRICTNESS == 0. */ ++#define SCM_DEBUG_TYPING_STRICTNESS 0 ++#include "libguile.h" ++ + struct block; + struct frame_info; + struct objfile; + +base-commit: 94df6741bbabaa9a51960446b2af4c0bed01b54b +-- +2.43.0 + diff --git a/gdb-linux_perf-bundle.patch b/gdb-linux_perf-bundle.patch deleted file mode 100644 index 36dbe9f..0000000 --- a/gdb-linux_perf-bundle.patch +++ /dev/null @@ -1,226 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Fedora GDB patches -Date: Fri, 27 Oct 2017 21:07:50 +0200 -Subject: gdb-linux_perf-bundle.patch - -;; [dts+el7] [x86*] Bundle linux_perf.h for libipt (RH BZ 1256513). -;;=fedora - -diff --git a/gdb/gdb.c b/gdb/gdb.c ---- a/gdb/gdb.c -+++ b/gdb/gdb.c -@@ -21,6 +21,10 @@ - #include "interps.h" - #include "run-on-main-thread.h" - -+#ifdef PERF_ATTR_SIZE_VER5_BUNDLE -+extern "C" void __libipt_init(void); -+#endif -+ - int - main (int argc, char **argv) - { -@@ -32,6 +36,10 @@ main (int argc, char **argv) - - struct captured_main_args args; - -+#ifdef PERF_ATTR_SIZE_VER5_BUNDLE -+ __libipt_init(); -+#endif -+ - memset (&args, 0, sizeof args); - args.argc = argc; - args.argv = argv; -diff --git a/gdb/nat/linux-btrace.h b/gdb/nat/linux-btrace.h ---- a/gdb/nat/linux-btrace.h -+++ b/gdb/nat/linux-btrace.h -@@ -28,6 +28,177 @@ - # include - #endif - -+#ifdef PERF_ATTR_SIZE_VER5_BUNDLE -+#ifndef HAVE_LINUX_PERF_EVENT_H -+# error "PERF_ATTR_SIZE_VER5_BUNDLE && !HAVE_LINUX_PERF_EVENT_H" -+#endif -+#ifndef PERF_ATTR_SIZE_VER5 -+#define PERF_ATTR_SIZE_VER5 -+#define perf_event_mmap_page perf_event_mmap_page_bundle -+// kernel-headers-3.10.0-493.el7.x86_64/usr/include/linux/perf_event.h -+/* -+ * Structure of the page that can be mapped via mmap -+ */ -+struct perf_event_mmap_page { -+ __u32 version; /* version number of this structure */ -+ __u32 compat_version; /* lowest version this is compat with */ -+ -+ /* -+ * Bits needed to read the hw events in user-space. -+ * -+ * u32 seq, time_mult, time_shift, index, width; -+ * u64 count, enabled, running; -+ * u64 cyc, time_offset; -+ * s64 pmc = 0; -+ * -+ * do { -+ * seq = pc->lock; -+ * barrier() -+ * -+ * enabled = pc->time_enabled; -+ * running = pc->time_running; -+ * -+ * if (pc->cap_usr_time && enabled != running) { -+ * cyc = rdtsc(); -+ * time_offset = pc->time_offset; -+ * time_mult = pc->time_mult; -+ * time_shift = pc->time_shift; -+ * } -+ * -+ * index = pc->index; -+ * count = pc->offset; -+ * if (pc->cap_user_rdpmc && index) { -+ * width = pc->pmc_width; -+ * pmc = rdpmc(index - 1); -+ * } -+ * -+ * barrier(); -+ * } while (pc->lock != seq); -+ * -+ * NOTE: for obvious reason this only works on self-monitoring -+ * processes. -+ */ -+ __u32 lock; /* seqlock for synchronization */ -+ __u32 index; /* hardware event identifier */ -+ __s64 offset; /* add to hardware event value */ -+ __u64 time_enabled; /* time event active */ -+ __u64 time_running; /* time event on cpu */ -+ union { -+ __u64 capabilities; -+ struct { -+ __u64 cap_bit0 : 1, /* Always 0, deprecated, see commit 860f085b74e9 */ -+ cap_bit0_is_deprecated : 1, /* Always 1, signals that bit 0 is zero */ -+ -+ cap_user_rdpmc : 1, /* The RDPMC instruction can be used to read counts */ -+ cap_user_time : 1, /* The time_* fields are used */ -+ cap_user_time_zero : 1, /* The time_zero field is used */ -+ cap_____res : 59; -+ }; -+ }; -+ -+ /* -+ * If cap_user_rdpmc this field provides the bit-width of the value -+ * read using the rdpmc() or equivalent instruction. This can be used -+ * to sign extend the result like: -+ * -+ * pmc <<= 64 - width; -+ * pmc >>= 64 - width; // signed shift right -+ * count += pmc; -+ */ -+ __u16 pmc_width; -+ -+ /* -+ * If cap_usr_time the below fields can be used to compute the time -+ * delta since time_enabled (in ns) using rdtsc or similar. -+ * -+ * u64 quot, rem; -+ * u64 delta; -+ * -+ * quot = (cyc >> time_shift); -+ * rem = cyc & (((u64)1 << time_shift) - 1); -+ * delta = time_offset + quot * time_mult + -+ * ((rem * time_mult) >> time_shift); -+ * -+ * Where time_offset,time_mult,time_shift and cyc are read in the -+ * seqcount loop described above. This delta can then be added to -+ * enabled and possible running (if index), improving the scaling: -+ * -+ * enabled += delta; -+ * if (index) -+ * running += delta; -+ * -+ * quot = count / running; -+ * rem = count % running; -+ * count = quot * enabled + (rem * enabled) / running; -+ */ -+ __u16 time_shift; -+ __u32 time_mult; -+ __u64 time_offset; -+ /* -+ * If cap_usr_time_zero, the hardware clock (e.g. TSC) can be calculated -+ * from sample timestamps. -+ * -+ * time = timestamp - time_zero; -+ * quot = time / time_mult; -+ * rem = time % time_mult; -+ * cyc = (quot << time_shift) + (rem << time_shift) / time_mult; -+ * -+ * And vice versa: -+ * -+ * quot = cyc >> time_shift; -+ * rem = cyc & (((u64)1 << time_shift) - 1); -+ * timestamp = time_zero + quot * time_mult + -+ * ((rem * time_mult) >> time_shift); -+ */ -+ __u64 time_zero; -+ __u32 size; /* Header size up to __reserved[] fields. */ -+ -+ /* -+ * Hole for extension of the self monitor capabilities -+ */ -+ -+ __u8 __reserved[118*8+4]; /* align to 1k. */ -+ -+ /* -+ * Control data for the mmap() data buffer. -+ * -+ * User-space reading the @data_head value should issue an smp_rmb(), -+ * after reading this value. -+ * -+ * When the mapping is PROT_WRITE the @data_tail value should be -+ * written by userspace to reflect the last read data, after issueing -+ * an smp_mb() to separate the data read from the ->data_tail store. -+ * In this case the kernel will not over-write unread data. -+ * -+ * See perf_output_put_handle() for the data ordering. -+ * -+ * data_{offset,size} indicate the location and size of the perf record -+ * buffer within the mmapped area. -+ */ -+ __u64 data_head; /* head in the data section */ -+ __u64 data_tail; /* user-space written tail */ -+ __u64 data_offset; /* where the buffer starts */ -+ __u64 data_size; /* data buffer size */ -+ -+ /* -+ * AUX area is defined by aux_{offset,size} fields that should be set -+ * by the userspace, so that -+ * -+ * aux_offset >= data_offset + data_size -+ * -+ * prior to mmap()ing it. Size of the mmap()ed area should be aux_size. -+ * -+ * Ring buffer pointers aux_{head,tail} have the same semantics as -+ * data_{head,tail} and same ordering rules apply. -+ */ -+ __u64 aux_head; -+ __u64 aux_tail; -+ __u64 aux_offset; -+ __u64 aux_size; -+}; -+#endif // PERF_ATTR_SIZE_VER5 -+#endif // PERF_ATTR_SIZE_VER5_BUNDLE -+ - struct target_ops; - - #if HAVE_LINUX_PERF_EVENT_H -diff --git a/gdbsupport/common.m4 b/gdbsupport/common.m4 ---- a/gdbsupport/common.m4 -+++ b/gdbsupport/common.m4 -@@ -168,7 +168,7 @@ AC_DEFUN([GDB_AC_COMMON], [ - AC_PREPROC_IFELSE([AC_LANG_SOURCE([[ - #include - #ifndef PERF_ATTR_SIZE_VER5 -- # error -+ // error // PERF_ATTR_SIZE_VER5_BUNDLE is not available here - Fedora+RHEL - #endif - ]])], [perf_event=yes], [perf_event=no]) - if test "$perf_event" != yes; then diff --git a/gdb-prune-inferior-after-switching-inferior.patch b/gdb-prune-inferior-after-switching-inferior.patch new file mode 100644 index 0000000..a5de740 --- /dev/null +++ b/gdb-prune-inferior-after-switching-inferior.patch @@ -0,0 +1,130 @@ +From 22d05b4879b8608e3768483735140a729952b565 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Sun, 18 Aug 2024 20:51:29 +0200 +Subject: [PATCH 39/46] [gdb] Prune inferior after switching inferior + +Usually with test-case gdb.python/py-progspace-events.exp I get: +... +(gdb) inferior 1^M +[Switching to inferior 1 [process 4116] (py-progspace-events)]^M +[Switching to thread 1.1 (Thread 0xf77d0ce0 (LWP 4116))]^M +28 { /* Nothing. */ }^M +(gdb) PASS: gdb.python/py-progspace-events.exp: inferior 1 +step^M +FreeProgspaceEvent: ^M +do_parent_stuff () at py-progspace-events.c:41^M +41 ++global_var;^M +(gdb) PASS: gdb.python/py-progspace-events.exp: step +... + +But occasionally I run into the following FAIL: +... +(gdb) inferior 1^M +[Switching to inferior 1 [process 5199] (py-progspace-events)]^M +[Switching to thread 1.1 (Thread 0xf77d0ce0 (LWP 5199))]^M +28 { /* Nothing. */ }^M +(gdb) FreeProgspaceEvent: ^M +FAIL: gdb.python/py-progspace-events.exp: inferior 1 (timeout) +... + +This is caused by a race between the handling of an event, and the +"inferior 1" command. + +In the passing case, the event is handled first. During which prune_inferiors +is called, but it can't remove inferior 2, because it's still the current one. + +In the failing case, the "inferior 1" command is handled first. Then during +handling of the event, prune_inferiors is called, and it can remove inferior 2 +because it's no longer the current one. + +This looks like a test-case issue to me, but ISTM that we can do better: by +calling prune_inferiors asap, at the end of the "inferior 1" command, we +stabilize the moment when the inferior is removed: +... +(gdb) inferior 1^M +[Switching to inferior 1 [process 5199] (py-progspace-events)]^M +[Switching to thread 1.1 (Thread 0xf77d0ce0 (LWP 5199))]^M +28 { /* Nothing. */ }^M +FreeProgspaceEvent: ^M +(gdb) PASS: gdb.python/py-progspace-events.exp: inferior 1 +... + +This also allows us to simplify the test-case by removing the step command, +which is no longer required to trigger the pruning of the inferior. + +Tested on x86_64-linux. + +Approved-by: Kevin Buettner + +PR gdb/31440 +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31440 +--- + gdb/inferior.c | 4 +++ + .../gdb.python/py-progspace-events.exp | 31 +++---------------- + 2 files changed, 9 insertions(+), 26 deletions(-) + +diff --git a/gdb/inferior.c b/gdb/inferior.c +index 0522cb5c14d..2a19c5b19a1 100644 +--- a/gdb/inferior.c ++++ b/gdb/inferior.c +@@ -790,6 +790,10 @@ inferior_command (const char *args, int from_tty) + notify_user_selected_context_changed + (USER_SELECTED_INFERIOR); + } ++ ++ /* Switching current inferior may have made one of the inferiors ++ prunable, so prune it. */ ++ prune_inferiors (); + } + } + +diff --git a/gdb/testsuite/gdb.python/py-progspace-events.exp b/gdb/testsuite/gdb.python/py-progspace-events.exp +index 95e4ca8da0b..9dfc7573d40 100644 +--- a/gdb/testsuite/gdb.python/py-progspace-events.exp ++++ b/gdb/testsuite/gdb.python/py-progspace-events.exp +@@ -79,37 +79,16 @@ gdb_test "continue" \ + "\\\[Inferior $decimal \[^\r\n\]+ exited normally\\\]"] \ + "continue until inferior 2 exits" + +-gdb_test "inferior 1" "\\\[Switching to inferior 1 .*" +- +-# Step the inferior. During this process GDB will prune the now ++# Switch to inferior 1. During this process GDB will prune the now + # defunct inferior, which deletes its program space, which should + # trigger the FreeProgspaceEvent. + # +-# However, there is a slight problem. When the target is remote, and +-# GDB is accessing files using remote fileio, then GDB will attempt to +-# prune the inferior at a point in time when the remote target is +-# waiting for a stop reply. Pruning an inferior causes GDB to close +-# files associated with that inferior. +-# +-# In non-async mode we can't send fileio packets while waiting for a +-# stop reply, so the attempts to close files fails, and this shows up +-# as an error. +-# +-# As this error has nothing to do with the feature being tested here, +-# we just accept the error message, the important part is the +-# 'FreeProgspaceEvent' string, so long as that appears (just once) +-# then the test is a success. +-set warning_msg \ +- [multi_line \ +- "warning: cannot close \"\[^\r\n\]+\": Cannot execute this command while the target is running\\." \ +- "Use the \"interrupt\" command to stop the target" \ +- "and then try again\\."] + +-gdb_test "step" \ ++gdb_test "inferior 1" \ + [multi_line \ +- "^FreeProgspaceEvent.*: (?:\r\n$warning_msg)*" \ +- "do_parent_stuff \\(\\) at \[^\r\n\]+" \ +- "$decimal\\s+\[^\r\n\]+"] ++ "\\\[Switching to inferior 1 .*" \ ++ ".*" \ ++ "FreeProgspaceEvent.*: "] + + # Let this inferior run to completion. + gdb_continue_to_end +-- +2.43.0 + diff --git a/gdb-python-finishbreakpoint-update.patch b/gdb-python-finishbreakpoint-update.patch index 0638499..8132b3d 100644 --- a/gdb-python-finishbreakpoint-update.patch +++ b/gdb-python-finishbreakpoint-update.patch @@ -1,7 +1,7 @@ -From adfcabe4cc43766996a61bdf08ce1e9db7f18dcc Mon Sep 17 00:00:00 2001 +From 086a725aa02b1195f63b2df4c2a2b4516788b2c6 Mon Sep 17 00:00:00 2001 From: Tom de Vries Date: Thu, 18 Apr 2024 14:27:04 +0200 -Subject: [PATCH] gdb-python-finishbreakpoint-update +Subject: [PATCH 42/46] gdb-python-finishbreakpoint-update [gdb/python] FinishBreakPoint update @@ -337,10 +337,10 @@ and running the test-cases: 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c -index db7d2e6a8e5..01f187ca4fe 100644 +index 5653842ce76..6e10914a316 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c -@@ -14683,6 +14683,10 @@ breakpoint_free_objfile (struct objfile *objfile) +@@ -14693,6 +14693,10 @@ breakpoint_free_objfile (struct objfile *objfile) static struct cmd_list_element *enablebreaklist = NULL; @@ -351,7 +351,7 @@ index db7d2e6a8e5..01f187ca4fe 100644 /* See breakpoint.h. */ cmd_list_element *commands_cmd_element = nullptr; -@@ -15243,8 +15247,14 @@ This is useful for formatted output in user-defined commands.")); +@@ -15255,8 +15259,14 @@ This is useful for formatted output in user-defined commands.")); gdb::observers::about_to_proceed.attach (breakpoint_about_to_proceed, "breakpoint"); @@ -367,10 +367,10 @@ index db7d2e6a8e5..01f187ca4fe 100644 "breakpoint"); } diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi -index 99670cca025..ba414b4e2c3 100644 +index 86ccc140c6d..e49cc580b1b 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi -@@ -6648,7 +6648,7 @@ is not writable. +@@ -6882,7 +6882,7 @@ is not writable. @tindex gdb.FinishBreakpoint A finish breakpoint is a temporary breakpoint set at the return address of @@ -379,7 +379,7 @@ index 99670cca025..ba414b4e2c3 100644 extends @code{gdb.Breakpoint}. The underlying breakpoint will be disabled and deleted when the execution will run out of the breakpoint scope (i.e.@: @code{Breakpoint.stop} or @code{FinishBreakpoint.out_of_scope} triggered). -@@ -6667,7 +6667,9 @@ details about this argument. +@@ -6901,7 +6901,9 @@ details about this argument. In some circumstances (e.g.@: @code{longjmp}, C@t{++} exceptions, @value{GDBN} @code{return} command, @dots{}), a function may not properly terminate, and thus never hit the finish breakpoint. When @value{GDBN} notices such a @@ -391,7 +391,7 @@ index 99670cca025..ba414b4e2c3 100644 You may want to sub-class @code{gdb.FinishBreakpoint} and override this method: diff --git a/gdb/python/py-finishbreakpoint.c b/gdb/python/py-finishbreakpoint.c -index 42a7e0706d2..fa7ec43fbb4 100644 +index c74a2473a81..957d4ebc142 100644 --- a/gdb/python/py-finishbreakpoint.c +++ b/gdb/python/py-finishbreakpoint.c @@ -433,6 +433,24 @@ bpfinishpy_handle_exit (struct inferior *inf) @@ -402,9 +402,9 @@ index 42a7e0706d2..fa7ec43fbb4 100644 + scope notifications. */ + +static void -+bpfinishpy_handle_thread_exit (struct thread_info *tp, gdb::optional, bool) ++bpfinishpy_handle_thread_exit (struct thread_info *tp, std::optional, bool) +{ -+ gdbpy_enter enter_py (target_gdbarch (), current_language); ++ gdbpy_enter enter_py (target_thread_architecture (tp->ptid), current_language); + + for (breakpoint &bp : all_breakpoints_safe ()) + { @@ -429,7 +429,7 @@ index 42a7e0706d2..fa7ec43fbb4 100644 return 0; } diff --git a/gdb/testsuite/gdb.python/py-finish-breakpoint2.exp b/gdb/testsuite/gdb.python/py-finish-breakpoint2.exp -index 66587b8b9a0..31479a05e6f 100644 +index b837bb3a108..7d99aad2fd2 100644 --- a/gdb/testsuite/gdb.python/py-finish-breakpoint2.exp +++ b/gdb/testsuite/gdb.python/py-finish-breakpoint2.exp @@ -87,6 +87,7 @@ if { $need_continue } { @@ -440,8 +440,6 @@ index 66587b8b9a0..31479a05e6f 100644 gdb_test "python ExceptionFinishBreakpoint(gdb.newest_frame())" \ "init ExceptionFinishBreakpoint" "set FinishBP after the exception again" - -base-commit: 6de9111c512de99fd8cb3ea89f9890b1d72f6ef0 -- -2.35.3 +2.43.0 diff --git a/gdb-python-fix-gdb.python-py-disasm.exp-on-arm-linux.patch b/gdb-python-fix-gdb.python-py-disasm.exp-on-arm-linux.patch deleted file mode 100644 index a8e39f6..0000000 --- a/gdb-python-fix-gdb.python-py-disasm.exp-on-arm-linux.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 4c7dab250c3581e691c2da87395e80244074d8bf Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Mon, 10 Jun 2024 17:53:30 +0200 -Subject: [PATCH] [gdb/python] Fix gdb.python/py-disasm.exp on arm-linux - -After fixing test-case gdb.python/py-disasm.exp to recognize the arm nop: -... - nop {0} -... -we run into: -... -disassemble test^M -Dump of assembler code for function test:^M - 0x004004d8 <+0>: push {r11} @ (str r11, [sp, #-4]!)^M - 0x004004dc <+4>: add r11, sp, #0^M - 0x004004e0 <+8>: nop {0}^M -=> 0x004004e4 <+12>: Python Exception : Buffer \ - returned from read_memory is sized 0 instead of the expected 4^M -^M -unknown disassembler error (error = -1)^M -(gdb) FAIL: $exp: global_disassembler=ShowInfoRepr: disassemble test -... - -This is caused by this code in gdbpy_disassembler::read_memory_func: -... - gdbpy_ref<> result_obj (PyObject_CallMethod ((PyObject *) obj, - "read_memory", - "KL", len, offset)); -... -where len has type "unsigned int", while "K" means "unsigned long long" [1]. - -Fix this by using "I" instead, meaning "unsigned int". - -Also, offset has type LONGEST, which is typedef'ed to int64_t, while "L" means -"long long". - -Fix this by using type gdb_py_longest for offset, in combination with format -character "GDB_PY_LL_ARG". Likewise in disasmpy_info_read_memory. - -Tested on arm-linux. - -Reviewed-By: Alexandra Petlanova Hajkova -Approved-By: Tom Tromey - -PR python/31845 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31845 - -[1] https://docs.python.org/3/c-api/arg.html - -(cherry picked from commit 4cd214dce4579f86a85a96c882e0fc8c4d94601c) ---- - gdb/python/py-disasm.c | 12 +++++++----- - gdb/testsuite/gdb.python/py-disasm.exp | 2 +- - gdb/testsuite/gdb.python/py-disasm.py | 2 +- - 3 files changed, 9 insertions(+), 7 deletions(-) - -diff --git a/gdb/python/py-disasm.c b/gdb/python/py-disasm.c -index 6f0fed137e6..b2e95b3cba6 100644 ---- a/gdb/python/py-disasm.c -+++ b/gdb/python/py-disasm.c -@@ -668,12 +668,13 @@ disasmpy_info_read_memory (PyObject *self, PyObject *args, PyObject *kw) - disasm_info_object *obj = (disasm_info_object *) self; - DISASMPY_DISASM_INFO_REQUIRE_VALID (obj); - -- LONGEST length, offset = 0; -+ gdb_py_longest length, offset = 0; - gdb::unique_xmalloc_ptr buffer; - static const char *keywords[] = { "length", "offset", nullptr }; - -- if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "L|L", keywords, -- &length, &offset)) -+ if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, -+ GDB_PY_LL_ARG "|" GDB_PY_LL_ARG, -+ keywords, &length, &offset)) - return nullptr; - - /* The apparent address from which we are reading memory. Note that in -@@ -850,13 +851,14 @@ gdbpy_disassembler::read_memory_func (bfd_vma memaddr, gdb_byte *buff, - /* The DisassembleInfo.read_memory method expects an offset from the - address stored within the DisassembleInfo object; calculate that - offset here. */ -- LONGEST offset = (LONGEST) memaddr - (LONGEST) obj->address; -+ gdb_py_longest offset -+ = (gdb_py_longest) memaddr - (gdb_py_longest) obj->address; - - /* Now call the DisassembleInfo.read_memory method. This might have been - overridden by the user. */ - gdbpy_ref<> result_obj (PyObject_CallMethod ((PyObject *) obj, - "read_memory", -- "KL", len, offset)); -+ "I" GDB_PY_LL_ARG, len, offset)); - - /* Handle any exceptions. */ - if (result_obj == nullptr) -diff --git a/gdb/testsuite/gdb.python/py-disasm.exp b/gdb/testsuite/gdb.python/py-disasm.exp -index f2f9225168a..9d0f6ec1d01 100644 ---- a/gdb/testsuite/gdb.python/py-disasm.exp -+++ b/gdb/testsuite/gdb.python/py-disasm.exp -@@ -65,7 +65,7 @@ proc py_remove_all_disassemblers {} { - # - # Each different disassembler tests some different feature of the - # Python disassembler API. --set nop "(nop|nop\t0)" -+set nop "(nop|nop\t0|[string_to_regexp nop\t{0}])" - set unknown_error_pattern "unknown disassembler error \\(error = -1\\)" - set addr_pattern "\r\n=> ${curr_pc_pattern} <\[^>\]+>:\\s+" - set base_pattern "${addr_pattern}${nop}" -diff --git a/gdb/testsuite/gdb.python/py-disasm.py b/gdb/testsuite/gdb.python/py-disasm.py -index 67ba6756ea9..6a39b0764e6 100644 ---- a/gdb/testsuite/gdb.python/py-disasm.py -+++ b/gdb/testsuite/gdb.python/py-disasm.py -@@ -46,7 +46,7 @@ def check_building_disassemble_result(): - - - def is_nop(s): -- return s == "nop" or s == "nop\t0" -+ return s == "nop" or s == "nop\t0" or s == "nop\t{0}" - - - # Remove all currently registered disassemblers. - -base-commit: 22383ac8031b0e626e8ecd62e4378266065d067c --- -2.35.3 - diff --git a/gdb-python-make-gdb.unwindinfo.add_saved_register-mo-fixup.patch b/gdb-python-make-gdb.unwindinfo.add_saved_register-mo-fixup.patch deleted file mode 100644 index 757228c..0000000 --- a/gdb-python-make-gdb.unwindinfo.add_saved_register-mo-fixup.patch +++ /dev/null @@ -1,70 +0,0 @@ -From fc73000faa1798573090994167b7e2d451c211db Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Fri, 10 May 2024 08:46:21 +0200 -Subject: [PATCH] [gdb/python] Make gdb.UnwindInfo.add_saved_register more - robust (fixup) - -In commit 2236c5e384d ("[gdb/python] Make gdb.UnwindInfo.add_saved_register -more robust") I added this code in unwind_infopy_add_saved_register: -... - if (value->optimized_out () || !value->entirely_available ()) -... -which may throw c++ exceptions. - -This needs to be caught and transformed into a python exception. - -Fix this by using GDB_PY_HANDLE_EXCEPTION. - -Tested on x86_64-linux. - -Approved-By: Tom Tromey - -Fixes: 2236c5e384d ("[gdb/python] Make gdb.UnwindInfo.add_saved_register more robust") -(cherry picked from commit 408bc9c5fc757bd4b8adb1c3d54ecd672beaedb7) ---- - gdb/python/py-unwind.c | 26 +++++++++++++++++--------- - 1 file changed, 17 insertions(+), 9 deletions(-) - -diff --git a/gdb/python/py-unwind.c b/gdb/python/py-unwind.c -index 471eb851674..e57c8c1adcf 100644 ---- a/gdb/python/py-unwind.c -+++ b/gdb/python/py-unwind.c -@@ -354,16 +354,24 @@ unwind_infopy_add_saved_register (PyObject *self, PyObject *args, PyObject *kw) - return nullptr; - } - -- if (value->optimized_out () || !value->entirely_available ()) -+ -+ try -+ { -+ if (value->optimized_out () || !value->entirely_available ()) -+ { -+ /* If we allow this value to be registered here, pyuw_sniffer is going -+ to run into an exception when trying to access its contents. -+ Throwing an exception here just puts a burden on the user to -+ implement the same checks on the user side. We could return False -+ here and True otherwise, but again that might require changes in -+ user code. So, handle this with minimal impact for the user, while -+ improving robustness: silently ignore the register/value pair. */ -+ Py_RETURN_NONE; -+ } -+ } -+ catch (const gdb_exception &except) - { -- /* If we allow this value to be registered here, pyuw_sniffer is going -- to run into an exception when trying to access its contents. -- Throwing an exception here just puts a burden on the user to -- implement the same checks on the user side. We could return False -- here and True otherwise, but again that might require changes in user -- code. So, handle this with minimal impact for the user, while -- improving robustness: silently ignore the register/value pair. */ -- Py_RETURN_NONE; -+ GDB_PY_HANDLE_EXCEPTION (except); - } - - gdbpy_ref<> new_value = gdbpy_ref<>::new_reference (pyo_reg_value); - -base-commit: a6f598be3d0477c5c59bd490573a5d457949658e --- -2.35.3 - diff --git a/gdb-python-make-gdb.unwindinfo.add_saved_register-mo.patch b/gdb-python-make-gdb.unwindinfo.add_saved_register-mo.patch deleted file mode 100644 index 19ed99f..0000000 --- a/gdb-python-make-gdb.unwindinfo.add_saved_register-mo.patch +++ /dev/null @@ -1,61 +0,0 @@ -From eafca1ce3d589c731927e5481199db715bcbeff3 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Sat, 2 Mar 2024 09:35:22 +0100 -Subject: [PATCH 2/2] [gdb/python] Make gdb.UnwindInfo.add_saved_register more - robust - -On arm-linux, until commit bbb12eb9c84 ("gdb/arm: Remove tpidruro register -from non-FreeBSD target descriptions") I ran into: -... -FAIL: gdb.base/inline-frame-cycle-unwind.exp: cycle at level 5: \ - backtrace when the unwind is broken at frame 5 -... - -What happens is the following: -- the TestUnwinder from inline-frame-cycle-unwind.py calls - gdb.UnwindInfo.add_saved_register with reg == tpidruro and value - "", -- pyuw_sniffer calls value->contents ().data () to access the value of the - register, which throws an UNAVAILABLE_ERROR, -- this causes the TestUnwinder unwinder to fail, after which another unwinder - succeeds and returns the correct frame, and -- the test-case fails because it's counting on the TestUnwinder to succeed and - return an incorrect frame. - -Fix this by checking for !value::entirely_available as well as -valued::optimized_out in unwind_infopy_add_saved_register. - -Tested on x86_64-linux and arm-linux. - -PR python/31437 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31437 ---- - gdb/python/py-unwind.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/gdb/python/py-unwind.c b/gdb/python/py-unwind.c -index 1856e41e2a1..471eb851674 100644 ---- a/gdb/python/py-unwind.c -+++ b/gdb/python/py-unwind.c -@@ -354,6 +354,18 @@ unwind_infopy_add_saved_register (PyObject *self, PyObject *args, PyObject *kw) - return nullptr; - } - -+ if (value->optimized_out () || !value->entirely_available ()) -+ { -+ /* If we allow this value to be registered here, pyuw_sniffer is going -+ to run into an exception when trying to access its contents. -+ Throwing an exception here just puts a burden on the user to -+ implement the same checks on the user side. We could return False -+ here and True otherwise, but again that might require changes in user -+ code. So, handle this with minimal impact for the user, while -+ improving robustness: silently ignore the register/value pair. */ -+ Py_RETURN_NONE; -+ } -+ - gdbpy_ref<> new_value = gdbpy_ref<>::new_reference (pyo_reg_value); - bool found = false; - for (saved_reg ® : *unwind_info->saved_regs) --- -2.35.3 - diff --git a/gdb-record-fix-out-of-bounds-write-in-aarch64_record.patch b/gdb-record-fix-out-of-bounds-write-in-aarch64_record.patch new file mode 100644 index 0000000..2e476e5 --- /dev/null +++ b/gdb-record-fix-out-of-bounds-write-in-aarch64_record.patch @@ -0,0 +1,89 @@ +From 9b1fc55c1887675923d4ddeda4b38ab05e6bb44c Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Thu, 13 Mar 2025 11:15:05 +0100 +Subject: [PATCH 1/2] [gdb/record] Fix out-of-bounds write in + aarch64_record_asimd_load_store + +After compiling gdb with -fstack-protector-all, and running test-case +gdb.reverse/getrandom.exp on aarch64-linux, we run into +"Stack smashing detected" in function aarch64_record_asimd_load_store. + +This is reported in PR record/32784. + +This happens due to an out-of-bounds write to local array record_buf_mem: +... + uint64_t record_buf_mem[24]; +... +when recording insn: +... +B+>0xfffff7ff4d10 st1 {v0.16b-v3.16b}, [x0] +... + +We can fix this by increasing the array size to 128, but rather than again +hardcoding a size, reimplement record_buf_mem as std::vector. + +Tested on aarch64-linux. + +Approved-By: Guinevere Larsen + +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32784 +(cherry picked from commit 51729ea0905d1f688b7fd2ea769e69b29daa1b7c) +--- + gdb/aarch64-tdep.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c +index e4bca6c6632..92daaa75b1c 100644 +--- a/gdb/aarch64-tdep.c ++++ b/gdb/aarch64-tdep.c +@@ -5030,9 +5030,9 @@ aarch64_record_asimd_load_store (aarch64_insn_decode_record *aarch64_insn_r) + CORE_ADDR address; + uint64_t addr_offset = 0; + uint32_t record_buf[24]; +- uint64_t record_buf_mem[24]; ++ std::vector record_buf_mem; + uint32_t reg_rn, reg_rt; +- uint32_t reg_index = 0, mem_index = 0; ++ uint32_t reg_index = 0; + uint8_t opcode_bits, size_bits; + + reg_rt = bits (aarch64_insn_r->aarch64_insn, 0, 4); +@@ -5095,8 +5095,8 @@ aarch64_record_asimd_load_store (aarch64_insn_decode_record *aarch64_insn_r) + record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM; + else + { +- record_buf_mem[mem_index++] = esize / 8; +- record_buf_mem[mem_index++] = address + addr_offset; ++ record_buf_mem.push_back (esize / 8); ++ record_buf_mem.push_back (address + addr_offset); + } + addr_offset = addr_offset + (esize / 8); + reg_rt = (reg_rt + 1) % 32; +@@ -5167,8 +5167,8 @@ aarch64_record_asimd_load_store (aarch64_insn_decode_record *aarch64_insn_r) + record_buf[reg_index++] = reg_tt + AARCH64_V0_REGNUM; + else + { +- record_buf_mem[mem_index++] = esize / 8; +- record_buf_mem[mem_index++] = address + addr_offset; ++ record_buf_mem.push_back (esize / 8); ++ record_buf_mem.push_back (address + addr_offset); + } + addr_offset = addr_offset + (esize / 8); + reg_tt = (reg_tt + 1) % 32; +@@ -5180,9 +5180,9 @@ aarch64_record_asimd_load_store (aarch64_insn_decode_record *aarch64_insn_r) + record_buf[reg_index++] = reg_rn; + + aarch64_insn_r->reg_rec_count = reg_index; +- aarch64_insn_r->mem_rec_count = mem_index / 2; ++ aarch64_insn_r->mem_rec_count = record_buf_mem.size () / 2; + MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count, +- record_buf_mem); ++ record_buf_mem.data ()); + REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count, + record_buf); + return AARCH64_RECORD_SUCCESS; + +base-commit: 96a340e789f714156bbac7f78f340e06659b5e70 +-- +2.43.0 + diff --git a/gdb-remote-fix-abort-on-remote_close_error.patch b/gdb-remote-fix-abort-on-remote_close_error.patch deleted file mode 100644 index d6a9a46..0000000 --- a/gdb-remote-fix-abort-on-remote_close_error.patch +++ /dev/null @@ -1,229 +0,0 @@ -From 0ad71e3088f345101085a1f72e81a000a100db18 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Sat, 27 Apr 2024 17:48:22 +0200 -Subject: [PATCH 25/48] [gdb/remote] Fix abort on REMOTE_CLOSE_ERROR - -When running test-case gdb.server/connect-with-no-symbol-file.exp on -aarch64-linux (specifically, an opensuse leap 15.5 container on a -fedora asahi 39 system), I run into: -... -(gdb) detach^M -Detaching from program: target:connect-with-no-symbol-file, process 185104^M -Ending remote debugging.^M -terminate called after throwing an instance of 'gdb_exception_error'^M -... - -The detailed backtrace of the corefile is: -... - (gdb) bt - #0 0x0000ffff75504f54 in raise () from /lib64/libpthread.so.0 - #1 0x00000000007a86b4 in handle_fatal_signal (sig=6) - at gdb/event-top.c:926 - #2 - #3 0x0000ffff74b977b4 in raise () from /lib64/libc.so.6 - #4 0x0000ffff74b98c18 in abort () from /lib64/libc.so.6 - #5 0x0000ffff74ea26f4 in __gnu_cxx::__verbose_terminate_handler() () - from /usr/lib64/libstdc++.so.6 - #6 0x0000ffff74ea011c in ?? () from /usr/lib64/libstdc++.so.6 - #7 0x0000ffff74ea0180 in std::terminate() () from /usr/lib64/libstdc++.so.6 - #8 0x0000ffff74ea0464 in __cxa_throw () from /usr/lib64/libstdc++.so.6 - #9 0x0000000001548870 in throw_it (reason=RETURN_ERROR, - error=TARGET_CLOSE_ERROR, fmt=0x16c7810 "Remote connection closed", ap=...) - at gdbsupport/common-exceptions.cc:203 - #10 0x0000000001548920 in throw_verror (error=TARGET_CLOSE_ERROR, - fmt=0x16c7810 "Remote connection closed", ap=...) - at gdbsupport/common-exceptions.cc:211 - #11 0x0000000001548a00 in throw_error (error=TARGET_CLOSE_ERROR, - fmt=0x16c7810 "Remote connection closed") - at gdbsupport/common-exceptions.cc:226 - #12 0x0000000000ac8f2c in remote_target::readchar (this=0x233d3d90, timeout=2) - at gdb/remote.c:9856 - #13 0x0000000000ac9f04 in remote_target::getpkt (this=0x233d3d90, - buf=0x233d40a8, forever=false, is_notif=0x0) at gdb/remote.c:10326 - #14 0x0000000000acf3d0 in remote_target::remote_hostio_send_command - (this=0x233d3d90, command_bytes=13, which_packet=17, - remote_errno=0xfffff1a3cf38, attachment=0xfffff1a3ce88, - attachment_len=0xfffff1a3ce90) at gdb/remote.c:12567 - #15 0x0000000000ad03bc in remote_target::fileio_fstat (this=0x233d3d90, fd=3, - st=0xfffff1a3d020, remote_errno=0xfffff1a3cf38) - at gdb/remote.c:12979 - #16 0x0000000000c39878 in target_fileio_fstat (fd=0, sb=0xfffff1a3d020, - target_errno=0xfffff1a3cf38) at gdb/target.c:3315 - #17 0x00000000007eee5c in target_fileio_stream::stat (this=0x233d4400, - abfd=0x2323fc40, sb=0xfffff1a3d020) at gdb/gdb_bfd.c:467 - #18 0x00000000007f012c in ::operator()(bfd *, - void *, stat *) const (__closure=0x0, abfd=0x2323fc40, stream=0x233d4400, - sb=0xfffff1a3d020) at gdb/gdb_bfd.c:955 - #19 0x00000000007f015c in ::_FUN(bfd *, void *, - stat *) () at gdb/gdb_bfd.c:956 - #20 0x0000000000f9b838 in opncls_bstat (abfd=0x2323fc40, sb=0xfffff1a3d020) - at bfd/opncls.c:665 - #21 0x0000000000f90adc in bfd_stat (abfd=0x2323fc40, statbuf=0xfffff1a3d020) - at bfd/bfdio.c:431 - #22 0x000000000065fe20 in reopen_exec_file () at gdb/corefile.c:52 - #23 0x0000000000c3a3e8 in generic_mourn_inferior () - at gdb/target.c:3642 - #24 0x0000000000abf3f0 in remote_unpush_target (target=0x233d3d90) - at gdb/remote.c:6067 - #25 0x0000000000aca8b0 in remote_target::mourn_inferior (this=0x233d3d90) - at gdb/remote.c:10587 - #26 0x0000000000c387cc in target_mourn_inferior ( - ptid=) - at gdb/target.c:2738 - #27 0x0000000000abfff0 in remote_target::remote_detach_1 (this=0x233d3d90, - inf=0x22fce540, from_tty=1) at gdb/remote.c:6421 - #28 0x0000000000ac0094 in remote_target::detach (this=0x233d3d90, - inf=0x22fce540, from_tty=1) at gdb/remote.c:6436 - #29 0x0000000000c37c3c in target_detach (inf=0x22fce540, from_tty=1) - at gdb/target.c:2526 - #30 0x0000000000860424 in detach_command (args=0x0, from_tty=1) - at gdb/infcmd.c:2817 - #31 0x000000000060b594 in do_simple_func (args=0x0, from_tty=1, c=0x231431a0) - at gdb/cli/cli-decode.c:94 - #32 0x00000000006108c8 in cmd_func (cmd=0x231431a0, args=0x0, from_tty=1) - at gdb/cli/cli-decode.c:2741 - #33 0x0000000000c65a94 in execute_command (p=0x232e52f6 "", from_tty=1) - at gdb/top.c:570 - #34 0x00000000007a7d2c in command_handler (command=0x232e52f0 "") - at gdb/event-top.c:566 - #35 0x00000000007a8290 in command_line_handler (rl=...) - at gdb/event-top.c:802 - #36 0x0000000000c9092c in tui_command_line_handler (rl=...) - at gdb/tui/tui-interp.c:103 - #37 0x00000000007a750c in gdb_rl_callback_handler (rl=0x23385330 "detach") - at gdb/event-top.c:258 - #38 0x0000000000d910f4 in rl_callback_read_char () - at readline/readline/callback.c:290 - #39 0x00000000007a7338 in gdb_rl_callback_read_char_wrapper_noexcept () - at gdb/event-top.c:194 - #40 0x00000000007a73f0 in gdb_rl_callback_read_char_wrapper - (client_data=0x22fbf640) at gdb/event-top.c:233 - #41 0x0000000000cbee1c in stdin_event_handler (error=0, client_data=0x22fbf640) - at gdb/ui.c:154 - #42 0x000000000154ed60 in handle_file_event (file_ptr=0x232be730, ready_mask=1) - at gdbsupport/event-loop.cc:572 - #43 0x000000000154f21c in gdb_wait_for_event (block=1) - at gdbsupport/event-loop.cc:693 - #44 0x000000000154dec4 in gdb_do_one_event (mstimeout=-1) - at gdbsupport/event-loop.cc:263 - #45 0x0000000000910f98 in start_event_loop () at gdb/main.c:400 - #46 0x0000000000911130 in captured_command_loop () at gdb/main.c:464 - #47 0x0000000000912b5c in captured_main (data=0xfffff1a3db58) - at gdb/main.c:1338 - #48 0x0000000000912bf4 in gdb_main (args=0xfffff1a3db58) - at gdb/main.c:1357 - #49 0x00000000004170f4 in main (argc=10, argv=0xfffff1a3dcc8) - at gdb/gdb.c:38 - (gdb) -... - -The abort happens because a c++ exception escapes to c code, specifically -opncls_bstat in bfd/opncls.c. Compiling with -fexceptions works around this. - -Fix this by catching the exception just before it escapes, in stat_trampoline -and likewise in few similar spot. - -Add a new template catch_exceptions to do so in a consistent way. - -Tested on aarch64-linux. - -Approved-by: Pedro Alves - -PR remote/31577 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31577 ---- - gdb/gdb_bfd.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 56 insertions(+), 3 deletions(-) - -diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c -index 217753cf914..3c34cc5693f 100644 ---- a/gdb/gdb_bfd.c -+++ b/gdb/gdb_bfd.c -@@ -887,6 +887,29 @@ gdb_bfd_openw (const char *filename, const char *target) - return gdb_bfd_ref_ptr::new_reference (result); - } - -+/* Wrap f (args) and handle exceptions by: -+ - returning val, and -+ - calling set_quit_flag or set_force_quit_flag, if needed. */ -+ -+template -+static R -+catch_exceptions (F &&f, Args&&... args) -+{ -+ try -+ { -+ return f (std::forward (args)...); -+ } -+ catch (const gdb_exception &ex) -+ { -+ if (ex.reason == RETURN_QUIT) -+ set_quit_flag (); -+ else if (ex.reason == RETURN_FORCED_QUIT) -+ set_force_quit_flag (); -+ } -+ -+ return val; -+} -+ - /* See gdb_bfd.h. */ - - gdb_bfd_ref_ptr -@@ -896,21 +919,51 @@ gdb_bfd_openr_iovec (const char *filename, const char *target, - auto do_open = [] (bfd *nbfd, void *closure) -> void * - { - auto real_opener = static_cast (closure); -- return (*real_opener) (nbfd); -+ /* Prevent exceptions from escaping to C code and triggering an abort. */ -+ auto res = catch_exceptions ([&] -+ { -+ return (*real_opener) (nbfd); -+ }); -+ if (res == nullptr) -+ { -+ errno = EIO; -+ bfd_set_error (bfd_error_system_call); -+ } -+ return res; - }; - - auto read_trampoline = [] (bfd *nbfd, void *stream, void *buf, - file_ptr nbytes, file_ptr offset) -> file_ptr - { - gdb_bfd_iovec_base *obj = static_cast (stream); -- return obj->read (nbfd, buf, nbytes, offset); -+ /* Prevent exceptions from escaping to C code and triggering an abort. */ -+ auto res = catch_exceptions ([&] -+ { -+ return obj->read (nbfd, buf, nbytes, offset); -+ }); -+ if (res == -1) -+ { -+ errno = EIO; -+ bfd_set_error (bfd_error_system_call); -+ } -+ return res; - }; - - auto stat_trampoline = [] (struct bfd *abfd, void *stream, - struct stat *sb) -> int - { - gdb_bfd_iovec_base *obj = static_cast (stream); -- return obj->stat (abfd, sb); -+ /* Prevent exceptions from escaping to C code and triggering an abort. */ -+ auto res = catch_exceptions ([&] -+ { -+ return obj->stat (abfd, sb); -+ }); -+ if (res == -1) -+ { -+ errno = EIO; -+ bfd_set_error (bfd_error_system_call); -+ } -+ return res; - }; - - auto close_trampoline = [] (struct bfd *nbfd, void *stream) -> int --- -2.35.3 - diff --git a/gdb-remove-qnx-neutrino-support.patch b/gdb-remove-qnx-neutrino-support.patch new file mode 100644 index 0000000..032d5cb --- /dev/null +++ b/gdb-remove-qnx-neutrino-support.patch @@ -0,0 +1,2923 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Simon Marchi +Date: Thu, 25 Jul 2024 13:41:35 -0400 +Subject: gdb-remove-qnx-neutrino-support.patch + +;; Backport of upstream commit 36fb20fa93484b104d. This is not really +;; relevant for our branch, but later commits that are important, and +;; which we want to backport, conflict unless the cleanup in this +;; patch is in place. +;; +;; This commit will be part of GDB 16, so this back-port should drop +;; out when we rebase onto GDB 16. +;; +;; gdb: remove QNX Neutrino support +;; +;; Remove the support for the QNX Neutrino OS (tdep and native bits). This +;; has been unmaintained for years, and we don't have a way to see if it +;; works (or even builds, for the native parts). Without somebody actively +;; maintaining it, this is just a burden for developers, especially that +;; this port does a few weird unique things that require reasoning about +;; when doing big change. +;; +;; Support for GDBserver was removed in 2020, commit 613f149a90d6 +;; ("gdbserver: remove support for Neutrino"). +;; +;; Change-Id: I4e25ec26ab06636629adebd02ceb161ee31c232d +;; Approved-by: Kevin Buettner + +diff --git a/gdb/Makefile.in b/gdb/Makefile.in +--- a/gdb/Makefile.in ++++ b/gdb/Makefile.in +@@ -828,7 +828,6 @@ ALL_TARGET_OBS = \ + i386-go32-tdep.o \ + i386-linux-tdep.o \ + i386-netbsd-tdep.o \ +- i386-nto-tdep.o \ + i386-obsd-tdep.o \ + i386-sol2-tdep.o \ + i386-tdep.o \ +@@ -856,7 +855,6 @@ ALL_TARGET_OBS = \ + nds32-tdep.o \ + nios2-linux-tdep.o \ + nios2-tdep.o \ +- nto-tdep.o \ + obsd-tdep.o \ + or1k-linux-tdep.o \ + or1k-tdep.o \ +@@ -1441,7 +1439,6 @@ HFILES_NO_SRCDIR = \ + nds32-tdep.h \ + nios2-tdep.h \ + elf-none-tdep.h \ +- nto-tdep.h \ + objc-lang.h \ + objfiles.h \ + obsd-nat.h \ +@@ -1573,7 +1570,6 @@ HFILES_NO_SRCDIR = \ + compile/gcc-c-plugin.h \ + compile/gcc-cp-plugin.h \ + config/nm-linux.h \ +- config/nm-nto.h \ + config/djgpp/langinfo.h \ + config/djgpp/nl_types.h \ + config/i386/nm-i386gnu.h \ +diff --git a/gdb/config/nm-nto.h b/gdb/config/nm-nto.h +deleted file mode 100644 +--- a/gdb/config/nm-nto.h ++++ /dev/null +@@ -1,29 +0,0 @@ +-/* Native support for QNX Neutrino version 6. +- +- Copyright (C) 2003-2024 Free Software Foundation, Inc. +- +- This code was donated by QNX Software Systems Ltd. +- +- 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 . */ +- +-#ifndef CONFIG_NM_NTO_H +-#define CONFIG_NM_NTO_H +- +-/* Setup the valid realtime signal range. */ +-#define REALTIME_LO 41 +-#define REALTIME_HI 56 +- +-#endif /* CONFIG_NM_NTO_H */ +diff --git a/gdb/configure.host b/gdb/configure.host +--- a/gdb/configure.host ++++ b/gdb/configure.host +@@ -110,7 +110,6 @@ i[34567]86-*-mingw32*) gdb_host=mingw + i[34567]86-*-msdosdjgpp*) gdb_host=go32 ;; + i[34567]86-*-linux*) gdb_host=linux ;; + i[34567]86-*-gnu*) gdb_host=i386gnu ;; +-i[3456]86-*-nto*) gdb_host=nto ;; + i[34567]86-*-openbsd*) gdb_host=obsd ;; + i[34567]86-*-solaris2* | x86_64-*-solaris2*) + gdb_host=sol2 ;; +diff --git a/gdb/configure.nat b/gdb/configure.nat +--- a/gdb/configure.nat ++++ b/gdb/configure.nat +@@ -421,15 +421,6 @@ case ${gdb_host} in + + esac + ;; +- nto) +- case ${gdb_host_cpu} in +- i386) +- # Host: Intel 386 running QNX. +- NATDEPFILES='nto-procfs.o' +- NAT_FILE='config/nm-nto.h' +- ;; +- esac +- ;; + obsd) + case ${gdb_host_cpu} in + i386) +diff --git a/gdb/configure.tgt b/gdb/configure.tgt +--- a/gdb/configure.tgt ++++ b/gdb/configure.tgt +@@ -304,11 +304,6 @@ i[34567]86-*-openbsd*) + # Target: OpenBSD/i386 + gdb_target_obs="i386-bsd-tdep.o i386-obsd-tdep.o bsd-uthread.o" + ;; +-i[34567]86-*-nto*) +- # Target: Intel 386 running qnx6. +- gdb_target_obs="solib-svr4.o \ +- i386-nto-tdep.o nto-tdep.o" +- ;; + i[34567]86-*-solaris2* | x86_64-*-solaris2*) + # Target: Solaris x86_64 + gdb_target_obs="${i386_tobjs} ${amd64_tobjs} \ +@@ -803,7 +798,6 @@ case "${targ}" in + gdb_osabi=GDB_OSABI_FREEBSD ;; + *-*-linux* | *-*-uclinux*) + gdb_osabi=GDB_OSABI_LINUX ;; +-*-*-nto*) gdb_osabi=GDB_OSABI_QNXNTO ;; + m68*-*-openbsd* | m88*-*-openbsd* | vax-*-openbsd*) ;; + *-*-openbsd*) gdb_osabi=GDB_OSABI_OPENBSD ;; + *-*-solaris*) gdb_osabi=GDB_OSABI_SOLARIS ;; +diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo +--- a/gdb/doc/gdb.texinfo ++++ b/gdb/doc/gdb.texinfo +@@ -2742,7 +2742,7 @@ + @end smallexample + + This command is available when debugging locally on most targets, excluding +-@sc{djgpp}, Cygwin, MS Windows, and QNX Neutrino. ++@sc{djgpp}, Cygwin, and MS Windows. + + @kindex set startup-with-shell + @anchor{set startup-with-shell} +@@ -22011,7 +22011,7 @@ + @cindex shared libraries + @anchor{Shared Libraries} + @value{GDBN} supports @sc{gnu}/Linux, MS-Windows, SunOS, +-Darwin/Mach-O, SVr4, IBM RS/6000 AIX, QNX Neutrino, FDPIC (FR-V), and ++Darwin/Mach-O, SVr4, IBM RS/6000 AIX, FDPIC (FR-V), and + DSBT (TIC6X) shared libraries. + + On MS-Windows @value{GDBN} must be linked with the Expat library to support +@@ -25203,16 +25203,6 @@ + These commands enable and disable tracing of entries into and exits + from the @code{syscall} interface. + +-@item info pidlist +-@kindex info pidlist +-@cindex process list, QNX Neutrino +-For QNX Neutrino only, this command displays the list of all the +-processes and all the threads within each process. +- +-@item info meminfo +-@kindex info meminfo +-@cindex mapinfo list, QNX Neutrino +-For QNX Neutrino only, this command displays the list of all mapinfos. + @end table + + @node DJGPP Native +diff --git a/gdb/i386-nto-tdep.c b/gdb/i386-nto-tdep.c +deleted file mode 100644 +--- a/gdb/i386-nto-tdep.c ++++ /dev/null +@@ -1,379 +0,0 @@ +-/* Target-dependent code for QNX Neutrino x86. +- +- Copyright (C) 2003-2024 Free Software Foundation, Inc. +- +- Contributed by QNX Software Systems Ltd. +- +- 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 . */ +- +-#include "extract-store-integer.h" +-#include "frame.h" +-#include "osabi.h" +-#include "regcache.h" +-#include "target.h" +- +-#include "i386-tdep.h" +-#include "i387-tdep.h" +-#include "nto-tdep.h" +-#include "solib.h" +-#include "solib-svr4.h" +- +-#ifndef X86_CPU_FXSR +-#define X86_CPU_FXSR (1L << 12) +-#endif +- +-/* Why 13? Look in our /usr/include/x86/context.h header at the +- x86_cpu_registers structure and you'll see an 'exx' junk register +- that is just filler. Don't ask me, ask the kernel guys. */ +-#define NUM_GPREGS 13 +- +-/* Mapping between the general-purpose registers in `struct xxx' +- format and GDB's register cache layout. */ +- +-/* From . */ +-static int i386nto_gregset_reg_offset[] = +-{ +- 7 * 4, /* %eax */ +- 6 * 4, /* %ecx */ +- 5 * 4, /* %edx */ +- 4 * 4, /* %ebx */ +- 11 * 4, /* %esp */ +- 2 * 4, /* %epb */ +- 1 * 4, /* %esi */ +- 0 * 4, /* %edi */ +- 8 * 4, /* %eip */ +- 10 * 4, /* %eflags */ +- 9 * 4, /* %cs */ +- 12 * 4, /* %ss */ +- -1 /* filler */ +-}; +- +-/* Given a GDB register number REGNUM, return the offset into +- Neutrino's register structure or -1 if the register is unknown. */ +- +-static int +-nto_reg_offset (int regnum) +-{ +- if (regnum >= 0 && regnum < ARRAY_SIZE (i386nto_gregset_reg_offset)) +- return i386nto_gregset_reg_offset[regnum]; +- +- return -1; +-} +- +-static void +-i386nto_supply_gregset (struct regcache *regcache, char *gpregs) +-{ +- struct gdbarch *gdbarch = regcache->arch (); +- i386_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); +- +- gdb_assert (tdep->gregset_reg_offset == i386nto_gregset_reg_offset); +- i386_gregset.supply_regset (&i386_gregset, regcache, -1, +- gpregs, NUM_GPREGS * 4); +-} +- +-static void +-i386nto_supply_fpregset (struct regcache *regcache, char *fpregs) +-{ +- if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR) +- i387_supply_fxsave (regcache, -1, fpregs); +- else +- i387_supply_fsave (regcache, -1, fpregs); +-} +- +-static void +-i386nto_supply_regset (struct regcache *regcache, int regset, char *data) +-{ +- switch (regset) +- { +- case NTO_REG_GENERAL: +- i386nto_supply_gregset (regcache, data); +- break; +- case NTO_REG_FLOAT: +- i386nto_supply_fpregset (regcache, data); +- break; +- } +-} +- +-static int +-i386nto_regset_id (int regno) +-{ +- if (regno == -1) +- return NTO_REG_END; +- else if (regno < I386_NUM_GREGS) +- return NTO_REG_GENERAL; +- else if (regno < I386_NUM_GREGS + I387_NUM_REGS) +- return NTO_REG_FLOAT; +- else if (regno < I386_SSE_NUM_REGS) +- return NTO_REG_FLOAT; /* We store xmm registers in fxsave_area. */ +- +- return -1; /* Error. */ +-} +- +-static int +-i386nto_register_area (struct gdbarch *gdbarch, +- int regno, int regset, unsigned *off) +-{ +- i386_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); +- +- *off = 0; +- if (regset == NTO_REG_GENERAL) +- { +- if (regno == -1) +- return NUM_GPREGS * 4; +- +- *off = nto_reg_offset (regno); +- if (*off == -1) +- return 0; +- return 4; +- } +- else if (regset == NTO_REG_FLOAT) +- { +- unsigned off_adjust, regsize, regset_size, regno_base; +- /* The following are flags indicating number in our fxsave_area. */ +- int first_four = (regno >= I387_FCTRL_REGNUM (tdep) +- && regno <= I387_FISEG_REGNUM (tdep)); +- int second_four = (regno > I387_FISEG_REGNUM (tdep) +- && regno <= I387_FOP_REGNUM (tdep)); +- int st_reg = (regno >= I387_ST0_REGNUM (tdep) +- && regno < I387_ST0_REGNUM (tdep) + 8); +- int xmm_reg = (regno >= I387_XMM0_REGNUM (tdep) +- && regno < I387_MXCSR_REGNUM (tdep)); +- +- if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR) +- { +- off_adjust = 32; +- regsize = 16; +- regset_size = 512; +- /* fxsave_area structure. */ +- if (first_four) +- { +- /* fpu_control_word, fpu_status_word, fpu_tag_word, fpu_operand +- registers. */ +- regsize = 2; /* Two bytes each. */ +- off_adjust = 0; +- regno_base = I387_FCTRL_REGNUM (tdep); +- } +- else if (second_four) +- { +- /* fpu_ip, fpu_cs, fpu_op, fpu_ds registers. */ +- regsize = 4; +- off_adjust = 8; +- regno_base = I387_FISEG_REGNUM (tdep) + 1; +- } +- else if (st_reg) +- { +- /* ST registers. */ +- regsize = 16; +- off_adjust = 32; +- regno_base = I387_ST0_REGNUM (tdep); +- } +- else if (xmm_reg) +- { +- /* XMM registers. */ +- regsize = 16; +- off_adjust = 160; +- regno_base = I387_XMM0_REGNUM (tdep); +- } +- else if (regno == I387_MXCSR_REGNUM (tdep)) +- { +- regsize = 4; +- off_adjust = 24; +- regno_base = I387_MXCSR_REGNUM (tdep); +- } +- else +- { +- /* Whole regset. */ +- gdb_assert (regno == -1); +- off_adjust = 0; +- regno_base = 0; +- regsize = regset_size; +- } +- } +- else +- { +- regset_size = 108; +- /* fsave_area structure. */ +- if (first_four || second_four) +- { +- /* fpu_control_word, ... , fpu_ds registers. */ +- regsize = 4; +- off_adjust = 0; +- regno_base = I387_FCTRL_REGNUM (tdep); +- } +- else if (st_reg) +- { +- /* One of ST registers. */ +- regsize = 10; +- off_adjust = 7 * 4; +- regno_base = I387_ST0_REGNUM (tdep); +- } +- else +- { +- /* Whole regset. */ +- gdb_assert (regno == -1); +- off_adjust = 0; +- regno_base = 0; +- regsize = regset_size; +- } +- } +- +- if (regno != -1) +- *off = off_adjust + (regno - regno_base) * regsize; +- else +- *off = 0; +- return regsize; +- } +- return -1; +-} +- +-static int +-i386nto_regset_fill (const struct regcache *regcache, int regset, char *data) +-{ +- if (regset == NTO_REG_GENERAL) +- { +- int regno; +- +- for (regno = 0; regno < NUM_GPREGS; regno++) +- { +- int offset = nto_reg_offset (regno); +- if (offset != -1) +- regcache->raw_collect (regno, data + offset); +- } +- } +- else if (regset == NTO_REG_FLOAT) +- { +- if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR) +- i387_collect_fxsave (regcache, -1, data); +- else +- i387_collect_fsave (regcache, -1, data); +- } +- else +- return -1; +- +- return 0; +-} +- +-/* Return whether THIS_FRAME corresponds to a QNX Neutrino sigtramp +- routine. */ +- +-static int +-i386nto_sigtramp_p (const frame_info_ptr &this_frame) +-{ +- CORE_ADDR pc = get_frame_pc (this_frame); +- const char *name; +- +- find_pc_partial_function (pc, &name, NULL, NULL); +- return name && strcmp ("__signalstub", name) == 0; +-} +- +-/* Assuming THIS_FRAME is a QNX Neutrino sigtramp routine, return the +- address of the associated sigcontext structure. */ +- +-static CORE_ADDR +-i386nto_sigcontext_addr (const frame_info_ptr &this_frame) +-{ +- struct gdbarch *gdbarch = get_frame_arch (this_frame); +- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); +- gdb_byte buf[4]; +- CORE_ADDR ptrctx; +- +- /* We store __ucontext_t addr in EDI register. */ +- get_frame_register (this_frame, I386_EDI_REGNUM, buf); +- ptrctx = extract_unsigned_integer (buf, 4, byte_order); +- ptrctx += 24 /* Context pointer is at this offset. */; +- +- return ptrctx; +-} +- +-static void +-init_i386nto_ops (void) +-{ +- nto_regset_id = i386nto_regset_id; +- nto_supply_gregset = i386nto_supply_gregset; +- nto_supply_fpregset = i386nto_supply_fpregset; +- nto_supply_altregset = nto_dummy_supply_regset; +- nto_supply_regset = i386nto_supply_regset; +- nto_register_area = i386nto_register_area; +- nto_regset_fill = i386nto_regset_fill; +- nto_fetch_link_map_offsets = +- svr4_ilp32_fetch_link_map_offsets; +-} +- +-static void +-i386nto_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +-{ +- i386_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); +- static solib_ops nto_svr4_so_ops; +- +- /* Deal with our strange signals. */ +- nto_initialize_signals (); +- +- /* NTO uses ELF. */ +- i386_elf_init_abi (info, gdbarch); +- +- /* Neutrino rewinds to look more normal. Need to override the i386 +- default which is [unfortunately] to decrement the PC. */ +- set_gdbarch_decr_pc_after_break (gdbarch, 0); +- +- tdep->gregset_reg_offset = i386nto_gregset_reg_offset; +- tdep->gregset_num_regs = ARRAY_SIZE (i386nto_gregset_reg_offset); +- tdep->sizeof_gregset = NUM_GPREGS * 4; +- +- tdep->sigtramp_p = i386nto_sigtramp_p; +- tdep->sigcontext_addr = i386nto_sigcontext_addr; +- tdep->sc_reg_offset = i386nto_gregset_reg_offset; +- tdep->sc_num_regs = ARRAY_SIZE (i386nto_gregset_reg_offset); +- +- /* Setjmp()'s return PC saved in EDX (5). */ +- tdep->jb_pc_offset = 20; /* 5x32 bit ints in. */ +- +- set_solib_svr4_fetch_link_map_offsets +- (gdbarch, svr4_ilp32_fetch_link_map_offsets); +- +- /* Initialize this lazily, to avoid an initialization order +- dependency on solib-svr4.c's _initialize routine. */ +- if (nto_svr4_so_ops.in_dynsym_resolve_code == NULL) +- { +- nto_svr4_so_ops = svr4_so_ops; +- +- /* Our loader handles solib relocations differently than svr4. */ +- nto_svr4_so_ops.relocate_section_addresses +- = nto_relocate_section_addresses; +- +- /* Supply a nice function to find our solibs. */ +- nto_svr4_so_ops.find_and_open_solib +- = nto_find_and_open_solib; +- +- /* Our linker code is in libc. */ +- nto_svr4_so_ops.in_dynsym_resolve_code +- = nto_in_dynsym_resolve_code; +- } +- set_gdbarch_so_ops (gdbarch, &nto_svr4_so_ops); +- +- set_gdbarch_wchar_bit (gdbarch, 32); +- set_gdbarch_wchar_signed (gdbarch, 0); +-} +- +-void _initialize_i386nto_tdep (); +-void +-_initialize_i386nto_tdep () +-{ +- init_i386nto_ops (); +- gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_QNXNTO, +- i386nto_init_abi); +- gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour, +- nto_elf_osabi_sniffer); +-} +diff --git a/gdb/nto-procfs.c b/gdb/nto-procfs.c +deleted file mode 100644 +--- a/gdb/nto-procfs.c ++++ /dev/null +@@ -1,1588 +0,0 @@ +-/* Machine independent support for QNX Neutrino /proc (process file system) +- for GDB. Written by Colin Burgess at QNX Software Systems Limited. +- +- Copyright (C) 2003-2024 Free Software Foundation, Inc. +- +- Contributed by QNX Software Systems Ltd. +- +- 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 . */ +- +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "gdbcore.h" +-#include "inferior.h" +-#include "target.h" +-#include "objfiles.h" +-#include "gdbthread.h" +-#include "nto-tdep.h" +-#include "command.h" +-#include "regcache.h" +-#include "solib.h" +-#include "inf-child.h" +-#include "gdbsupport/filestuff.h" +-#include "gdbsupport/scoped_fd.h" +- +-#define NULL_PID 0 +-#define _DEBUG_FLAG_TRACE (_DEBUG_FLAG_TRACE_EXEC|_DEBUG_FLAG_TRACE_RD|\ +- _DEBUG_FLAG_TRACE_WR|_DEBUG_FLAG_TRACE_MODIFY) +- +-int ctl_fd; +- +-static sighandler_t ofunc; +- +-static procfs_run run; +- +-/* Create the "native" and "procfs" targets. */ +- +-struct nto_procfs_target : public inf_child_target +-{ +- void open (const char *arg, int from_tty) override; +- +- void attach (const char *, int) override = 0; +- +- void post_attach (int); +- +- void detach (inferior *, int) override; +- +- void resume (ptid_t, int, enum gdb_signal) override; +- +- ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override; +- +- void fetch_registers (struct regcache *, int) override; +- void store_registers (struct regcache *, int) override; +- +- enum target_xfer_status xfer_partial (enum target_object object, +- const char *annex, +- gdb_byte *readbuf, +- const gdb_byte *writebuf, +- ULONGEST offset, ULONGEST len, +- ULONGEST *xfered_len) override; +- +- void files_info () override; +- +- int insert_breakpoint (struct gdbarch *, struct bp_target_info *) override; +- +- int remove_breakpoint (struct gdbarch *, struct bp_target_info *, +- enum remove_bp_reason) override; +- +- int can_use_hw_breakpoint (enum bptype, int, int) override; +- +- int insert_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override; +- +- int remove_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override; +- +- int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type, +- struct expression *) override; +- +- int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type, +- struct expression *) override; +- +- bool stopped_by_watchpoint () override; +- +- void kill () override; +- +- void create_inferior (const char *, const std::string &, +- char **, int) override; +- +- void mourn_inferior () override; +- +- void pass_signals (gdb::array_view) override; +- +- bool thread_alive (ptid_t ptid) override; +- +- void update_thread_list () override; +- +- std::string pid_to_str (ptid_t) override; +- +- void interrupt () override; +- +- const char *extra_thread_info (struct thread_info *) override; +- +- const char *pid_to_exec_file (int pid) override; +-}; +- +-/* For "target native". */ +- +-static const target_info nto_native_target_info = { +- "native", +- N_("QNX Neutrino local process"), +- N_("QNX Neutrino local process (started by the \"run\" command).") +-}; +- +-class nto_procfs_target_native final : public nto_procfs_target +-{ +- const target_info &info () const override +- { return nto_native_target_info; } +-}; +- +-/* For "target procfs ". */ +- +-static const target_info nto_procfs_target_info = { +- "procfs", +- N_("QNX Neutrino local or remote process"), +- N_("QNX Neutrino process. target procfs NODE") +-}; +- +-struct nto_procfs_target_procfs final : public nto_procfs_target +-{ +- const target_info &info () const override +- { return nto_procfs_target_info; } +-}; +- +-static ptid_t do_attach (ptid_t ptid); +- +-/* These two globals are only ever set in procfs_open_1, but are +- referenced elsewhere. 'nto_procfs_node' is a flag used to say +- whether we are local, or we should get the current node descriptor +- for the remote QNX node. */ +-static char *nodestr; +-static unsigned nto_procfs_node = ND_LOCAL_NODE; +- +-/* Return the current QNX Node, or error out. This is a simple +- wrapper for the netmgr_strtond() function. The reason this +- is required is because QNX node descriptors are transient so +- we have to re-acquire them every time. */ +-static unsigned +-nto_node (void) +-{ +- unsigned node; +- +- if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) == 0 +- || nodestr == NULL) +- return ND_LOCAL_NODE; +- +- node = netmgr_strtond (nodestr, 0); +- if (node == -1) +- error (_("Lost the QNX node. Debug session probably over.")); +- +- return (node); +-} +- +-static enum gdb_osabi +-procfs_is_nto_target (bfd *abfd) +-{ +- return GDB_OSABI_QNXNTO; +-} +- +-/* This is called when we call 'target native' or 'target procfs +- ' from the (gdb) prompt. For QNX6 (nto), the only valid arg +- will be a QNX node string, eg: "/net/some_node". If arg is not a +- valid QNX node, we will default to local. */ +-void +-nto_procfs_target::open (const char *arg, int from_tty) +-{ +- char *endstr; +- char buffer[50]; +- int total_size; +- procfs_sysinfo *sysinfo; +- char nto_procfs_path[PATH_MAX]; +- +- /* Offer to kill previous inferiors before opening this target. */ +- target_preopen (from_tty); +- +- nto_is_nto_target = procfs_is_nto_target; +- +- /* Set the default node used for spawning to this one, +- and only override it if there is a valid arg. */ +- +- xfree (nodestr); +- nodestr = NULL; +- +- nto_procfs_node = ND_LOCAL_NODE; +- nodestr = (arg != NULL) ? xstrdup (arg) : NULL; +- +- if (nodestr) +- { +- nto_procfs_node = netmgr_strtond (nodestr, &endstr); +- if (nto_procfs_node == -1) +- { +- if (errno == ENOTSUP) +- gdb_printf ("QNX Net Manager not found.\n"); +- gdb_printf ("Invalid QNX node %s: error %d (%s).\n", nodestr, +- errno, safe_strerror (errno)); +- xfree (nodestr); +- nodestr = NULL; +- nto_procfs_node = ND_LOCAL_NODE; +- } +- else if (*endstr) +- { +- if (*(endstr - 1) == '/') +- *(endstr - 1) = 0; +- else +- *endstr = 0; +- } +- } +- snprintf (nto_procfs_path, PATH_MAX - 1, "%s%s", +- (nodestr != NULL) ? nodestr : "", "/proc"); +- +- scoped_fd fd (open (nto_procfs_path, O_RDONLY)); +- if (fd.get () == -1) +- { +- gdb_printf ("Error opening %s : %d (%s)\n", nto_procfs_path, errno, +- safe_strerror (errno)); +- error (_("Invalid procfs arg")); +- } +- +- sysinfo = (void *) buffer; +- if (devctl (fd.get (), DCMD_PROC_SYSINFO, sysinfo, sizeof buffer, 0) != EOK) +- { +- gdb_printf ("Error getting size: %d (%s)\n", errno, +- safe_strerror (errno)); +- error (_("Devctl failed.")); +- } +- else +- { +- total_size = sysinfo->total_size; +- sysinfo = alloca (total_size); +- if (sysinfo == NULL) +- { +- gdb_printf ("Memory error: %d (%s)\n", errno, +- safe_strerror (errno)); +- error (_("alloca failed.")); +- } +- else +- { +- if (devctl (fd.get (), DCMD_PROC_SYSINFO, sysinfo, total_size, 0) +- != EOK) +- { +- gdb_printf ("Error getting sysinfo: %d (%s)\n", errno, +- safe_strerror (errno)); +- error (_("Devctl failed.")); +- } +- else +- { +- if (sysinfo->type != +- nto_map_arch_to_cputype +- (gdbarch_bfd_arch_info +- (current_inferior ()->arch ())->arch_name)) +- error (_("Invalid target CPU.")); +- } +- } +- } +- +- inf_child_target::open (arg, from_tty); +- gdb_printf ("Debugging using %s\n", nto_procfs_path); +-} +- +-static void +-procfs_set_thread (ptid_t ptid) +-{ +- pid_t tid; +- +- tid = ptid.tid (); +- devctl (ctl_fd, DCMD_PROC_CURTHREAD, &tid, sizeof (tid), 0); +-} +- +-/* Return true if the thread TH is still alive. */ +- +-bool +-nto_procfs_target::thread_alive (ptid_t ptid) +-{ +- pid_t tid; +- pid_t pid; +- procfs_status status; +- int err; +- +- tid = ptid.tid (); +- pid = ptid.pid (); +- +- if (kill (pid, 0) == -1) +- return false; +- +- status.tid = tid; +- if ((err = devctl (ctl_fd, DCMD_PROC_TIDSTATUS, +- &status, sizeof (status), 0)) != EOK) +- return false; +- +- /* Thread is alive or dead but not yet joined, +- or dead and there is an alive (or dead unjoined) thread with +- higher tid. +- +- If the tid is not the same as requested, requested tid is dead. */ +- return (status.tid == tid) && (status.state != STATE_DEAD); +-} +- +-static void +-update_thread_private_data_name (struct thread_info *new_thread, +- const char *newname) +-{ +- nto_thread_info *pti = get_nto_thread_info (new_thread); +- +- gdb_assert (newname != NULL); +- gdb_assert (new_thread != NULL); +- +- if (pti) +- { +- pti = new nto_thread_info; +- new_thread->priv.reset (pti); +- } +- +- pti->name = newname; +-} +- +-static void +-update_thread_private_data (struct thread_info *new_thread, +- pthread_t tid, int state, int flags) +-{ +- procfs_info pidinfo; +- struct _thread_name *tn; +- procfs_threadctl tctl; +- +-#if _NTO_VERSION > 630 +- gdb_assert (new_thread != NULL); +- +- if (devctl (ctl_fd, DCMD_PROC_INFO, &pidinfo, +- sizeof(pidinfo), 0) != EOK) +- return; +- +- memset (&tctl, 0, sizeof (tctl)); +- tctl.cmd = _NTO_TCTL_NAME; +- tn = (struct _thread_name *) (&tctl.data); +- +- /* Fetch name for the given thread. */ +- tctl.tid = tid; +- tn->name_buf_len = sizeof (tctl.data) - sizeof (*tn); +- tn->new_name_len = -1; /* Getting, not setting. */ +- if (devctl (ctl_fd, DCMD_PROC_THREADCTL, &tctl, sizeof (tctl), NULL) != EOK) +- tn->name_buf[0] = '\0'; +- +- tn->name_buf[_NTO_THREAD_NAME_MAX] = '\0'; +- +- update_thread_private_data_name (new_thread, tn->name_buf); +- +- nto_thread_info *pti = get_nto_thread_info (new_thread); +- pti->tid = tid; +- pti->state = state; +- pti->flags = flags; +-#endif /* _NTO_VERSION */ +-} +- +-void +-nto_procfs_target::update_thread_list () +-{ +- procfs_status status; +- pid_t pid; +- ptid_t ptid; +- pthread_t tid; +- struct thread_info *new_thread; +- +- if (ctl_fd == -1) +- return; +- +- prune_threads (); +- +- pid = current_inferior ()->pid; +- +- status.tid = 1; +- +- for (tid = 1;; ++tid) +- { +- if (status.tid == tid +- && (devctl (ctl_fd, DCMD_PROC_TIDSTATUS, &status, sizeof (status), 0) +- != EOK)) +- break; +- if (status.tid != tid) +- /* The reason why this would not be equal is that devctl might have +- returned different tid, meaning the requested tid no longer exists +- (e.g. thread exited). */ +- continue; +- ptid = ptid_t (pid, 0, tid); +- new_thread = this->find_thread (ptid); +- if (!new_thread) +- new_thread = add_thread (ptid); +- update_thread_private_data (new_thread, tid, status.state, 0); +- status.tid++; +- } +- return; +-} +- +-static void +-procfs_pidlist (const char *args, int from_tty) +-{ +- struct dirent *dirp = NULL; +- char buf[PATH_MAX]; +- procfs_info *pidinfo = NULL; +- procfs_debuginfo *info = NULL; +- procfs_status *status = NULL; +- pid_t num_threads = 0; +- pid_t pid; +- char name[512]; +- char procfs_dir[PATH_MAX]; +- +- snprintf (procfs_dir, sizeof (procfs_dir), "%s%s", +- (nodestr != NULL) ? nodestr : "", "/proc"); +- +- gdb_dir_up dp (opendir (procfs_dir)); +- if (dp == NULL) +- { +- gdb_printf (gdb_stderr, "failed to opendir \"%s\" - %d (%s)", +- procfs_dir, errno, safe_strerror (errno)); +- return; +- } +- +- /* Start scan at first pid. */ +- rewinddir (dp.get ()); +- +- do +- { +- /* Get the right pid and procfs path for the pid. */ +- do +- { +- dirp = readdir (dp.get ()); +- if (dirp == NULL) +- return; +- snprintf (buf, sizeof (buf), "%s%s/%s/as", +- (nodestr != NULL) ? nodestr : "", +- "/proc", dirp->d_name); +- pid = atoi (dirp->d_name); +- } +- while (pid == 0); +- +- /* Open the procfs path. */ +- scoped_fd fd (open (buf, O_RDONLY)); +- if (fd.get () == -1) +- { +- gdb_printf (gdb_stderr, "failed to open %s - %d (%s)\n", +- buf, errno, safe_strerror (errno)); +- continue; +- } +- +- pidinfo = (procfs_info *) buf; +- if (devctl (fd.get (), DCMD_PROC_INFO, pidinfo, sizeof (buf), 0) != EOK) +- { +- gdb_printf (gdb_stderr, +- "devctl DCMD_PROC_INFO failed - %d (%s)\n", +- errno, safe_strerror (errno)); +- break; +- } +- num_threads = pidinfo->num_threads; +- +- info = (procfs_debuginfo *) buf; +- if (devctl (fd.get (), DCMD_PROC_MAPDEBUG_BASE, info, sizeof (buf), 0) +- != EOK) +- strcpy (name, "unavailable"); +- else +- strcpy (name, info->path); +- +- /* Collect state info on all the threads. */ +- status = (procfs_status *) buf; +- for (status->tid = 1; status->tid <= num_threads; status->tid++) +- { +- const int err +- = devctl (fd.get (), DCMD_PROC_TIDSTATUS, status, sizeof (buf), 0); +- gdb_printf ("%s - %d", name, pid); +- if (err == EOK && status->tid != 0) +- gdb_printf ("/%d\n", status->tid); +- else +- { +- gdb_printf ("\n"); +- break; +- } +- } +- } +- while (dirp != NULL); +-} +- +-static void +-procfs_meminfo (const char *args, int from_tty) +-{ +- procfs_mapinfo *mapinfos = NULL; +- static int num_mapinfos = 0; +- procfs_mapinfo *mapinfo_p, *mapinfo_p2; +- int flags = ~0, err, num, i, j; +- +- struct +- { +- procfs_debuginfo info; +- char buff[_POSIX_PATH_MAX]; +- } map; +- +- struct info +- { +- unsigned addr; +- unsigned size; +- unsigned flags; +- unsigned debug_vaddr; +- unsigned long long offset; +- }; +- +- struct printinfo +- { +- unsigned long long ino; +- unsigned dev; +- struct info text; +- struct info data; +- char name[256]; +- } printme; +- +- /* Get the number of map entrys. */ +- err = devctl (ctl_fd, DCMD_PROC_MAPINFO, NULL, 0, &num); +- if (err != EOK) +- { +- printf ("failed devctl num mapinfos - %d (%s)\n", err, +- safe_strerror (err)); +- return; +- } +- +- mapinfos = XNEWVEC (procfs_mapinfo, num); +- +- num_mapinfos = num; +- mapinfo_p = mapinfos; +- +- /* Fill the map entrys. */ +- err = devctl (ctl_fd, DCMD_PROC_MAPINFO, mapinfo_p, num +- * sizeof (procfs_mapinfo), &num); +- if (err != EOK) +- { +- printf ("failed devctl mapinfos - %d (%s)\n", err, safe_strerror (err)); +- xfree (mapinfos); +- return; +- } +- +- num = std::min (num, num_mapinfos); +- +- /* Run through the list of mapinfos, and store the data and text info +- so we can print it at the bottom of the loop. */ +- for (mapinfo_p = mapinfos, i = 0; i < num; i++, mapinfo_p++) +- { +- if (!(mapinfo_p->flags & flags)) +- mapinfo_p->ino = 0; +- +- if (mapinfo_p->ino == 0) /* Already visited. */ +- continue; +- +- map.info.vaddr = mapinfo_p->vaddr; +- +- err = devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map), 0); +- if (err != EOK) +- continue; +- +- memset (&printme, 0, sizeof printme); +- printme.dev = mapinfo_p->dev; +- printme.ino = mapinfo_p->ino; +- printme.text.addr = mapinfo_p->vaddr; +- printme.text.size = mapinfo_p->size; +- printme.text.flags = mapinfo_p->flags; +- printme.text.offset = mapinfo_p->offset; +- printme.text.debug_vaddr = map.info.vaddr; +- strcpy (printme.name, map.info.path); +- +- /* Check for matching data. */ +- for (mapinfo_p2 = mapinfos, j = 0; j < num; j++, mapinfo_p2++) +- { +- if (mapinfo_p2->vaddr != mapinfo_p->vaddr +- && mapinfo_p2->ino == mapinfo_p->ino +- && mapinfo_p2->dev == mapinfo_p->dev) +- { +- map.info.vaddr = mapinfo_p2->vaddr; +- err = +- devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map), 0); +- if (err != EOK) +- continue; +- +- if (strcmp (map.info.path, printme.name)) +- continue; +- +- /* Lower debug_vaddr is always text, if necessary, swap. */ +- if ((int) map.info.vaddr < (int) printme.text.debug_vaddr) +- { +- memcpy (&(printme.data), &(printme.text), +- sizeof (printme.data)); +- printme.text.addr = mapinfo_p2->vaddr; +- printme.text.size = mapinfo_p2->size; +- printme.text.flags = mapinfo_p2->flags; +- printme.text.offset = mapinfo_p2->offset; +- printme.text.debug_vaddr = map.info.vaddr; +- } +- else +- { +- printme.data.addr = mapinfo_p2->vaddr; +- printme.data.size = mapinfo_p2->size; +- printme.data.flags = mapinfo_p2->flags; +- printme.data.offset = mapinfo_p2->offset; +- printme.data.debug_vaddr = map.info.vaddr; +- } +- mapinfo_p2->ino = 0; +- } +- } +- mapinfo_p->ino = 0; +- +- gdb_printf ("%s\n", printme.name); +- gdb_printf ("\ttext=%08x bytes @ 0x%08x\n", printme.text.size, +- printme.text.addr); +- gdb_printf ("\t\tflags=%08x\n", printme.text.flags); +- gdb_printf ("\t\tdebug=%08x\n", printme.text.debug_vaddr); +- gdb_printf ("\t\toffset=%s\n", phex (printme.text.offset, 8)); +- if (printme.data.size) +- { +- gdb_printf ("\tdata=%08x bytes @ 0x%08x\n", printme.data.size, +- printme.data.addr); +- gdb_printf ("\t\tflags=%08x\n", printme.data.flags); +- gdb_printf ("\t\tdebug=%08x\n", printme.data.debug_vaddr); +- gdb_printf ("\t\toffset=%s\n", phex (printme.data.offset, 8)); +- } +- gdb_printf ("\tdev=0x%x\n", printme.dev); +- gdb_printf ("\tino=0x%x\n", (unsigned int) printme.ino); +- } +- xfree (mapinfos); +- return; +-} +- +-/* Print status information about what we're accessing. */ +-void +-nto_procfs_target::files_info () +-{ +- struct inferior *inf = current_inferior (); +- +- gdb_printf ("\tUsing the running image of %s %s via %s.\n", +- inf->attach_flag ? "attached" : "child", +- target_pid_to_str (ptid_t (inf->pid)).c_str (), +- (nodestr != NULL) ? nodestr : "local node"); +-} +- +-/* Target to_pid_to_exec_file implementation. */ +- +-const char * +-nto_procfs_target::pid_to_exec_file (const int pid) +-{ +- int proc_fd; +- static char proc_path[PATH_MAX]; +- ssize_t rd; +- +- /* Read exe file name. */ +- snprintf (proc_path, sizeof (proc_path), "%s/proc/%d/exefile", +- (nodestr != NULL) ? nodestr : "", pid); +- proc_fd = open (proc_path, O_RDONLY); +- if (proc_fd == -1) +- return NULL; +- +- rd = read (proc_fd, proc_path, sizeof (proc_path) - 1); +- close (proc_fd); +- if (rd <= 0) +- { +- proc_path[0] = '\0'; +- return NULL; +- } +- proc_path[rd] = '\0'; +- return proc_path; +-} +- +-/* Attach to process PID, then initialize for debugging it. */ +-void +-nto_procfs_target::attach (const char *args, int from_tty) +-{ +- int pid; +- struct inferior *inf; +- +- pid = parse_pid_to_attach (args); +- +- if (pid == getpid ()) +- error (_("Attaching GDB to itself is not a good idea...")); +- +- target_announce_attach (from_tty, pid); +- +- ptid_t ptid = do_attach (ptid_t (pid)); +- inf = current_inferior (); +- inferior_appeared (inf, pid); +- inf->attach_flag = true; +- +- if (!inf->target_is_pushed (ops)) +- inf->push_target (ops); +- +- update_thread_list (); +- +- switch_to_thread (this->find_thread (ptid)); +-} +- +-void +-nto_procfs_target::post_attach (pid_t pid) +-{ +- if (current_program_space->exec_bfd ()) +- solib_create_inferior_hook (0); +-} +- +-static ptid_t +-do_attach (ptid_t ptid) +-{ +- procfs_status status; +- struct sigevent event; +- char path[PATH_MAX]; +- +- snprintf (path, PATH_MAX - 1, "%s%s/%d/as", +- (nodestr != NULL) ? nodestr : "", "/proc", ptid.pid ()); +- ctl_fd = open (path, O_RDWR); +- if (ctl_fd == -1) +- error (_("Couldn't open proc file %s, error %d (%s)"), path, errno, +- safe_strerror (errno)); +- if (devctl (ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0) != EOK) +- error (_("Couldn't stop process")); +- +- /* Define a sigevent for process stopped notification. */ +- event.sigev_notify = SIGEV_SIGNAL_THREAD; +- event.sigev_signo = SIGUSR1; +- event.sigev_code = 0; +- event.sigev_value.sival_ptr = NULL; +- event.sigev_priority = -1; +- devctl (ctl_fd, DCMD_PROC_EVENT, &event, sizeof (event), 0); +- +- if (devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0) == EOK +- && status.flags & _DEBUG_FLAG_STOPPED) +- SignalKill (nto_node (), ptid.pid (), 0, SIGCONT, 0, 0); +- nto_init_solib_absolute_prefix (); +- return ptid_t (ptid.pid (), 0, status.tid); +-} +- +-/* Ask the user what to do when an interrupt is received. */ +-static void +-interrupt_query (void) +-{ +- if (query (_("Interrupted while waiting for the program.\n\ +-Give up (and stop debugging it)? "))) +- { +- target_mourn_inferior (inferior_ptid); +- quit (); +- } +-} +- +-/* The user typed ^C twice. */ +-static void +-nto_handle_sigint_twice (int signo) +-{ +- signal (signo, ofunc); +- interrupt_query (); +- signal (signo, nto_handle_sigint_twice); +-} +- +-static void +-nto_handle_sigint (int signo) +-{ +- /* If this doesn't work, try more severe steps. */ +- signal (signo, nto_handle_sigint_twice); +- +- target_interrupt (); +-} +- +-sptid_t +-nto_procfs_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, +- target_wait_flags options) +-{ +- sigset_t set; +- siginfo_t info; +- procfs_status status; +- static int exit_signo = 0; /* To track signals that cause termination. */ +- +- ourstatus->set_spurious (); +- +- if (inferior_ptid == null_ptid) +- { +- ourstatus->set_stopped (GDB_SIGNAL_0); +- exit_signo = 0; +- return null_ptid; +- } +- +- sigemptyset (&set); +- sigaddset (&set, SIGUSR1); +- +- devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0); +- while (!(status.flags & _DEBUG_FLAG_ISTOP)) +- { +- ofunc = signal (SIGINT, nto_handle_sigint); +- sigwaitinfo (&set, &info); +- signal (SIGINT, ofunc); +- devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0); +- } +- +- nto_inferior_data (NULL)->stopped_flags = status.flags; +- nto_inferior_data (NULL)->stopped_pc = status.ip; +- +- if (status.flags & _DEBUG_FLAG_SSTEP) +- ourstatus->set_stopped (GDB_SIGNAL_TRAP); +- /* Was it a breakpoint? */ +- else if (status.flags & _DEBUG_FLAG_TRACE) +- ourstatus->set_stopped (GDB_SIGNAL_TRAP); +- else if (status.flags & _DEBUG_FLAG_ISTOP) +- { +- switch (status.why) +- { +- case _DEBUG_WHY_SIGNALLED: +- ourstatus->set_stopped (gdb_signal_from_host (status.info.si_signo)); +- exit_signo = 0; +- break; +- case _DEBUG_WHY_FAULTED: +- if (status.info.si_signo == SIGTRAP) +- { +- ourstatus->set_stopped (0); +- exit_signo = 0; +- } +- else +- { +- ourstatus->set_stopped +- (gdb_signal_from_host (status.info.si_signo)); +- exit_signo = ourstatus->sig (); +- } +- break; +- +- case _DEBUG_WHY_TERMINATED: +- { +- int waitval = 0; +- +- waitpid (inferior_ptid.pid (), &waitval, WNOHANG); +- if (exit_signo) +- { +- /* Abnormal death. */ +- ourstatus->set_signalled (exit_signo); +- } +- else +- { +- /* Normal death. */ +- ourstatus->set_exited (WEXITSTATUS (waitval)); +- } +- exit_signo = 0; +- break; +- } +- +- case _DEBUG_WHY_REQUESTED: +- /* We are assuming a requested stop is due to a SIGINT. */ +- ourstatus->set_stopped (GDB_SIGNAL_INT); +- exit_signo = 0; +- break; +- } +- } +- +- return ptid_t (status.pid, 0, status.tid); +-} +- +-/* Read the current values of the inferior's registers, both the +- general register set and floating point registers (if supported) +- and update gdb's idea of their current values. */ +-void +-nto_procfs_target::fetch_registers (struct regcache *regcache, int regno) +-{ +- union +- { +- procfs_greg greg; +- procfs_fpreg fpreg; +- procfs_altreg altreg; +- } +- reg; +- int regsize; +- +- procfs_set_thread (regcache->ptid ()); +- if (devctl (ctl_fd, DCMD_PROC_GETGREG, ®, sizeof (reg), ®size) == EOK) +- nto_supply_gregset (regcache, (char *) ®.greg); +- if (devctl (ctl_fd, DCMD_PROC_GETFPREG, ®, sizeof (reg), ®size) +- == EOK) +- nto_supply_fpregset (regcache, (char *) ®.fpreg); +- if (devctl (ctl_fd, DCMD_PROC_GETALTREG, ®, sizeof (reg), ®size) +- == EOK) +- nto_supply_altregset (regcache, (char *) ®.altreg); +-} +- +-/* Helper for procfs_xfer_partial that handles memory transfers. +- Arguments are like target_xfer_partial. */ +- +-static enum target_xfer_status +-procfs_xfer_memory (gdb_byte *readbuf, const gdb_byte *writebuf, +- ULONGEST memaddr, ULONGEST len, ULONGEST *xfered_len) +-{ +- int nbytes; +- +- if (lseek (ctl_fd, (off_t) memaddr, SEEK_SET) != (off_t) memaddr) +- return TARGET_XFER_E_IO; +- +- if (writebuf != NULL) +- nbytes = write (ctl_fd, writebuf, len); +- else +- nbytes = read (ctl_fd, readbuf, len); +- if (nbytes <= 0) +- return TARGET_XFER_E_IO; +- *xfered_len = nbytes; +- return TARGET_XFER_OK; +-} +- +-/* Target to_xfer_partial implementation. */ +- +-enum target_xfer_status +-nto_procfs_target::xfer_partial (enum target_object object, +- const char *annex, gdb_byte *readbuf, +- const gdb_byte *writebuf, ULONGEST offset, +- ULONGEST len, ULONGEST *xfered_len) +-{ +- switch (object) +- { +- case TARGET_OBJECT_MEMORY: +- return procfs_xfer_memory (readbuf, writebuf, offset, len, xfered_len); +- case TARGET_OBJECT_AUXV: +- if (readbuf != NULL) +- { +- int err; +- CORE_ADDR initial_stack; +- debug_process_t procinfo; +- /* For 32-bit architecture, size of auxv_t is 8 bytes. */ +- const unsigned int sizeof_auxv_t = sizeof (auxv_t); +- const unsigned int sizeof_tempbuf = 20 * sizeof_auxv_t; +- int tempread; +- gdb_byte *const tempbuf = alloca (sizeof_tempbuf); +- +- if (tempbuf == NULL) +- return TARGET_XFER_E_IO; +- +- err = devctl (ctl_fd, DCMD_PROC_INFO, &procinfo, +- sizeof procinfo, 0); +- if (err != EOK) +- return TARGET_XFER_E_IO; +- +- initial_stack = procinfo.initial_stack; +- +- /* procfs is always 'self-hosted', no byte-order manipulation. */ +- tempread = nto_read_auxv_from_initial_stack (initial_stack, tempbuf, +- sizeof_tempbuf, +- sizeof (auxv_t)); +- tempread = std::min (tempread, len) - offset; +- memcpy (readbuf, tempbuf + offset, tempread); +- *xfered_len = tempread; +- return tempread ? TARGET_XFER_OK : TARGET_XFER_EOF; +- } +- /* Fallthru */ +- default: +- return this->beneath ()->xfer_partial (object, annex, +- readbuf, writebuf, offset, len, +- xfered_len); +- } +-} +- +-/* Take a program previously attached to and detaches it. +- The program resumes execution and will no longer stop +- on signals, etc. We'd better not have left any breakpoints +- in the program or it'll die when it hits one. */ +-void +-nto_procfs_target::detach (inferior *inf, int from_tty) +-{ +- target_announce_detach (); +- +- if (siggnal) +- SignalKill (nto_node (), inf->pid, 0, 0, 0, 0); +- +- close (ctl_fd); +- ctl_fd = -1; +- +- switch_to_no_thread (); +- detach_inferior (inf->pid); +- init_thread_list (); +- inf_child_maybe_unpush_target (ops); +-} +- +-static int +-procfs_breakpoint (CORE_ADDR addr, int type, int size) +-{ +- procfs_break brk; +- +- brk.type = type; +- brk.addr = addr; +- brk.size = size; +- errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0); +- if (errno != EOK) +- return 1; +- return 0; +-} +- +-int +-nto_procfs_target::insert_breakpoint (struct gdbarch *gdbarch, +- struct bp_target_info *bp_tgt) +-{ +- bp_tgt->placed_address = bp_tgt->reqstd_address; +- return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, 0); +-} +- +-int +-nto_procfs_target::remove_breakpoint (struct gdbarch *gdbarch, +- struct bp_target_info *bp_tgt, +- enum remove_bp_reason reason) +-{ +- return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, -1); +-} +- +-int +-nto_procfs_target::insert_hw_breakpoint (struct gdbarch *gdbarch, +- struct bp_target_info *bp_tgt) +-{ +- bp_tgt->placed_address = bp_tgt->reqstd_address; +- return procfs_breakpoint (bp_tgt->placed_address, +- _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0); +-} +- +-int +-nto_procfs_target::remove_hw_breakpoint (struct gdbarch *gdbarch, +- struct bp_target_info *bp_tgt) +-{ +- return procfs_breakpoint (bp_tgt->placed_address, +- _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1); +-} +- +-void +-nto_procfs_target::resume (ptid_t ptid, int step, enum gdb_signal signo) +-{ +- int signal_to_pass; +- procfs_status status; +- sigset_t *run_fault = (sigset_t *) (void *) &run.fault; +- +- if (inferior_ptid == null_ptid) +- return; +- +- procfs_set_thread (ptid == minus_one_ptid ? inferior_ptid : +- ptid); +- +- run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE; +- if (step) +- run.flags |= _DEBUG_RUN_STEP; +- +- sigemptyset (run_fault); +- sigaddset (run_fault, FLTBPT); +- sigaddset (run_fault, FLTTRACE); +- sigaddset (run_fault, FLTILL); +- sigaddset (run_fault, FLTPRIV); +- sigaddset (run_fault, FLTBOUNDS); +- sigaddset (run_fault, FLTIOVF); +- sigaddset (run_fault, FLTIZDIV); +- sigaddset (run_fault, FLTFPE); +- /* Peter V will be changing this at some point. */ +- sigaddset (run_fault, FLTPAGE); +- +- run.flags |= _DEBUG_RUN_ARM; +- +- signal_to_pass = gdb_signal_to_host (signo); +- +- if (signal_to_pass) +- { +- devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0); +- signal_to_pass = gdb_signal_to_host (signo); +- if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED)) +- { +- if (signal_to_pass != status.info.si_signo) +- { +- SignalKill (nto_node (), inferior_ptid.pid (), 0, +- signal_to_pass, 0, 0); +- run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG; +- } +- else /* Let it kill the program without telling us. */ +- sigdelset (&run.trace, signal_to_pass); +- } +- } +- else +- run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT; +- +- errno = devctl (ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0); +- if (errno != EOK) +- { +- perror (_("run error!\n")); +- return; +- } +-} +- +-void +-nto_procfs_target::mourn_inferior () +-{ +- if (inferior_ptid != null_ptid) +- { +- SignalKill (nto_node (), inferior_ptid.pid (), 0, SIGKILL, 0, 0); +- close (ctl_fd); +- } +- switch_to_no_thread (); +- init_thread_list (); +- inf_child_mourn_inferior (ops); +-} +- +-/* This function breaks up an argument string into an argument +- vector suitable for passing to execvp(). +- E.g., on "run a b c d" this routine would get as input +- the string "a b c d", and as output it would fill in argv with +- the four arguments "a", "b", "c", "d". The only additional +- functionality is simple quoting. The gdb command: +- run a "b c d" f +- will fill in argv with the three args "a", "b c d", "e". */ +-static void +-breakup_args (char *scratch, char **argv) +-{ +- char *pp, *cp = scratch; +- char quoting = 0; +- +- for (;;) +- { +- /* Scan past leading separators. */ +- quoting = 0; +- while (*cp == ' ' || *cp == '\t' || *cp == '\n') +- cp++; +- +- /* Break if at end of string. */ +- if (*cp == '\0') +- break; +- +- /* Take an arg. */ +- if (*cp == '"') +- { +- cp++; +- quoting = strchr (cp, '"') ? 1 : 0; +- } +- +- *argv++ = cp; +- +- /* Scan for next arg separator. */ +- pp = cp; +- if (quoting) +- cp = strchr (pp, '"'); +- if ((cp == NULL) || (!quoting)) +- cp = strchr (pp, ' '); +- if (cp == NULL) +- cp = strchr (pp, '\t'); +- if (cp == NULL) +- cp = strchr (pp, '\n'); +- +- /* No separators => end of string => break. */ +- if (cp == NULL) +- { +- pp = cp; +- break; +- } +- +- /* Replace the separator with a terminator. */ +- *cp++ = '\0'; +- } +- +- /* Execv requires a null-terminated arg vector. */ +- *argv = NULL; +-} +- +-void +-nto_procfs_target::create_inferior (const char *exec_file, +- const std::string &allargs, +- char **env, int from_tty) +-{ +- struct inheritance inherit; +- pid_t pid; +- int flags, errn; +- char **argv, *args; +- const char *in = "", *out = "", *err = ""; +- int fd, fds[3]; +- sigset_t set; +- struct inferior *inf; +- +- argv = xmalloc ((allargs.size () / (unsigned) 2 + 2) * +- sizeof (*argv)); +- argv[0] = const_cast (get_exec_file (1)); +- if (!argv[0]) +- { +- if (exec_file) +- argv[0] = exec_file; +- else +- return; +- } +- +- args = xstrdup (allargs.c_str ()); +- breakup_args (args, (exec_file != NULL) ? &argv[1] : &argv[0]); +- +- argv = nto_parse_redirection (argv, &in, &out, &err); +- +- fds[0] = STDIN_FILENO; +- fds[1] = STDOUT_FILENO; +- fds[2] = STDERR_FILENO; +- +- /* If the user specified I/O via gdb's --tty= arg, use it, but only +- if the i/o is not also being specified via redirection. */ +- const char *inferior_tty = current_inferior ()->tty (); +- if (inferior_tty != nullptr) +- { +- if (!in[0]) +- in = inferior_tty; +- if (!out[0]) +- out = inferior_tty; +- if (!err[0]) +- err = inferior_tty; +- } +- +- if (in[0]) +- { +- fd = open (in, O_RDONLY); +- if (fd == -1) +- perror (in); +- else +- fds[0] = fd; +- } +- if (out[0]) +- { +- fd = open (out, O_WRONLY); +- if (fd == -1) +- perror (out); +- else +- fds[1] = fd; +- } +- if (err[0]) +- { +- fd = open (err, O_WRONLY); +- if (fd == -1) +- perror (err); +- else +- fds[2] = fd; +- } +- +- /* Clear any pending SIGUSR1's but keep the behavior the same. */ +- signal (SIGUSR1, signal (SIGUSR1, SIG_IGN)); +- +- sigemptyset (&set); +- sigaddset (&set, SIGUSR1); +- sigprocmask (SIG_UNBLOCK, &set, NULL); +- +- memset (&inherit, 0, sizeof (inherit)); +- +- if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) != 0) +- { +- inherit.nd = nto_node (); +- inherit.flags |= SPAWN_SETND; +- inherit.flags &= ~SPAWN_EXEC; +- } +- inherit.flags |= SPAWN_SETGROUP | SPAWN_HOLD; +- inherit.pgroup = SPAWN_NEWPGROUP; +- pid = spawnp (argv[0], 3, fds, &inherit, argv, +- ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) == 0 ? env : 0); +- xfree (args); +- +- sigprocmask (SIG_BLOCK, &set, NULL); +- +- if (pid == -1) +- error (_("Error spawning %s: %d (%s)"), argv[0], errno, +- safe_strerror (errno)); +- +- if (fds[0] != STDIN_FILENO) +- close (fds[0]); +- if (fds[1] != STDOUT_FILENO) +- close (fds[1]); +- if (fds[2] != STDERR_FILENO) +- close (fds[2]); +- +- ptid_t ptid = do_attach (ptid_t (pid)); +- update_thread_list (); +- switch_to_thread (this->find_thread (ptid)); +- +- inf = current_inferior (); +- inferior_appeared (inf, pid); +- inf->attach_flag = false; +- +- flags = _DEBUG_FLAG_KLC; /* Kill-on-Last-Close flag. */ +- errn = devctl (ctl_fd, DCMD_PROC_SET_FLAG, &flags, sizeof (flags), 0); +- if (errn != EOK) +- { +- /* FIXME: expected warning? */ +- /* warning( "Failed to set Kill-on-Last-Close flag: errno = %d(%s)\n", +- errn, safe_strerror(errn) ); */ +- } +- if (!inf->target_is_pushed (ops)) +- inf->push_target (ops); +- target_terminal::init (); +- +- if (current_program_space->exec_bfd () != NULL +- || (current_program_space->symfile_object_file != NULL +- && current_program_space->symfile_object_file->obfd != NULL)) +- solib_create_inferior_hook (0); +-} +- +-void +-nto_procfs_target::interrupt () +-{ +- devctl (ctl_fd, DCMD_PROC_STOP, NULL, 0, 0); +-} +- +-void +-nto_procfs_target::kill () +-{ +- target_mourn_inferior (inferior_ptid); +-} +- +-/* Fill buf with regset and return devctl cmd to do the setting. Return +- -1 if we fail to get the regset. Store size of regset in regsize. */ +-static int +-get_regset (int regset, char *buf, int bufsize, int *regsize) +-{ +- int dev_get, dev_set; +- switch (regset) +- { +- case NTO_REG_GENERAL: +- dev_get = DCMD_PROC_GETGREG; +- dev_set = DCMD_PROC_SETGREG; +- break; +- +- case NTO_REG_FLOAT: +- dev_get = DCMD_PROC_GETFPREG; +- dev_set = DCMD_PROC_SETFPREG; +- break; +- +- case NTO_REG_ALT: +- dev_get = DCMD_PROC_GETALTREG; +- dev_set = DCMD_PROC_SETALTREG; +- break; +- +- case NTO_REG_SYSTEM: +- default: +- return -1; +- } +- if (devctl (ctl_fd, dev_get, buf, bufsize, regsize) != EOK) +- return -1; +- +- return dev_set; +-} +- +-void +-nto_procfs_target::store_registers (struct regcache *regcache, int regno) +-{ +- union +- { +- procfs_greg greg; +- procfs_fpreg fpreg; +- procfs_altreg altreg; +- } +- reg; +- unsigned off; +- int len, regset, regsize, dev_set, err; +- char *data; +- ptid_t ptid = regcache->ptid (); +- +- if (ptid == null_ptid) +- return; +- procfs_set_thread (ptid); +- +- if (regno == -1) +- { +- for (regset = NTO_REG_GENERAL; regset < NTO_REG_END; regset++) +- { +- dev_set = get_regset (regset, (char *) ®, +- sizeof (reg), ®size); +- if (dev_set == -1) +- continue; +- +- if (nto_regset_fill (regcache, regset, (char *) ®) == -1) +- continue; +- +- err = devctl (ctl_fd, dev_set, ®, regsize, 0); +- if (err != EOK) +- gdb_printf (gdb_stderr, +- "Warning unable to write regset %d: %s\n", +- regno, safe_strerror (err)); +- } +- } +- else +- { +- regset = nto_regset_id (regno); +- if (regset == -1) +- return; +- +- dev_set = get_regset (regset, (char *) ®, sizeof (reg), ®size); +- if (dev_set == -1) +- return; +- +- len = nto_register_area (regcache->arch (), +- regno, regset, &off); +- +- if (len < 1) +- return; +- +- regcache->raw_collect (regno, (char *) ® + off); +- +- err = devctl (ctl_fd, dev_set, ®, regsize, 0); +- if (err != EOK) +- gdb_printf (gdb_stderr, +- "Warning unable to write regset %d: %s\n", regno, +- safe_strerror (err)); +- } +-} +- +-/* Set list of signals to be handled in the target. */ +- +-void +-nto_procfs_target::pass_signals +- (gdb::array_view pass_signals) +-{ +- int signo; +- +- sigfillset (&run.trace); +- +- for (signo = 1; signo < NSIG; signo++) +- { +- int target_signo = gdb_signal_from_host (signo); +- if (target_signo < pass_signals.size () && pass_signals[target_signo]) +- sigdelset (&run.trace, signo); +- } +-} +- +-std::string +-nto_procfs_target::pid_to_str (ptid_t ptid) +-{ +- int pid, tid; +- struct tidinfo *tip; +- +- pid = ptid.pid (); +- tid = ptid.tid (); +- +-#if 0 /* NYI */ +- tip = procfs_thread_info (pid, tid); +- if (tip != NULL) +- snprintf (&buf[n], 1023, " (state = 0x%02x)", tip->state); +-#endif +- +- return string_printf ("process %d", pid); +-} +- +-/* to_can_run implementation for "target procfs". Note this really +- means "can this target be the default run target", which there can +- be only one, and we make it be "target native" like other ports. +- "target procfs " wouldn't make sense as default run target, as +- it needs . */ +- +-int +-nto_procfs_target::can_run () +-{ +- return 0; +-} +- +-/* "target procfs". */ +-static nto_procfs_target_procfs nto_procfs_ops; +- +-/* "target native". */ +-static nto_procfs_target_native nto_native_ops; +- +-/* Create the "native" and "procfs" targets. */ +- +-static void +-init_procfs_targets (void) +-{ +- /* Register "target native". This is the default run target. */ +- add_target (nto_native_target_info, inf_child_open_target); +- set_native_target (&nto_native_ops); +- +- /* Register "target procfs ". */ +- add_target (nto_procfs_target_info, inf_child_open_target); +-} +- +-#define OSTYPE_NTO 1 +- +-void _initialize_procfs (); +-void +-_initialize_procfs () +-{ +- sigset_t set; +- +- init_procfs_targets (); +- +- /* We use SIGUSR1 to gain control after we block waiting for a process. +- We use sigwaitevent to wait. */ +- sigemptyset (&set); +- sigaddset (&set, SIGUSR1); +- sigprocmask (SIG_BLOCK, &set, NULL); +- +- /* Initially, make sure all signals are reported. */ +- sigfillset (&run.trace); +- +- /* Stuff some information. */ +- nto_cpuinfo_flags = SYSPAGE_ENTRY (cpuinfo)->flags; +- nto_cpuinfo_valid = 1; +- +- add_info ("pidlist", procfs_pidlist, _("pidlist")); +- add_info ("meminfo", procfs_meminfo, _("memory information")); +- +- nto_is_nto_target = procfs_is_nto_target; +-} +- +- +-static int +-procfs_hw_watchpoint (int addr, int len, enum target_hw_bp_type type) +-{ +- procfs_break brk; +- +- switch (type) +- { +- case hw_read: +- brk.type = _DEBUG_BREAK_RD; +- break; +- case hw_access: +- brk.type = _DEBUG_BREAK_RW; +- break; +- default: /* Modify. */ +-/* FIXME: brk.type = _DEBUG_BREAK_RWM gives EINVAL for some reason. */ +- brk.type = _DEBUG_BREAK_RW; +- } +- brk.type |= _DEBUG_BREAK_HW; /* Always ask for HW. */ +- brk.addr = addr; +- brk.size = len; +- +- errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0); +- if (errno != EOK) +- { +- perror (_("Failed to set hardware watchpoint")); +- return -1; +- } +- return 0; +-} +- +-bool +-nto_procfs_target::can_use_hw_breakpoint (enum bptype type, +- int cnt, int othertype) +-{ +- return 1; +-} +- +-int +-nto_procfs_target::remove_hw_watchpoint (CORE_ADDR addr, int len, +- enum target_hw_bp_type type, +- struct expression *cond) +-{ +- return procfs_hw_watchpoint (addr, -1, type); +-} +- +-int +-nto_procfs_target::insert_hw_watchpoint (CORE_ADDR addr, int len, +- enum target_hw_bp_type type, +- struct expression *cond) +-{ +- return procfs_hw_watchpoint (addr, len, type); +-} +- +-bool +-nto_procfs_target::stopped_by_watchpoint () +-{ +- /* NOTE: nto_stopped_by_watchpoint will be called ONLY while we are +- stopped due to a SIGTRAP. This assumes gdb works in 'all-stop' mode; +- future gdb versions will likely run in 'non-stop' mode in which case +- we will have to store/examine statuses per thread in question. +- Until then, this will work fine. */ +- +- struct inferior *inf = current_inferior (); +- struct nto_inferior_data *inf_data; +- +- gdb_assert (inf != NULL); +- +- inf_data = nto_inferior_data (inf); +- +- return inf_data->stopped_flags +- & (_DEBUG_FLAG_TRACE_RD +- | _DEBUG_FLAG_TRACE_WR +- | _DEBUG_FLAG_TRACE_MODIFY); +-} +diff --git a/gdb/nto-tdep.c b/gdb/nto-tdep.c +deleted file mode 100644 +--- a/gdb/nto-tdep.c ++++ /dev/null +@@ -1,521 +0,0 @@ +-/* nto-tdep.c - general QNX Neutrino target functionality. +- +- Copyright (C) 2003-2024 Free Software Foundation, Inc. +- +- Contributed by QNX Software Systems Ltd. +- +- 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 . */ +- +-#include +-#include "nto-tdep.h" +-#include "extract-store-integer.h" +-#include "top.h" +-#include "inferior.h" +-#include "infrun.h" +-#include "gdbarch.h" +-#include "bfd.h" +-#include "elf-bfd.h" +-#include "solib-svr4.h" +-#include "gdbcore.h" +-#include "objfiles.h" +-#include "source.h" +-#include "gdbsupport/pathstuff.h" +- +-#define QNX_NOTE_NAME "QNX" +-#define QNX_INFO_SECT_NAME "QNX_info" +- +-#ifdef __CYGWIN__ +-#include +-#endif +- +-#ifdef __CYGWIN__ +-static char default_nto_target[] = "C:\\QNXsdk\\target\\qnx6"; +-#elif defined(__sun__) || defined(linux) +-static char default_nto_target[] = "/opt/QNXsdk/target/qnx6"; +-#else +-static char default_nto_target[] = ""; +-#endif +- +-struct nto_target_ops current_nto_target; +- +-static const registry::key +- nto_inferior_data_reg; +- +-static char * +-nto_target (void) +-{ +- char *p = getenv ("QNX_TARGET"); +- +-#ifdef __CYGWIN__ +- static char buf[PATH_MAX]; +- if (p) +- cygwin_conv_path (CCP_WIN_A_TO_POSIX, p, buf, PATH_MAX); +- else +- cygwin_conv_path (CCP_WIN_A_TO_POSIX, default_nto_target, buf, PATH_MAX); +- return buf; +-#else +- return p ? p : default_nto_target; +-#endif +-} +- +-/* Take a string such as i386, rs6000, etc. and map it onto CPUTYPE_X86, +- CPUTYPE_PPC, etc. as defined in nto-share/dsmsgs.h. */ +-int +-nto_map_arch_to_cputype (const char *arch) +-{ +- if (!strcmp (arch, "i386") || !strcmp (arch, "x86")) +- return CPUTYPE_X86; +- if (!strcmp (arch, "rs6000") || !strcmp (arch, "powerpc")) +- return CPUTYPE_PPC; +- if (!strcmp (arch, "mips")) +- return CPUTYPE_MIPS; +- if (!strcmp (arch, "arm")) +- return CPUTYPE_ARM; +- if (!strcmp (arch, "sh")) +- return CPUTYPE_SH; +- return CPUTYPE_UNKNOWN; +-} +- +-int +-nto_find_and_open_solib (const char *solib, unsigned o_flags, +- gdb::unique_xmalloc_ptr *temp_pathname) +-{ +- char *buf, *arch_path, *nto_root; +- const char *endian; +- const char *base; +- const char *arch; +- int arch_len, len, ret; +-#define PATH_FMT \ +- "%s/lib:%s/usr/lib:%s/usr/photon/lib:%s/usr/photon/dll:%s/lib/dll" +- +- nto_root = nto_target (); +- gdbarch *gdbarch = current_inferior ()->arch (); +- if (strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name, "i386") == 0) +- { +- arch = "x86"; +- endian = ""; +- } +- else if (strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name, +- "rs6000") == 0 +- || strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name, +- "powerpc") == 0) +- { +- arch = "ppc"; +- endian = "be"; +- } +- else +- { +- arch = gdbarch_bfd_arch_info (gdbarch)->arch_name; +- endian = gdbarch_byte_order (gdbarch) +- == BFD_ENDIAN_BIG ? "be" : "le"; +- } +- +- /* In case nto_root is short, add strlen(solib) +- so we can reuse arch_path below. */ +- +- arch_len = (strlen (nto_root) + strlen (arch) + strlen (endian) + 2 +- + strlen (solib)); +- arch_path = (char *) alloca (arch_len); +- xsnprintf (arch_path, arch_len, "%s/%s%s", nto_root, arch, endian); +- +- len = strlen (PATH_FMT) + strlen (arch_path) * 5 + 1; +- buf = (char *) alloca (len); +- xsnprintf (buf, len, PATH_FMT, arch_path, arch_path, arch_path, arch_path, +- arch_path); +- +- base = lbasename (solib); +- ret = openp (buf, OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, base, o_flags, +- temp_pathname); +- if (ret < 0 && base != solib) +- { +- xsnprintf (arch_path, arch_len, "/%s", solib); +- ret = open (arch_path, o_flags, 0); +- if (temp_pathname) +- { +- if (ret >= 0) +- *temp_pathname = gdb_realpath (arch_path); +- else +- temp_pathname->reset (NULL); +- } +- } +- return ret; +-} +- +-void +-nto_init_solib_absolute_prefix (void) +-{ +- char buf[PATH_MAX * 2], arch_path[PATH_MAX]; +- char *nto_root; +- const char *endian; +- const char *arch; +- +- nto_root = nto_target (); +- gdbarch *gdbarch = current_inferior ()->arch (); +- if (strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name, "i386") == 0) +- { +- arch = "x86"; +- endian = ""; +- } +- else if (strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name, +- "rs6000") == 0 +- || strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name, +- "powerpc") == 0) +- { +- arch = "ppc"; +- endian = "be"; +- } +- else +- { +- arch = gdbarch_bfd_arch_info (gdbarch)->arch_name; +- endian = gdbarch_byte_order (gdbarch) +- == BFD_ENDIAN_BIG ? "be" : "le"; +- } +- +- xsnprintf (arch_path, sizeof (arch_path), "%s/%s%s", nto_root, arch, endian); +- +- xsnprintf (buf, sizeof (buf), "set solib-absolute-prefix %s", arch_path); +- execute_command (buf, 0); +-} +- +-char ** +-nto_parse_redirection (char *pargv[], const char **pin, const char **pout, +- const char **perr) +-{ +- char **argv; +- const char *in, *out, *err, *p; +- int argc, i, n; +- +- for (n = 0; pargv[n]; n++); +- if (n == 0) +- return NULL; +- in = ""; +- out = ""; +- err = ""; +- +- argv = XCNEWVEC (char *, n + 1); +- argc = n; +- for (i = 0, n = 0; n < argc; n++) +- { +- p = pargv[n]; +- if (*p == '>') +- { +- p++; +- if (*p) +- out = p; +- else +- out = pargv[++n]; +- } +- else if (*p == '<') +- { +- p++; +- if (*p) +- in = p; +- else +- in = pargv[++n]; +- } +- else if (*p++ == '2' && *p++ == '>') +- { +- if (*p == '&' && *(p + 1) == '1') +- err = out; +- else if (*p) +- err = p; +- else +- err = pargv[++n]; +- } +- else +- argv[i++] = pargv[n]; +- } +- *pin = in; +- *pout = out; +- *perr = err; +- return argv; +-} +- +-static CORE_ADDR +-lm_addr (const solib &so) +-{ +- auto *li = gdb::checked_static_cast (so.lm_info.get ()); +- +- return li->l_addr; +-} +- +-static CORE_ADDR +-nto_truncate_ptr (CORE_ADDR addr) +-{ +- gdbarch *gdbarch = current_inferior ()->arch (); +- if (gdbarch_ptr_bit (gdbarch) == sizeof (CORE_ADDR) * 8) +- /* We don't need to truncate anything, and the bit twiddling below +- will fail due to overflow problems. */ +- return addr; +- else +- return addr & (((CORE_ADDR) 1 << gdbarch_ptr_bit (gdbarch)) - 1); +-} +- +-static Elf_Internal_Phdr * +-find_load_phdr (bfd *abfd) +-{ +- Elf_Internal_Phdr *phdr; +- unsigned int i; +- +- if (!elf_tdata (abfd)) +- return NULL; +- +- phdr = elf_tdata (abfd)->phdr; +- for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++) +- { +- if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X)) +- return phdr; +- } +- return NULL; +-} +- +-void +-nto_relocate_section_addresses (solib &so, target_section *sec) +-{ +- /* Neutrino treats the l_addr base address field in link.h as different than +- the base address in the System V ABI and so the offset needs to be +- calculated and applied to relocations. */ +- Elf_Internal_Phdr *phdr = find_load_phdr (sec->the_bfd_section->owner); +- unsigned vaddr = phdr ? phdr->p_vaddr : 0; +- +- sec->addr = nto_truncate_ptr (sec->addr + lm_addr (so) - vaddr); +- sec->endaddr = nto_truncate_ptr (sec->endaddr + lm_addr (so) - vaddr); +-} +- +-/* This is cheating a bit because our linker code is in libc.so. If we +- ever implement lazy linking, this may need to be re-examined. */ +-int +-nto_in_dynsym_resolve_code (CORE_ADDR pc) +-{ +- if (in_plt_section (pc)) +- return 1; +- return 0; +-} +- +-void +-nto_dummy_supply_regset (struct regcache *regcache, char *regs) +-{ +- /* Do nothing. */ +-} +- +-static void +-nto_sniff_abi_note_section (bfd *abfd, asection *sect, void *obj) +-{ +- const char *sectname; +- unsigned int sectsize; +- /* Buffer holding the section contents. */ +- char *note; +- unsigned int namelen; +- const char *name; +- const unsigned sizeof_Elf_Nhdr = 12; +- +- sectname = bfd_section_name (sect); +- sectsize = bfd_section_size (sect); +- +- if (sectsize > 128) +- sectsize = 128; +- +- if (sectname != NULL && strstr (sectname, QNX_INFO_SECT_NAME) != NULL) +- *(enum gdb_osabi *) obj = GDB_OSABI_QNXNTO; +- else if (sectname != NULL && strstr (sectname, "note") != NULL +- && sectsize > sizeof_Elf_Nhdr) +- { +- note = XNEWVEC (char, sectsize); +- bfd_get_section_contents (abfd, sect, note, 0, sectsize); +- namelen = (unsigned int) bfd_h_get_32 (abfd, note); +- name = note + sizeof_Elf_Nhdr; +- if (sectsize >= namelen + sizeof_Elf_Nhdr +- && namelen == sizeof (QNX_NOTE_NAME) +- && 0 == strcmp (name, QNX_NOTE_NAME)) +- *(enum gdb_osabi *) obj = GDB_OSABI_QNXNTO; +- +- XDELETEVEC (note); +- } +-} +- +-enum gdb_osabi +-nto_elf_osabi_sniffer (bfd *abfd) +-{ +- enum gdb_osabi osabi = GDB_OSABI_UNKNOWN; +- +- bfd_map_over_sections (abfd, +- nto_sniff_abi_note_section, +- &osabi); +- +- return osabi; +-} +- +-static const char * const nto_thread_state_str[] = +-{ +- "DEAD", /* 0 0x00 */ +- "RUNNING", /* 1 0x01 */ +- "READY", /* 2 0x02 */ +- "STOPPED", /* 3 0x03 */ +- "SEND", /* 4 0x04 */ +- "RECEIVE", /* 5 0x05 */ +- "REPLY", /* 6 0x06 */ +- "STACK", /* 7 0x07 */ +- "WAITTHREAD", /* 8 0x08 */ +- "WAITPAGE", /* 9 0x09 */ +- "SIGSUSPEND", /* 10 0x0a */ +- "SIGWAITINFO", /* 11 0x0b */ +- "NANOSLEEP", /* 12 0x0c */ +- "MUTEX", /* 13 0x0d */ +- "CONDVAR", /* 14 0x0e */ +- "JOIN", /* 15 0x0f */ +- "INTR", /* 16 0x10 */ +- "SEM", /* 17 0x11 */ +- "WAITCTX", /* 18 0x12 */ +- "NET_SEND", /* 19 0x13 */ +- "NET_REPLY" /* 20 0x14 */ +-}; +- +-const char * +-nto_extra_thread_info (struct target_ops *self, struct thread_info *ti) +-{ +- if (ti != NULL && ti->priv != NULL) +- { +- nto_thread_info *priv = get_nto_thread_info (ti); +- +- if (priv->state < ARRAY_SIZE (nto_thread_state_str)) +- return nto_thread_state_str [priv->state]; +- } +- return ""; +-} +- +-void +-nto_initialize_signals (void) +-{ +- /* We use SIG45 for pulses, or something, so nostop, noprint +- and pass them. */ +- signal_stop_update (gdb_signal_from_name ("SIG45"), 0); +- signal_print_update (gdb_signal_from_name ("SIG45"), 0); +- signal_pass_update (gdb_signal_from_name ("SIG45"), 1); +- +- /* By default we don't want to stop on these two, but we do want to pass. */ +-#if defined(SIGSELECT) +- signal_stop_update (SIGSELECT, 0); +- signal_print_update (SIGSELECT, 0); +- signal_pass_update (SIGSELECT, 1); +-#endif +- +-#if defined(SIGPHOTON) +- signal_stop_update (SIGPHOTON, 0); +- signal_print_update (SIGPHOTON, 0); +- signal_pass_update (SIGPHOTON, 1); +-#endif +-} +- +-/* Read AUXV from initial_stack. */ +-LONGEST +-nto_read_auxv_from_initial_stack (CORE_ADDR initial_stack, gdb_byte *readbuf, +- LONGEST len, size_t sizeof_auxv_t) +-{ +- gdb_byte targ32[4]; /* For 32 bit target values. */ +- gdb_byte targ64[8]; /* For 64 bit target values. */ +- CORE_ADDR data_ofs = 0; +- ULONGEST anint; +- LONGEST len_read = 0; +- gdb_byte *buff; +- enum bfd_endian byte_order; +- int ptr_size; +- +- if (sizeof_auxv_t == 16) +- ptr_size = 8; +- else +- ptr_size = 4; +- +- /* Skip over argc, argv and envp... Comment from ldd.c: +- +- The startup frame is set-up so that we have: +- auxv +- NULL +- ... +- envp2 +- envp1 <----- void *frame + (argc + 2) * sizeof(char *) +- NULL +- ... +- argv2 +- argv1 +- argc <------ void * frame +- +- On entry to ldd, frame gives the address of argc on the stack. */ +- /* Read argc. 4 bytes on both 64 and 32 bit arches and luckily little +- * endian. So we just read first 4 bytes. */ +- if (target_read_memory (initial_stack + data_ofs, targ32, 4) != 0) +- return 0; +- +- byte_order = gdbarch_byte_order (current_inferior ()->arch ()); +- +- anint = extract_unsigned_integer (targ32, sizeof (targ32), byte_order); +- +- /* Size of pointer is assumed to be 4 bytes (32 bit arch.) */ +- data_ofs += (anint + 2) * ptr_size; /* + 2 comes from argc itself and +- NULL terminating pointer in +- argv. */ +- +- /* Now loop over env table: */ +- anint = 0; +- while (target_read_memory (initial_stack + data_ofs, targ64, ptr_size) +- == 0) +- { +- if (extract_unsigned_integer (targ64, ptr_size, byte_order) == 0) +- anint = 1; /* Keep looping until non-null entry is found. */ +- else if (anint) +- break; +- data_ofs += ptr_size; +- } +- initial_stack += data_ofs; +- +- memset (readbuf, 0, len); +- buff = readbuf; +- while (len_read <= len-sizeof_auxv_t) +- { +- if (target_read_memory (initial_stack + len_read, buff, sizeof_auxv_t) +- == 0) +- { +- /* Both 32 and 64 bit structures have int as the first field. */ +- const ULONGEST a_type +- = extract_unsigned_integer (buff, sizeof (targ32), byte_order); +- +- if (a_type == AT_NULL) +- break; +- buff += sizeof_auxv_t; +- len_read += sizeof_auxv_t; +- } +- else +- break; +- } +- return len_read; +-} +- +-/* Return nto_inferior_data for the given INFERIOR. If not yet created, +- construct it. */ +- +-struct nto_inferior_data * +-nto_inferior_data (struct inferior *const inferior) +-{ +- struct inferior *const inf = inferior ? inferior : current_inferior (); +- struct nto_inferior_data *inf_data; +- +- gdb_assert (inf != NULL); +- +- inf_data = nto_inferior_data_reg.get (inf); +- if (inf_data == NULL) +- inf_data = nto_inferior_data_reg.emplace (inf); +- +- return inf_data; +-} +diff --git a/gdb/nto-tdep.h b/gdb/nto-tdep.h +deleted file mode 100644 +--- a/gdb/nto-tdep.h ++++ /dev/null +@@ -1,194 +0,0 @@ +-/* nto-tdep.h - QNX Neutrino target header. +- +- Copyright (C) 2003-2024 Free Software Foundation, Inc. +- +- Contributed by QNX Software Systems Ltd. +- +- 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 . */ +- +-#ifndef NTO_TDEP_H +-#define NTO_TDEP_H +- +-#include "solist.h" +-#include "osabi.h" +-#include "regset.h" +-#include "gdbthread.h" +-#include "gdbsupport/gdb-checked-static-cast.h" +- +-/* Target operations defined for Neutrino targets (-nto-tdep.c). */ +- +-struct nto_target_ops +-{ +-/* The CPUINFO flags from the remote. Currently used by +- i386 for fxsave but future proofing other hosts. +- This is initialized in procfs_attach or nto_start_remote +- depending on our host/target. It would only be invalid +- if we were talking to an older pdebug which didn't support +- the cpuinfo message. */ +- unsigned cpuinfo_flags; +- +-/* True if successfully retrieved cpuinfo from remote. */ +- int cpuinfo_valid; +- +-/* Given a register, return an id that represents the Neutrino +- regset it came from. If reg == -1 update all regsets. */ +- int (*regset_id) (int); +- +- void (*supply_gregset) (struct regcache *, char *); +- +- void (*supply_fpregset) (struct regcache *, char *); +- +- void (*supply_altregset) (struct regcache *, char *); +- +-/* Given a regset, tell gdb about registers stored in data. */ +- void (*supply_regset) (struct regcache *, int, char *); +- +-/* Given a register and regset, calculate the offset into the regset +- and stuff it into the last argument. If regno is -1, calculate the +- size of the entire regset. Returns length of data, -1 if unknown +- regset, 0 if unknown register. */ +- int (*register_area) (struct gdbarch *, int, int, unsigned *); +- +-/* Build the Neutrino register set info into the data buffer. +- Return -1 if unknown regset, 0 otherwise. */ +- int (*regset_fill) (const struct regcache *, int, char *); +- +-/* Gives the fetch_link_map_offsets function exposure outside of +- solib-svr4.c so that we can override relocate_section_addresses(). */ +- struct link_map_offsets *(*fetch_link_map_offsets) (void); +- +-/* Used by nto_elf_osabi_sniffer to determine if we're connected to an +- Neutrino target. */ +- enum gdb_osabi (*is_nto_target) (bfd *abfd); +-}; +- +-extern struct nto_target_ops current_nto_target; +- +-#define nto_cpuinfo_flags (current_nto_target.cpuinfo_flags) +- +-#define nto_cpuinfo_valid (current_nto_target.cpuinfo_valid) +- +-#define nto_regset_id (current_nto_target.regset_id) +- +-#define nto_supply_gregset (current_nto_target.supply_gregset) +- +-#define nto_supply_fpregset (current_nto_target.supply_fpregset) +- +-#define nto_supply_altregset (current_nto_target.supply_altregset) +- +-#define nto_supply_regset (current_nto_target.supply_regset) +- +-#define nto_register_area (current_nto_target.register_area) +- +-#define nto_regset_fill (current_nto_target.regset_fill) +- +-#define nto_fetch_link_map_offsets \ +-(current_nto_target.fetch_link_map_offsets) +- +-#define nto_is_nto_target (current_nto_target.is_nto_target) +- +-/* Keep this consistant with neutrino syspage.h. */ +-enum +-{ +- CPUTYPE_X86, +- CPUTYPE_PPC, +- CPUTYPE_MIPS, +- CPUTYPE_SPARE, +- CPUTYPE_ARM, +- CPUTYPE_SH, +- CPUTYPE_UNKNOWN +-}; +- +-enum +-{ +- OSTYPE_QNX4, +- OSTYPE_NTO +-}; +- +-/* These correspond to the DSMSG_* versions in dsmsgs.h. */ +-enum +-{ +- NTO_REG_GENERAL, +- NTO_REG_FLOAT, +- NTO_REG_SYSTEM, +- NTO_REG_ALT, +- NTO_REG_END +-}; +- +-typedef char qnx_reg64[8]; +- +-typedef struct _debug_regs +-{ +- qnx_reg64 padding[1024]; +-} nto_regset_t; +- +-struct nto_thread_info : public private_thread_info +-{ +- short tid = 0; +- unsigned char state = 0; +- unsigned char flags = 0; +- std::string name; +-}; +- +-static inline nto_thread_info * +-get_nto_thread_info (thread_info *thread) +-{ +- return gdb::checked_static_cast (thread->priv.get ()); +-} +- +-/* Per-inferior data, common for both procfs and remote. */ +-struct nto_inferior_data +-{ +- /* Last stopped flags result from wait function */ +- unsigned int stopped_flags = 0; +- +- /* Last known stopped PC */ +- CORE_ADDR stopped_pc = 0; +-}; +- +-/* Generic functions in nto-tdep.c. */ +- +-void nto_init_solib_absolute_prefix (void); +- +-char **nto_parse_redirection (char *start_argv[], const char **in, +- const char **out, const char **err); +- +-void nto_relocate_section_addresses (solib &, target_section *); +- +-int nto_map_arch_to_cputype (const char *); +- +-int nto_find_and_open_solib (const char *, unsigned, +- gdb::unique_xmalloc_ptr *); +- +-enum gdb_osabi nto_elf_osabi_sniffer (bfd *abfd); +- +-void nto_initialize_signals (void); +- +-/* Dummy function for initializing nto_target_ops on targets which do +- not define a particular regset. */ +-void nto_dummy_supply_regset (struct regcache *regcache, char *regs); +- +-int nto_in_dynsym_resolve_code (CORE_ADDR pc); +- +-const char *nto_extra_thread_info (struct target_ops *self, struct thread_info *); +- +-LONGEST nto_read_auxv_from_initial_stack (CORE_ADDR initial_stack, +- gdb_byte *readbuf, +- LONGEST len, size_t sizeof_auxv_t); +- +-struct nto_inferior_data *nto_inferior_data (struct inferior *inf); +- +-#endif /* NTO_TDEP_H */ +diff --git a/gdb/osabi.c b/gdb/osabi.c +--- a/gdb/osabi.c ++++ b/gdb/osabi.c +@@ -70,7 +70,6 @@ static const struct osabi_names gdb_osabi_names[] = + { "OpenBSD", NULL }, + { "WindowsCE", NULL }, + { "DJGPP", NULL }, +- { "QNX-Neutrino", NULL }, + { "Cygwin", NULL }, + { "Windows", NULL }, + { "AIX", NULL }, +diff --git a/gdb/osabi.h b/gdb/osabi.h +--- a/gdb/osabi.h ++++ b/gdb/osabi.h +@@ -35,7 +35,6 @@ enum gdb_osabi + GDB_OSABI_OPENBSD, + GDB_OSABI_WINCE, + GDB_OSABI_GO32, +- GDB_OSABI_QNXNTO, + GDB_OSABI_CYGWIN, + GDB_OSABI_WINDOWS, + GDB_OSABI_AIX, +diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp +--- a/gdb/testsuite/lib/gdb.exp ++++ b/gdb/testsuite/lib/gdb.exp +@@ -8079,7 +8079,6 @@ gdb_caching_proc gdb_has_argv0 {} { + || [istarget *-wince-pe] || [istarget *-*-mingw32ce*] + || [istarget *-*-osf*] + || [istarget *-*-dicos*] +- || [istarget *-*-nto*] + || [istarget *-*-*vms*] + || [istarget *-*-lynx*178]) } { + fail "argv\[0\] should be available on this target" diff --git a/gdb-rhbz-2232086-cpp-ify-mapped-symtab.patch b/gdb-rhbz-2232086-cpp-ify-mapped-symtab.patch deleted file mode 100644 index 0b2e9a1..0000000 --- a/gdb-rhbz-2232086-cpp-ify-mapped-symtab.patch +++ /dev/null @@ -1,264 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Andrew Burgess -Date: Sat, 25 Nov 2023 10:35:37 +0000 -Subject: gdb-rhbz-2232086-cpp-ify-mapped-symtab.patch - -;; Back-port upstream commit acc117b57f7 as part of a fix for -;; non-deterministic gdb-index generation (RH BZ 2232086). - -gdb: C++-ify mapped_symtab from dwarf2/index-write.c - -Make static the functions add_index_entry, find_slot, and hash_expand, -member functions of the mapped_symtab class. - -Fold an additional snippet of code from write_gdbindex into -mapped_symtab::minimize, this code relates to minimisation, so this -seems like a good home for it. - -Make the n_elements, data, and m_string_obstack member variables of -mapped_symtab private. Provide a new obstack() member function to -provide access to the obstack when needed, and also add member -functions begin(), end(), cbegin(), and cend() so that the -mapped_symtab class can be treated like a contained and iterated -over. - -I've also taken this opportunity to split out the logic for whether -the hash table (m_data) needs expanding, this is the new function -hash_needs_expanding. This will be useful in a later commit. - -There should be no user visible changes after this commit. - -Approved-By: Tom Tromey - -diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c ---- a/gdb/dwarf2/index-write.c -+++ b/gdb/dwarf2/index-write.c -@@ -187,86 +187,135 @@ struct mapped_symtab - { - mapped_symtab () - { -- data.resize (1024); -+ m_data.resize (1024); - } - -- /* Minimize each entry in the symbol table, removing duplicates. */ -+ /* If there are no elements in the symbol table, then reduce the table -+ size to zero. Otherwise call symtab_index_entry::minimize each entry -+ in the symbol table. */ -+ - void minimize () - { -- for (symtab_index_entry &item : data) -+ if (m_element_count == 0) -+ m_data.resize (0); -+ -+ for (symtab_index_entry &item : m_data) - item.minimize (); - } - -- offset_type n_elements = 0; -- std::vector data; -+ /* Add an entry to SYMTAB. NAME is the name of the symbol. CU_INDEX is -+ the index of the CU in which the symbol appears. IS_STATIC is one if -+ the symbol is static, otherwise zero (global). */ -+ -+ void add_index_entry (const char *name, int is_static, -+ gdb_index_symbol_kind kind, offset_type cu_index); -+ -+ /* Access the obstack. */ -+ struct obstack *obstack () -+ { return &m_string_obstack; } -+ -+private: -+ -+ /* Find a slot in SYMTAB for the symbol NAME. Returns a reference to -+ the slot. -+ -+ Function is used only during write_hash_table so no index format -+ backward compatibility is needed. */ -+ -+ symtab_index_entry &find_slot (const char *name); -+ -+ /* Expand SYMTAB's hash table. */ -+ -+ void hash_expand (); -+ -+ /* Return true if the hash table in data needs to grow. */ -+ -+ bool hash_needs_expanding () const -+ { return 4 * m_element_count / 3 >= m_data.size (); } -+ -+ /* A vector that is used as a hash table. */ -+ std::vector m_data; -+ -+ /* The number of elements stored in the m_data hash. */ -+ offset_type m_element_count = 0; - - /* Temporary storage for names. */ - auto_obstack m_string_obstack; --}; - --/* Find a slot in SYMTAB for the symbol NAME. Returns a reference to -- the slot. -+public: -+ using iterator = decltype (m_data)::iterator; -+ using const_iterator = decltype (m_data)::const_iterator; - -- Function is used only during write_hash_table so no index format backward -- compatibility is needed. */ -+ iterator begin () -+ { return m_data.begin (); } - --static symtab_index_entry & --find_slot (struct mapped_symtab *symtab, const char *name) -+ iterator end () -+ { return m_data.end (); } -+ -+ const_iterator cbegin () -+ { return m_data.cbegin (); } -+ -+ const_iterator cend () -+ { return m_data.cend (); } -+}; -+ -+/* See class definition. */ -+ -+symtab_index_entry & -+mapped_symtab::find_slot (const char *name) - { - offset_type index, step, hash = mapped_index_string_hash (INT_MAX, name); - -- index = hash & (symtab->data.size () - 1); -- step = ((hash * 17) & (symtab->data.size () - 1)) | 1; -+ index = hash & (m_data.size () - 1); -+ step = ((hash * 17) & (m_data.size () - 1)) | 1; - - for (;;) - { -- if (symtab->data[index].name == NULL -- || strcmp (name, symtab->data[index].name) == 0) -- return symtab->data[index]; -- index = (index + step) & (symtab->data.size () - 1); -+ if (m_data[index].name == NULL -+ || strcmp (name, m_data[index].name) == 0) -+ return m_data[index]; -+ index = (index + step) & (m_data.size () - 1); - } - } - --/* Expand SYMTAB's hash table. */ -+/* See class definition. */ - --static void --hash_expand (struct mapped_symtab *symtab) -+void -+mapped_symtab::hash_expand () - { -- auto old_entries = std::move (symtab->data); -+ auto old_entries = std::move (m_data); - -- symtab->data.clear (); -- symtab->data.resize (old_entries.size () * 2); -+ gdb_assert (m_data.size () == 0); -+ m_data.resize (old_entries.size () * 2); - - for (auto &it : old_entries) - if (it.name != NULL) - { -- auto &ref = find_slot (symtab, it.name); -+ auto &ref = this->find_slot (it.name); - ref = std::move (it); - } - } - --/* Add an entry to SYMTAB. NAME is the name of the symbol. -- CU_INDEX is the index of the CU in which the symbol appears. -- IS_STATIC is one if the symbol is static, otherwise zero (global). */ -+/* See class definition. */ - --static void --add_index_entry (struct mapped_symtab *symtab, const char *name, -- int is_static, gdb_index_symbol_kind kind, -- offset_type cu_index) -+void -+mapped_symtab::add_index_entry (const char *name, int is_static, -+ gdb_index_symbol_kind kind, -+ offset_type cu_index) - { -- symtab_index_entry *slot = &find_slot (symtab, name); -+ symtab_index_entry *slot = &this->find_slot (name); - if (slot->name == NULL) - { - /* This is a new element in the hash table. */ -- ++symtab->n_elements; -+ ++this->m_element_count; - - /* We might need to grow the hash table. */ -- if (4 * symtab->n_elements / 3 >= symtab->data.size ()) -+ if (this->hash_needs_expanding ()) - { -- hash_expand (symtab); -+ this->hash_expand (); - - /* This element will have a different slot in the new table. */ -- slot = &find_slot (symtab, name); -+ slot = &this->find_slot (name); - - /* But it should still be a new element in the hash table. */ - gdb_assert (slot->name == nullptr); -@@ -387,7 +436,7 @@ write_hash_table (mapped_symtab *symtab, data_buf &output, data_buf &cpool) - - /* We add all the index vectors to the constant pool first, to - ensure alignment is ok. */ -- for (symtab_index_entry &entry : symtab->data) -+ for (symtab_index_entry &entry : *symtab) - { - if (entry.name == NULL) - continue; -@@ -416,7 +465,7 @@ write_hash_table (mapped_symtab *symtab, data_buf &output, data_buf &cpool) - - /* Now write out the hash table. */ - std::unordered_map str_table; -- for (const auto &entry : symtab->data) -+ for (const auto &entry : *symtab) - { - offset_type str_off, vec_off; - -@@ -1151,7 +1200,7 @@ write_cooked_index (cooked_index *table, - const auto it = cu_index_htab.find (entry->per_cu); - gdb_assert (it != cu_index_htab.cend ()); - -- const char *name = entry->full_name (&symtab->m_string_obstack); -+ const char *name = entry->full_name (symtab->obstack ()); - - if (entry->per_cu->lang () == language_ada) - { -@@ -1159,7 +1208,7 @@ write_cooked_index (cooked_index *table, - gdb, it has to use the encoded name, with any - suffixes stripped. */ - std::string encoded = ada_encode (name, false); -- name = obstack_strdup (&symtab->m_string_obstack, -+ name = obstack_strdup (symtab->obstack (), - encoded.c_str ()); - } - else if (entry->per_cu->lang () == language_cplus -@@ -1191,8 +1240,8 @@ write_cooked_index (cooked_index *table, - else - kind = GDB_INDEX_SYMBOL_KIND_TYPE; - -- add_index_entry (symtab, name, (entry->flags & IS_STATIC) != 0, -- kind, it->second); -+ symtab->add_index_entry (name, (entry->flags & IS_STATIC) != 0, -+ kind, it->second); - } - } - -@@ -1267,8 +1316,6 @@ write_gdbindex (dwarf2_per_bfd *per_bfd, cooked_index *table, - symtab.minimize (); - - data_buf symtab_vec, constant_pool; -- if (symtab.n_elements == 0) -- symtab.data.resize (0); - - write_hash_table (&symtab, symtab_vec, constant_pool); - diff --git a/gdb-rhbz-2232086-generate-dwarf-5-index-consistently.patch b/gdb-rhbz-2232086-generate-dwarf-5-index-consistently.patch deleted file mode 100644 index 15365e6..0000000 --- a/gdb-rhbz-2232086-generate-dwarf-5-index-consistently.patch +++ /dev/null @@ -1,101 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Andrew Burgess -Date: Mon, 27 Nov 2023 13:19:39 +0000 -Subject: gdb-rhbz-2232086-generate-dwarf-5-index-consistently.patch - -;; Back-port upstream commit 3644f41dc80 as part of a fix for -;; non-deterministic gdb-index generation (RH BZ 2232086). - -gdb: generate dwarf-5 index identically as worker-thread count changes - -Similar to the previous commit, this commit ensures that the dwarf-5 -index files are generated identically as the number of worker-threads -changes. - -Building the dwarf-5 index makes use of a closed hash table, the -bucket_hash local within debug_names::build(). Entries are added to -bucket_hash from m_name_to_value_set, which, in turn, is populated -by calls to debug_names::insert() in write_debug_names. The insert -calls are ordered based on the entries within the cooked_index, and -the ordering within cooked_index depends on the number of worker -threads that GDB is using. - -My proposal is to sort each chain within the bucket_hash closed hash -table prior to using this to build the dwarf-5 index. - -The buckets within bucket_hash will always have the same ordering (for -a given GDB build with a given executable), and by sorting the chains -within each bucket, we can be sure that GDB will see each entry in a -deterministic order. - -I've extended the index creation test to cover this case. - -Approved-By: Tom Tromey - -diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c ---- a/gdb/dwarf2/index-write.c -+++ b/gdb/dwarf2/index-write.c -@@ -452,6 +452,11 @@ class c_str_view - return strcmp (m_cstr, other.m_cstr) == 0; - } - -+ bool operator< (const c_str_view &other) const -+ { -+ return strcmp (m_cstr, other.m_cstr) < 0; -+ } -+ - /* Return the underlying C string. Note, the returned string is - only a reference with lifetime of this object. */ - const char *c_str () const -@@ -771,10 +776,18 @@ class debug_names - } - for (size_t bucket_ix = 0; bucket_ix < bucket_hash.size (); ++bucket_ix) - { -- const std::forward_list &hashitlist -- = bucket_hash[bucket_ix]; -+ std::forward_list &hashitlist = bucket_hash[bucket_ix]; - if (hashitlist.empty ()) - continue; -+ -+ /* Sort the items within each bucket. This ensures that the -+ generated index files will be the same no matter the order in -+ which symbols were added into the index. */ -+ hashitlist.sort ([] (const hash_it_pair &a, const hash_it_pair &b) -+ { -+ return a.it->first < b.it->first; -+ }); -+ - uint32_t &bucket_slot = m_bucket_table[bucket_ix]; - /* The hashes array is indexed starting at 1. */ - store_unsigned_integer (reinterpret_cast (&bucket_slot), -diff --git a/gdb/testsuite/gdb.gdb/index-file.exp b/gdb/testsuite/gdb.gdb/index-file.exp ---- a/gdb/testsuite/gdb.gdb/index-file.exp -+++ b/gdb/testsuite/gdb.gdb/index-file.exp -@@ -47,6 +47,9 @@ remote_exec host "mkdir -p ${dir1}" - with_timeout_factor $timeout_factor { - gdb_test_no_output "save gdb-index $dir1" \ - "create gdb-index file" -+ -+ gdb_test_no_output "save gdb-index -dwarf-5 $dir1" \ -+ "create dwarf-index files" - } - - # Close GDB. -@@ -143,13 +146,16 @@ if { $worker_threads > 1 } { - with_timeout_factor $timeout_factor { - gdb_test_no_output "save gdb-index $dir2" \ - "create second gdb-index file" -+ -+ gdb_test_no_output "save gdb-index -dwarf-5 $dir2" \ -+ "create second dwarf-index files" - } - - # Close GDB. - gdb_exit - - # Now check that the index files are identical. -- foreach suffix { gdb-index } { -+ foreach suffix { gdb-index debug_names debug_str } { - set result \ - [remote_exec host \ - "cmp -s \"$dir1/${index_filename_base}.${suffix}\" \"$dir2/${index_filename_base}.${suffix}\""] diff --git a/gdb-rhbz-2232086-generate-gdb-index-consistently.patch b/gdb-rhbz-2232086-generate-gdb-index-consistently.patch deleted file mode 100644 index 0d78380..0000000 --- a/gdb-rhbz-2232086-generate-gdb-index-consistently.patch +++ /dev/null @@ -1,230 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Andrew Burgess -Date: Fri, 24 Nov 2023 12:04:36 +0000 -Subject: gdb-rhbz-2232086-generate-gdb-index-consistently.patch - -;; Back-port upstream commit aff250145af as part of a fix for -;; non-deterministic gdb-index generation (RH BZ 2232086). - -gdb: generate gdb-index identically regardless of work thread count - -It was observed that changing the number of worker threads that GDB -uses (maintenance set worker-threads NUM) would have an impact on the -layout of the generated gdb-index. - -The cause seems to be how the CU are distributed between threads, and -then symbols that appear in multiple CU can be encountered earlier or -later depending on whether a particular CU moves between threads. - -I certainly found this behaviour was reproducible when generating an -index for GDB itself, like: - - gdb -q -nx -nh -batch \ - -eiex 'maint set worker-threads NUM' \ - -ex 'save gdb-index /tmp/' - -And then setting different values for NUM will change the generated -index. - -Now, the question is: does this matter? - -I would like to suggest that yes, this does matter. At Red Hat we -generate a gdb-index as part of the build process, and we would -ideally like to have reproducible builds: for the same source, -compiled with the same tool-chain, we should get the exact same output -binary. And we do .... except for the index. - -Now we could simply force GDB to only use a single worker thread when -we build the index, but, I don't think the idea of reproducible builds -is that strange, so I think we should ensure that our generated -indexes are always reproducible. - -To achieve this, I propose that we add an extra step when building the -gdb-index file. After constructing the initial symbol hash table -contents, we will pull all the symbols out of the hash, sort them, -then re-insert them in sorted order. This will ensure that the -structure of the generated hash will remain consistent (given the same -set of symbols). - -I've extended the existing index-file test to check that the generated -index doesn't change if we adjust the number of worker threads used. -Given that this test is already rather slow, I've only made one change -to the worker-thread count. Maybe this test should be changed to use -a smaller binary, which is quicker to load, and for which we could -then try many different worker thread counts. - -Approved-By: Tom Tromey - -diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c ---- a/gdb/dwarf2/index-write.c -+++ b/gdb/dwarf2/index-write.c -@@ -210,6 +210,13 @@ struct mapped_symtab - void add_index_entry (const char *name, int is_static, - gdb_index_symbol_kind kind, offset_type cu_index); - -+ /* When entries are originally added into the data hash the order will -+ vary based on the number of worker threads GDB is configured to use. -+ This function will rebuild the hash such that the final layout will be -+ deterministic regardless of the number of worker threads used. */ -+ -+ void sort (); -+ - /* Access the obstack. */ - struct obstack *obstack () - { return &m_string_obstack; } -@@ -296,6 +303,65 @@ mapped_symtab::hash_expand () - } - } - -+/* See mapped_symtab class declaration. */ -+ -+void mapped_symtab::sort () -+{ -+ /* Move contents out of this->data vector. */ -+ std::vector original_data = std::move (m_data); -+ -+ /* Restore the size of m_data, this will avoid having to expand the hash -+ table (and rehash all elements) when we reinsert after sorting. -+ However, we do reset the element count, this allows for some sanity -+ checking asserts during the reinsert phase. */ -+ gdb_assert (m_data.size () == 0); -+ m_data.resize (original_data.size ()); -+ m_element_count = 0; -+ -+ /* Remove empty entries from ORIGINAL_DATA, this makes sorting quicker. */ -+ auto it = std::remove_if (original_data.begin (), original_data.end (), -+ [] (const symtab_index_entry &entry) -> bool -+ { -+ return entry.name == nullptr; -+ }); -+ original_data.erase (it, original_data.end ()); -+ -+ /* Sort the existing contents. */ -+ std::sort (original_data.begin (), original_data.end (), -+ [] (const symtab_index_entry &a, -+ const symtab_index_entry &b) -> bool -+ { -+ /* Return true if A is before B. */ -+ gdb_assert (a.name != nullptr); -+ gdb_assert (b.name != nullptr); -+ -+ return strcmp (a.name, b.name) < 0; -+ }); -+ -+ /* Re-insert each item from the sorted list. */ -+ for (auto &entry : original_data) -+ { -+ /* We know that ORIGINAL_DATA contains no duplicates, this data was -+ taken from a hash table that de-duplicated entries for us, so -+ count this as a new item. -+ -+ As we retained the original size of m_data (see above) then we -+ should never need to grow m_data_ during this re-insertion phase, -+ assert that now. */ -+ ++m_element_count; -+ gdb_assert (!this->hash_needs_expanding ()); -+ -+ /* Lookup a slot. */ -+ symtab_index_entry &slot = this->find_slot (entry.name); -+ -+ /* As discussed above, we should not find duplicates. */ -+ gdb_assert (slot.name == nullptr); -+ -+ /* Move this item into the slot we found. */ -+ slot = std::move (entry); -+ } -+} -+ - /* See class definition. */ - - void -@@ -1311,6 +1377,9 @@ write_gdbindex (dwarf2_per_bfd *per_bfd, cooked_index *table, - for (auto map : table->get_addrmaps ()) - write_address_map (map, addr_vec, cu_index_htab); - -+ /* Ensure symbol hash is built domestically. */ -+ symtab.sort (); -+ - /* Now that we've processed all symbols we can shrink their cu_indices - lists. */ - symtab.minimize (); -diff --git a/gdb/testsuite/gdb.gdb/index-file.exp b/gdb/testsuite/gdb.gdb/index-file.exp ---- a/gdb/testsuite/gdb.gdb/index-file.exp -+++ b/gdb/testsuite/gdb.gdb/index-file.exp -@@ -38,6 +38,9 @@ with_timeout_factor $timeout_factor { - clean_restart $filename - } - -+# Record how many worker threads GDB is using. -+set worker_threads [gdb_get_worker_threads] -+ - # Generate an index file. - set dir1 [standard_output_file "index_1"] - remote_exec host "mkdir -p ${dir1}" -@@ -116,3 +119,41 @@ proc check_symbol_table_usage { filename } { - - set index_filename_base [file tail $filename] - check_symbol_table_usage "$dir1/${index_filename_base}.gdb-index" -+ -+# If GDB is using more than 1 worker thread then reduce the number of -+# worker threads, regenerate the index, and check that we get the same -+# index file back. At one point the layout of the index would vary -+# based on the number of worker threads used. -+if { $worker_threads > 1 } { -+ # Start GDB, but don't load a file yet. -+ clean_restart -+ -+ # Adjust the number of threads to use. -+ set reduced_threads [expr $worker_threads / 2] -+ gdb_test_no_output "maint set worker-threads $reduced_threads" -+ -+ with_timeout_factor $timeout_factor { -+ # Now load the test binary. -+ gdb_file_cmd $filename -+ } -+ -+ # Generate an index file. -+ set dir2 [standard_output_file "index_2"] -+ remote_exec host "mkdir -p ${dir2}" -+ with_timeout_factor $timeout_factor { -+ gdb_test_no_output "save gdb-index $dir2" \ -+ "create second gdb-index file" -+ } -+ -+ # Close GDB. -+ gdb_exit -+ -+ # Now check that the index files are identical. -+ foreach suffix { gdb-index } { -+ set result \ -+ [remote_exec host \ -+ "cmp -s \"$dir1/${index_filename_base}.${suffix}\" \"$dir2/${index_filename_base}.${suffix}\""] -+ gdb_assert { [lindex $result 0] == 0 } \ -+ "$suffix files are identical" -+ } -+} -diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp ---- a/gdb/testsuite/lib/gdb.exp -+++ b/gdb/testsuite/lib/gdb.exp -@@ -10033,6 +10033,21 @@ proc is_target_non_stop { {testname ""} } { - return $is_non_stop - } - -+# Return the number of worker threads that GDB is currently using. -+ -+proc gdb_get_worker_threads { {testname ""} } { -+ set worker_threads "UNKNOWN" -+ gdb_test_multiple "maintenance show worker-threads" $testname { -+ -wrap -re "The number of worker threads GDB can use is unlimited \\(currently ($::decimal)\\)\\." { -+ set worker_threads $expect_out(1,string) -+ } -+ -wrap -re "The number of worker threads GDB can use is ($::decimal)\\." { -+ set worker_threads $expect_out(1,string) -+ } -+ } -+ return $worker_threads -+} -+ - # Check if the compiler emits epilogue information associated - # with the closing brace or with the last statement line. - # diff --git a/gdb-rhbz-2232086-reduce-size-of-gdb-index.patch b/gdb-rhbz-2232086-reduce-size-of-gdb-index.patch deleted file mode 100644 index 41b495e..0000000 --- a/gdb-rhbz-2232086-reduce-size-of-gdb-index.patch +++ /dev/null @@ -1,222 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Andrew Burgess -Date: Fri, 24 Nov 2023 11:50:35 +0000 -Subject: gdb-rhbz-2232086-reduce-size-of-gdb-index.patch - -;; Back-port upstream commit aa19bc1d259 as part of a fix for -;; non-deterministic gdb-index generation (RH BZ 2232086). - -gdb: reduce size of generated gdb-index file - -I noticed in passing that out algorithm for generating the gdb-index -file is incorrect. When building the hash table in add_index_entry we -count every incoming entry rehash when the number of entries gets too -large. However, some of the incoming entries will be duplicates, -which don't actually result in new items being added to the hash -table. - -As a result, we grow the gdb-index hash table far too often. - -With an unmodified GDB, generating a gdb-index for GDB, I see a file -size of 90M, with a hash usage (in the generated index file) of just -2.6%. - -With a patched GDB, generating a gdb-index for the _same_ GDB binary, -I now see a gdb-index file size of 30M, with a hash usage of 41.9%. - -This is a 67% reduction in gdb-index file size. - -Obviously, not every gdb-index file is going to see such big savings, -however, the larger a program, and the more symbols that are -duplicated between compilation units, the more GDB would over count, -and so, over-grow the index. - -The gdb-index hash table we create has a minimum size of 1024, and -then we grow the hash when it is 75% full, doubling the hash table at -that time. Given this, then we expect that either: - - a. The hash table is size 1024, and less than 75% full, or - b. The hash table is between 37.5% and 75% full. - -I've include a test that checks some of these constraints -- I've not -bothered to check the upper limit, and over full hash table isn't -really a problem here, but if the fill percentage is less than 37.5% -then this indicates that we've done something wrong (obviously, I also -check for the 1024 minimum size). - -Approved-By: Tom Tromey - -diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c ---- a/gdb/dwarf2/index-write.c -+++ b/gdb/dwarf2/index-write.c -@@ -254,20 +254,29 @@ add_index_entry (struct mapped_symtab *symtab, const char *name, - int is_static, gdb_index_symbol_kind kind, - offset_type cu_index) - { -- offset_type cu_index_and_attrs; -+ symtab_index_entry *slot = &find_slot (symtab, name); -+ if (slot->name == NULL) -+ { -+ /* This is a new element in the hash table. */ -+ ++symtab->n_elements; - -- ++symtab->n_elements; -- if (4 * symtab->n_elements / 3 >= symtab->data.size ()) -- hash_expand (symtab); -+ /* We might need to grow the hash table. */ -+ if (4 * symtab->n_elements / 3 >= symtab->data.size ()) -+ { -+ hash_expand (symtab); - -- symtab_index_entry &slot = find_slot (symtab, name); -- if (slot.name == NULL) -- { -- slot.name = name; -+ /* This element will have a different slot in the new table. */ -+ slot = &find_slot (symtab, name); -+ -+ /* But it should still be a new element in the hash table. */ -+ gdb_assert (slot->name == nullptr); -+ } -+ -+ slot->name = name; - /* index_offset is set later. */ - } - -- cu_index_and_attrs = 0; -+ offset_type cu_index_and_attrs = 0; - DW2_GDB_INDEX_CU_SET_VALUE (cu_index_and_attrs, cu_index); - DW2_GDB_INDEX_SYMBOL_STATIC_SET_VALUE (cu_index_and_attrs, is_static); - DW2_GDB_INDEX_SYMBOL_KIND_SET_VALUE (cu_index_and_attrs, kind); -@@ -279,7 +288,7 @@ add_index_entry (struct mapped_symtab *symtab, const char *name, - the last entry pushed), but a symbol could have multiple kinds in one CU. - To keep things simple we don't worry about the duplication here and - sort and uniquify the list after we've processed all symbols. */ -- slot.cu_indices.push_back (cu_index_and_attrs); -+ slot->cu_indices.push_back (cu_index_and_attrs); - } - - /* See symtab_index_entry. */ -diff --git a/gdb/testsuite/gdb.gdb/index-file.exp b/gdb/testsuite/gdb.gdb/index-file.exp -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.gdb/index-file.exp -@@ -0,0 +1,118 @@ -+# Copyright 2023 Free Software Foundation, Inc. -+ -+# 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 . -+ -+# Load the GDB executable, and then 'save gdb-index', and make some -+# checks of the generated index file. -+ -+load_lib selftest-support.exp -+ -+# Can't save an index with readnow. -+if {[readnow]} { -+ untested "cannot create an index when readnow is in use" -+ return -1 -+} -+ -+# A multiplier used to ensure slow tasks are less likely to timeout. -+set timeout_factor 20 -+ -+set filename [selftest_prepare] -+if { $filename eq "" } { -+ unsupported "${gdb_test_file_name}.exp" -+ return -1 -+} -+ -+with_timeout_factor $timeout_factor { -+ # Start GDB, load FILENAME. -+ clean_restart $filename -+} -+ -+# Generate an index file. -+set dir1 [standard_output_file "index_1"] -+remote_exec host "mkdir -p ${dir1}" -+with_timeout_factor $timeout_factor { -+ gdb_test_no_output "save gdb-index $dir1" \ -+ "create gdb-index file" -+} -+ -+# Close GDB. -+gdb_exit -+ -+# Validate that the index-file FILENAME has made efficient use of its -+# symbol hash table. Calculate the number of symbols in the hash -+# table and the total hash table size. The hash table starts with -+# 1024 entries, and then doubles each time it is filled to 75%. At -+# 75% filled, doubling the size takes it to 37.5% filled. -+# -+# Thus, the hash table is correctly filled if: -+# 1. Its size is 1024 (i.e. it has not yet had its first doubling), or -+# 2. Its filled percentage is over 37% -+# -+# We could check that it is not over filled, but I don't as that's not -+# really an issue. But we did once have a bug where the table was -+# doubled incorrectly, in which case we'd see a filled percentage of -+# around 2% in some cases, which is a huge waste of disk space. -+proc check_symbol_table_usage { filename } { -+ # Open the file in binary mode and read-only mode. -+ set fp [open $filename rb] -+ -+ # Configure the channel to use binary translation. -+ fconfigure $fp -translation binary -+ -+ # Read the first 8 bytes of the file, which contain the header of -+ # the index section. -+ set header [read $fp [expr 7 * 4]] -+ -+ # Scan the header to get the version, the CU list offset, and the -+ # types CU list offset. -+ binary scan $header iiiiii version \ -+ _ _ _ symbol_table_offset shortcut_offset -+ -+ # The length of the symbol hash table (in entries). -+ set len [expr ($shortcut_offset - $symbol_table_offset) / 8] -+ -+ # Now walk the hash table and count how many entries are in use. -+ set offset $symbol_table_offset -+ set count 0 -+ while { $offset < $shortcut_offset } { -+ seek $fp $offset -+ set entry [read $fp 8] -+ binary scan $entry ii name_ptr flags -+ if { $name_ptr != 0 } { -+ incr count -+ } -+ -+ incr offset 8 -+ } -+ -+ # Close the file. -+ close $fp -+ -+ # Calculate how full the cache is. -+ set pct [expr (100 * double($count)) / $len] -+ -+ # Write our results out to the gdb.log. -+ verbose -log "Hash table size: $len" -+ verbose -log "Hash table entries: $count" -+ verbose -log "Percentage usage: $pct%" -+ -+ # The minimum fill percentage is actually 37.5%, but we give TCL a -+ # little flexibility in case the FP maths give a result a little -+ # off. -+ gdb_assert { $len == 1024 || $pct > 37 } \ -+ "symbol hash table usage" -+} -+ -+set index_filename_base [file tail $filename] -+check_symbol_table_usage "$dir1/${index_filename_base}.gdb-index" diff --git a/gdb-rhbz1007614-memleak-infpy_read_memory-test.patch b/gdb-rhbz1007614-memleak-infpy_read_memory-test.patch deleted file mode 100644 index 6eecc8f..0000000 --- a/gdb-rhbz1007614-memleak-infpy_read_memory-test.patch +++ /dev/null @@ -1,170 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Fedora GDB patches -Date: Fri, 27 Oct 2017 21:07:50 +0200 -Subject: gdb-rhbz1007614-memleak-infpy_read_memory-test.patch - -;; Fix 'memory leak in infpy_read_memory()' (RH BZ 1007614) -;;=fedoratest - -Original message by Tom Tromey: - - - Message-ID: <871uoc1va3.fsf@fleche.redhat.com> - -Comment from Sergio Durigan Junior: - - In order to correctly test this patch, I wrote a testcase based on Jan - Kratochvil's . The - testcase, which can be seen below, tests GDB in order to see if the - amount of memory being leaked is minimal, as requested in the bugzilla. - It is hard to define what "minimum" is, so I ran the testcase on all - supported RHEL architectures and came up with an average. - -commit cc0265cdda9dc7e8665e8bfcf5b4477489daf27c -Author: Tom Tromey -Date: Wed Mar 28 17:38:08 2012 +0000 - - * python/py-inferior.c (infpy_read_memory): Remove cleanups and - explicitly free 'buffer' on exit paths. Decref 'membuf_object' - before returning. - -diff --git a/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.c b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.c -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.c -@@ -0,0 +1,27 @@ -+/* This testcase is part of GDB, the GNU debugger. -+ -+ Copyright 2014 Free Software Foundation, Inc. -+ -+ 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 . */ -+ -+static struct x -+ { -+ char unsigned u[4096]; -+ } x, *px = &x; -+ -+int -+main (int argc, char *argv[]) -+{ -+ return 0; -+} -diff --git a/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.exp b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.exp -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.exp -@@ -0,0 +1,68 @@ -+# Copyright 2014 Free Software Foundation, Inc. -+ -+# 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 . -+ -+set testfile py-gdb-rhbz1007614-memleak-infpy_read_memory -+set srcfile ${testfile}.c -+set binfile [standard_output_file ${testfile}] -+ -+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } { -+ return -1 -+} -+ -+if { [skip_python_tests] } { continue } -+ -+set pid_of_gdb [exp_pid -i [board_info host fileid]] -+ -+proc memory_v_pages_get {} { -+ global pid_of_gdb -+ set fd [open "/proc/$pid_of_gdb/statm"] -+ gets $fd line -+ close $fd -+ # number of pages of virtual memory -+ scan $line "%d" drs -+ return $drs -+} -+ -+if { ![runto_main] } { -+ untested $testfile.exp -+ return -1 -+} -+ -+set remote_python_file [remote_download host ${srcdir}/${subdir}/${testfile}.py] -+ -+gdb_test "source ${remote_python_file}" "" -+ -+gdb_test "hello-world" "" -+ -+set kbytes_before [memory_v_pages_get] -+verbose -log "kbytes_before = $kbytes_before" -+ -+gdb_test "hello-world" "" -+ -+set kbytes_after [memory_v_pages_get] -+verbose -log "kbytes_after = $kbytes_after" -+ -+set kbytes_diff [expr $kbytes_after - $kbytes_before] -+verbose -log "kbytes_diff = $kbytes_diff" -+ -+# The value "1000" was calculated by running a few GDB sessions with this -+# testcase, and seeing how much (in average) the memory consumption -+# increased after the "hello-world" command issued above. The average -+# was around 500 bytes, so I chose 1000 as a high estimate. -+if { $kbytes_diff > 1000 } { -+ fail "there is a memory leak on GDB (RHBZ 1007614)" -+} else { -+ pass "there is not a memory leak on GDB (RHBZ 1007614)" -+} -diff --git a/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.py b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.py -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.py -@@ -0,0 +1,30 @@ -+# Copyright (C) 2014 Free Software Foundation, Inc. -+ -+# 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 . -+ -+class HelloWorld (gdb.Command): -+ """Greet the whole world.""" -+ -+ def __init__ (self): -+ super (HelloWorld, self).__init__ ("hello-world", -+ gdb.COMMAND_OBSCURE) -+ -+ def invoke (self, arg, from_tty): -+ px = gdb.parse_and_eval("px") -+ core = gdb.inferiors()[0] -+ for i in range(256 * 1024): -+ chunk = core.read_memory(px, 4096) -+ print "Hello, World!" -+ -+HelloWorld () diff --git a/gdb-rhbz1261564-aarch64-hw-watchpoint-test.patch b/gdb-rhbz1261564-aarch64-hw-watchpoint-test.patch deleted file mode 100644 index 3a5e2d4..0000000 --- a/gdb-rhbz1261564-aarch64-hw-watchpoint-test.patch +++ /dev/null @@ -1,104 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Fedora GDB patches -Date: Fri, 27 Oct 2017 21:07:50 +0200 -Subject: gdb-rhbz1261564-aarch64-hw-watchpoint-test.patch - -;; [aarch64] Fix hardware watchpoints (RH BZ 1261564). -;;=fedoratest - -diff --git a/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.c b/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.c -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.c -@@ -0,0 +1,33 @@ -+/* This testcase is part of GDB, the GNU debugger. -+ -+ Copyright 2016 Free Software Foundation, Inc. -+ -+ 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 . */ -+ -+__attribute__((aligned(16))) struct -+{ -+ int var0, var4, var8; -+} aligned; -+ -+int -+main (void) -+{ -+ aligned.var0 = 1; -+ aligned.var4 = 2; -+ aligned.var8 = 3; -+ -+ aligned.var4 = aligned.var0; -+ -+ return 0; -+} -diff --git a/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.exp b/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.exp -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.exp -@@ -0,0 +1,53 @@ -+# Copyright (C) 2016 Free Software Foundation, Inc. -+ -+# 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 . -+ -+if { [prepare_for_testing rhbz1261564-aarch64-watchpoint.exp "rhbz1261564-aarch64-watchpoint"] } { -+ return -1 -+} -+ -+if { ! [ runto main ] } then { return 0 } -+ -+set test "rwatch aligned.var4" -+if [istarget "s390*-*-*"] { -+ gdb_test $test {Target does not support this type of hardware watchpoint\.} -+ untested "s390* does not support hw read watchpoint" -+ return -+} -+gdb_test $test "Hardware read watchpoint \[0-9\]+: aligned.var4" -+ -+proc checkvar { address } { -+ global gdb_prompt -+ -+ set test "p &aligned.var$address" -+ gdb_test_multiple $test $test { -+ -re " = \\(int \\*\\) 0x\[0-9a-f\]+$address \r\n$gdb_prompt $" { -+ pass $test -+ } -+ -re "\r\n$gdb_prompt $" { -+ untested "$test (unexpected ELF layout)" -+ return 0 -+ } -+ } -+ return 1 -+} -+if ![checkvar "0"] { return } -+if ![checkvar "4"] { return } -+if ![checkvar "8"] { return } -+ -+# Assumes: PPC_PTRACE_GETHWDBGINFO::data_bp_alignment == 8 -+# 'lwz' does read only 4 bytes but the hw watchpoint is 8 bytes wide. -+setup_xfail "powerpc*-*-*" -+ -+gdb_continue_to_end diff --git a/gdb-rhbz2232086-refactor-selftest-support.patch b/gdb-rhbz2232086-refactor-selftest-support.patch deleted file mode 100644 index c19ef46..0000000 --- a/gdb-rhbz2232086-refactor-selftest-support.patch +++ /dev/null @@ -1,77 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Andrew Burgess -Date: Fri, 24 Nov 2023 11:10:08 +0000 -Subject: gdb-rhbz2232086-refactor-selftest-support.patch - -;; Back-port upstream commit 1f0fab7ff86 as part of a fix for -;; non-deterministic gdb-index generation (RH BZ 2232086). - -gdb/testsuite: small refactor in selftest-support.exp - -Split out the code that makes a copy of the GDB executable ready for -self testing into a new proc. A later commit in this series wants to -load the GDB executable into GDB (for creating an on-disk debug -index), but doesn't need to make use of the full do_self_tests proc. - -There should be no changes in what is tested after this commit. - -Approved-By: Tom Tromey - -diff --git a/gdb/testsuite/lib/selftest-support.exp b/gdb/testsuite/lib/selftest-support.exp ---- a/gdb/testsuite/lib/selftest-support.exp -+++ b/gdb/testsuite/lib/selftest-support.exp -@@ -92,11 +92,13 @@ proc selftest_setup { executable function } { - return 0 - } - --# A simple way to run some self-tests. -- --proc do_self_tests {function body} { -- global GDB tool -- -+# Prepare for running a self-test by moving the GDB executable to a -+# location where we can use it as the inferior. Return the filename -+# of the new location. -+# -+# If the current testing setup is not suitable for running a -+# self-test, then return an empty string. -+proc selftest_prepare {} { - # Are we testing with a remote board? In that case, the target - # won't have access to the GDB's auxilliary data files - # (data-directory, etc.). It's simpler to just skip. -@@ -120,19 +122,31 @@ proc do_self_tests {function body} { - # Run the test with self. Copy the file executable file in case - # this OS doesn't like to edit its own text space. - -- set GDB_FULLPATH [find_gdb $GDB] -+ set gdb_fullpath [find_gdb $::GDB] - - if {[is_remote host]} { -- set xgdb x$tool -+ set xgdb x$::tool - } else { -- set xgdb [standard_output_file x$tool] -+ set xgdb [standard_output_file x$::tool] - } - - # Remove any old copy lying around. - remote_file host delete $xgdb - -+ set filename [remote_download host $gdb_fullpath $xgdb] -+ -+ return $filename -+} -+ -+# A simple way to run some self-tests. -+ -+proc do_self_tests {function body} { -+ set file [selftest_prepare] -+ if { $file eq "" } { -+ return -+ } -+ - gdb_start -- set file [remote_download host $GDB_FULLPATH $xgdb] - - # When debugging GDB with GDB, some operations can take a relatively long - # time, especially if the build is non-optimized. Bump the timeout for the diff --git a/gdb-rhbz2250652-avoid-PyOS_ReadlineTState.patch b/gdb-rhbz2250652-avoid-PyOS_ReadlineTState.patch deleted file mode 100644 index 1aa07a6..0000000 --- a/gdb-rhbz2250652-avoid-PyOS_ReadlineTState.patch +++ /dev/null @@ -1,48 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= -Date: Mon, 8 Jan 2024 13:24:05 +0100 -Subject: gdb-rhbz2250652-avoid-PyOS_ReadlineTState.patch - -gdb/python: avoid use of _PyOS_ReadlineTState - -In python/py-gdb-readline.c we make use of _PyOS_ReadlineTState, -however, this variable is no longer public in Python 3.13, and so GDB -no longer builds. - -We are making use of _PyOS_ReadlineTState in order to re-acquire the -Python Global Interpreter Lock (GIL). The _PyOS_ReadlineTState -variable is set in Python's outer readline code prior to calling the -user (GDB) supplied readline callback function, which for us is -gdbpy_readline_wrapper. The gdbpy_readline_wrapper function is called -without the GIL held. - -Instead of using _PyOS_ReadlineTState, I propose that we switch to -calling PyGILState_Ensure() and PyGILState_Release(). These functions -will acquire the GIL based on the current thread. I think this should -be sufficient; I can't imagine why we'd be running -gdbpy_readline_wrapper on one thread on behalf of a different Python -thread.... that would be unexpected I think. - -Approved-By: Tom Tromey - -diff --git a/gdb/python/py-gdb-readline.c b/gdb/python/py-gdb-readline.c ---- a/gdb/python/py-gdb-readline.c -+++ b/gdb/python/py-gdb-readline.c -@@ -56,13 +56,11 @@ gdbpy_readline_wrapper (FILE *sys_stdin, FILE *sys_stdout, - if (except.reason == RETURN_QUIT) - return NULL; - -- /* The thread state is nulled during gdbpy_readline_wrapper, -- with the original value saved in the following undocumented -- variable (see Python's Parser/myreadline.c and -- Modules/readline.c). */ -- PyEval_RestoreThread (_PyOS_ReadlineTState); -+ -+ /* This readline callback is called without the GIL held. */ -+ gdbpy_gil gil; -+ - gdbpy_convert_exception (except); -- PyEval_SaveThread (); - return NULL; - } - diff --git a/gdb-rhbz2250652-gdbpy_gil.patch b/gdb-rhbz2250652-gdbpy_gil.patch deleted file mode 100644 index c51d512..0000000 --- a/gdb-rhbz2250652-gdbpy_gil.patch +++ /dev/null @@ -1,81 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= -Date: Mon, 8 Jan 2024 13:12:15 +0100 -Subject: gdb-rhbz2250652-gdbpy_gil.patch - -gdb: move gdbpy_gil into python-internal.h - -Move gdbpy_gil class into python-internal.h, the next -commit wants to make use of this class from a file other -than python.c. - -Approved-By: Tom Tromey - -diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h ---- a/gdb/python/python-internal.h -+++ b/gdb/python/python-internal.h -@@ -754,6 +754,30 @@ class gdbpy_allow_threads - PyThreadState *m_save; - }; - -+/* A helper class to save and restore the GIL, but without touching -+ the other globals that are handled by gdbpy_enter. */ -+ -+class gdbpy_gil -+{ -+public: -+ -+ gdbpy_gil () -+ : m_state (PyGILState_Ensure ()) -+ { -+ } -+ -+ ~gdbpy_gil () -+ { -+ PyGILState_Release (m_state); -+ } -+ -+ DISABLE_COPY_AND_ASSIGN (gdbpy_gil); -+ -+private: -+ -+ PyGILState_STATE m_state; -+}; -+ - /* Use this after a TRY_EXCEPT to throw the appropriate Python - exception. */ - #define GDB_PY_HANDLE_EXCEPTION(Exception) \ -diff --git a/gdb/python/python.c b/gdb/python/python.c ---- a/gdb/python/python.c -+++ b/gdb/python/python.c -@@ -257,30 +257,6 @@ gdbpy_enter::finalize () - python_gdbarch = target_gdbarch (); - } - --/* A helper class to save and restore the GIL, but without touching -- the other globals that are handled by gdbpy_enter. */ -- --class gdbpy_gil --{ --public: -- -- gdbpy_gil () -- : m_state (PyGILState_Ensure ()) -- { -- } -- -- ~gdbpy_gil () -- { -- PyGILState_Release (m_state); -- } -- -- DISABLE_COPY_AND_ASSIGN (gdbpy_gil); -- --private: -- -- PyGILState_STATE m_state; --}; -- - /* Set the quit flag. */ - - static void diff --git a/gdb-rhbz2261580-intrusive_list-assertion-fix.patch b/gdb-rhbz2261580-intrusive_list-assertion-fix.patch deleted file mode 100644 index 8ec30bc..0000000 --- a/gdb-rhbz2261580-intrusive_list-assertion-fix.patch +++ /dev/null @@ -1,55 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Kevin Buettner -Date: Mon, 29 Jan 2024 14:51:22 -0700 -Subject: gdb-rhbz2261580-intrusive_list-assertion-fix.patch - -;; Backport upstream workaround for GCC 14 problem which cause assertion -;; failures in GDB. - -[gdb/build] Workaround gcc PR113599 - -Since gcc commit d3f48f68227 ("c++: non-dependent .* operand folding -[PR112427]"), with gdb we run into PR gcc/113599 [1], a wrong-code bug, as -reported in PR build/31281. - -Work around this by flipping inherit order: -... --class thread_info : public refcounted_object, -- public intrusive_list_node -+class thread_info : public intrusive_list_node, -+ public refcounted_object -... - -An argument could be made that this isn't necessary, because this occurred in -an unreleased gcc version. - -However, I think it could be useful when bisecting gcc for other problems in -building gdb. Having this workaround means the bisect won't reintroduce the -problem. Furthermore, the workaround is harmless. - -Tested on Fedora rawhide x86_64. - -Approved-By: Tom Tromey - -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31281 - -[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113599 - -diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h ---- a/gdb/gdbthread.h -+++ b/gdb/gdbthread.h -@@ -242,10 +242,11 @@ using private_thread_info_up = std::unique_ptr; - strong reference, and is thus not accounted for in the thread's - refcount. - -- The intrusive_list_node base links threads in a per-inferior list. */ -+ The intrusive_list_node base links threads in a per-inferior list. -+ We place it first in the inherit order to work around PR gcc/113599. */ - --class thread_info : public refcounted_object, -- public intrusive_list_node -+class thread_info : public intrusive_list_node, -+ public refcounted_object - { - public: - explicit thread_info (inferior *inf, ptid_t ptid); diff --git a/gdb-rhbz947564-findvar-assertion-frame-failed-testcase.patch b/gdb-rhbz947564-findvar-assertion-frame-failed-testcase.patch deleted file mode 100644 index c4b1a01..0000000 --- a/gdb-rhbz947564-findvar-assertion-frame-failed-testcase.patch +++ /dev/null @@ -1,147 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Fedora GDB patches -Date: Fri, 27 Oct 2017 21:07:50 +0200 -Subject: gdb-rhbz947564-findvar-assertion-frame-failed-testcase.patch - -;; Import regression test for `gdb/findvar.c:417: internal-error: -;; read_var_value: Assertion `frame' failed.' (RH BZ 947564) from RHEL 6.5. -;;=fedoratest - -diff --git a/gdb/testsuite/gdb.threads/tls-rhbz947564.cc b/gdb/testsuite/gdb.threads/tls-rhbz947564.cc -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.threads/tls-rhbz947564.cc -@@ -0,0 +1,53 @@ -+#include -+#include -+ -+class x -+ { -+ public: -+ int n; -+ -+ x() : n(0) {} -+ }; -+ -+class y -+ { -+ public: -+ int v; -+ -+ y() : v(0) {} -+ static __thread x *xp; -+ }; -+ -+__thread x *y::xp; -+ -+static void -+foo (y *yp) -+{ -+ yp->v = 1; /* foo_marker */ -+} -+ -+static void * -+bar (void *unused) -+{ -+ x xinst; -+ y::xp= &xinst; -+ -+ y yy; -+ foo(&yy); -+ -+ return NULL; -+} -+ -+int -+main(int argc, char *argv[]) -+{ -+ pthread_t t[2]; -+ -+ pthread_create (&t[0], NULL, bar, NULL); -+ pthread_create (&t[1], NULL, bar, NULL); -+ -+ pthread_join (t[0], NULL); -+ pthread_join (t[1], NULL); -+ -+ return 0; -+} -diff --git a/gdb/testsuite/gdb.threads/tls-rhbz947564.exp b/gdb/testsuite/gdb.threads/tls-rhbz947564.exp -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.threads/tls-rhbz947564.exp -@@ -0,0 +1,75 @@ -+# Copyright (C) 2013 Free Software Foundation, Inc. -+ -+# 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 . */ -+ -+set testfile tls-rhbz947564 -+set srcfile ${testfile}.cc -+set binfile [standard_output_file ${testfile}] -+ -+if [istarget "*-*-linux"] then { -+ set target_cflags "-D_MIT_POSIX_THREADS" -+} else { -+ set target_cflags "" -+} -+ -+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list c++ debug]] != "" } { -+ return -1 -+} -+ -+gdb_exit -+gdb_start -+gdb_reinitialize_dir $srcdir/$subdir -+ -+gdb_load ${binfile} -+ -+if { ![runto_main] } { -+ fail "Can't run to function main" -+ return 0 -+} -+ -+gdb_breakpoint "foo" -+gdb_continue_to_breakpoint "foo" ".* foo_marker .*" -+ -+proc get_xp_val {try} { -+ global expect_out -+ global gdb_prompt -+ global hex -+ -+ set xp_val "" -+ gdb_test_multiple "print *yp" "print yp value" { -+ -re { = \{v = 0, static xp = (0x[0-9a-f]+)\}.* } { -+ pass "print $try value of *yp" -+ set xp_val $expect_out(1,string) -+ } -+ -re "$gdb_prompt $" { -+ fail "print $try value of *yp" -+ } -+ timeout { -+ fail "print $try value of *yp (timeout)" -+ } -+ } -+ return $xp_val -+} -+ -+set first_run [get_xp_val "first"] -+ -+gdb_test "continue" "Breakpoint \[0-9\]+, foo \\\(yp=$hex\\\) at.*" -+ -+set second_run [get_xp_val "second"] -+ -+if { $first_run != $second_run } { -+ pass "different values for TLS variable" -+} else { -+ fail "different values for TLS variable" -+} diff --git a/gdb-s390-add-arch14-record-replay-support.patch b/gdb-s390-add-arch14-record-replay-support.patch deleted file mode 100644 index 185e315..0000000 --- a/gdb-s390-add-arch14-record-replay-support.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 6cfb7bf81be3ab6f131dbc6a27eefca516cf7517 Mon Sep 17 00:00:00 2001 -From: Andreas Arnez -Date: Tue, 13 Feb 2024 18:55:29 +0100 -Subject: [PATCH 2/2] gdb: s390: Add arch14 record/replay support - -Enable recording of the new "arch14" instructions on z/Architecture -targets, except for the specialized-function-assist instruction NNPA. ---- - gdb/s390-tdep.c | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c -index 54b5c89e5e3..dcac407caef 100644 ---- a/gdb/s390-tdep.c -+++ b/gdb/s390-tdep.c -@@ -5534,6 +5534,14 @@ s390_process_record (struct gdbarch *gdbarch, struct regcache *regcache, - case 0xe635: /* VLRL - vector load rightmost with immed. length */ - case 0xe637: /* VLRLR - vector load rightmost with length */ - case 0xe649: /* VLIP - vector load immediate decimal */ -+ case 0xe656: /* VCLFNH - vector fp convert and lengthen from NNP high */ -+ case 0xe65e: /* VCLFNL - vector fp convert and lengthen from NNP low */ -+ case 0xe655: /* VCNF - vector fp convert to NNP */ -+ case 0xe65d: /* VCFN - vector fp convert from NNP */ -+ case 0xe674: /* VSCHP - decimal scale and convert to HFP */ -+ case 0xe675: /* VCRNF - vector fp convert and round to NNP */ -+ case 0xe67c: /* VSCSHP - decimal scale and convert and split to HFP */ -+ case 0xe67d: /* VCSPH - vector convert HFP to scaled decimal */ - case 0xe700: /* VLEB - vector load element */ - case 0xe701: /* VLEH - vector load element */ - case 0xe702: /* VLEG - vector load element */ -@@ -5791,11 +5799,16 @@ s390_process_record (struct gdbarch *gdbarch, struct regcache *regcache, - - /* 0xe747-0xe749 undefined */ - -+ case 0xe651: /* VCLZDP - vector count leading zero digits */ -+ case 0xe654: /* VUPKZH - vector unpack zoned high */ - case 0xe658: /* VCVD - vector convert to decimal 32 bit */ - case 0xe659: /* VSRP - vector shift and round decimal */ - case 0xe65a: /* VCVDG - vector convert to decimal 64 bit*/ - case 0xe65b: /* VPSOP - vector perform sign operation decimal */ -+ case 0xe65c: /* VUPKZL - vector unpack zoned low */ -+ case 0xe670: /* VPKZR - vector pack zoned register */ - case 0xe671: /* VAP - vector add decimal */ -+ case 0xe672: /* VSRPR - vector shift and round decimal register */ - case 0xe673: /* VSP - vector subtract decimal */ - case 0xe678: /* VMP - vector multiply decimal */ - case 0xe679: /* VMSP - vector multiply decimal */ --- -2.35.3 - diff --git a/gdb-simultaneous-step-resume-breakpoint-test.patch b/gdb-simultaneous-step-resume-breakpoint-test.patch deleted file mode 100644 index ad4a1f2..0000000 --- a/gdb-simultaneous-step-resume-breakpoint-test.patch +++ /dev/null @@ -1,162 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Fedora GDB patches -Date: Fri, 27 Oct 2017 21:07:50 +0200 -Subject: gdb-simultaneous-step-resume-breakpoint-test.patch - -;; New test for step-resume breakpoint placed in multiple threads at once. -;;=fedoratest - -diff --git a/gdb/testsuite/gdb.threads/simultaneous-step-resume-breakpoint.c b/gdb/testsuite/gdb.threads/simultaneous-step-resume-breakpoint.c -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.threads/simultaneous-step-resume-breakpoint.c -@@ -0,0 +1,79 @@ -+/* Copyright 2009 Free Software Foundation, Inc. -+ -+ Written by Fred Fish of Cygnus Support -+ Contributed by Cygnus Support -+ -+ 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 . */ -+ -+/* Test multiple threads stepping into a .debug_line-less function with -+ a breakpoint placed on its return-to-caller point. */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define THREADS 3 -+ -+static void * -+func (void *unused) -+{ -+ int i; -+ -+ errno = 0; -+ i = 0xdeadf00d; -+ i = sleep (THREADS); /* sleep-call */ -+ if (errno != 0) /* sleep-after */ -+ perror ("sleep"); -+ -+ /* The GDB bug with forgotten step-resume breakpoint could leave stale -+ breakpoint on the I assignment making it a nop. */ -+ if (i == 0xdeadf00d) -+ assert (0); -+ -+ assert (i == 0); -+ -+ pthread_exit (NULL); -+} -+ -+int -+main (void) -+{ -+ pthread_t threads[THREADS]; -+ int threadi; -+ -+ for (threadi = 0; threadi < THREADS; threadi++) -+ { -+ int i; -+ -+ i = pthread_create (&threads[threadi], NULL, func, NULL); -+ assert (i == 0); -+ -+ i = sleep (1); -+ assert (i == 0); -+ } -+ -+ for (threadi = 0; threadi < THREADS; threadi++) -+ { -+ int i; -+ -+ i = pthread_join (threads[threadi], NULL); -+ assert (i == 0); -+ } -+ -+ return 0; /* final-exit */ -+} -diff --git a/gdb/testsuite/gdb.threads/simultaneous-step-resume-breakpoint.exp b/gdb/testsuite/gdb.threads/simultaneous-step-resume-breakpoint.exp -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.threads/simultaneous-step-resume-breakpoint.exp -@@ -0,0 +1,65 @@ -+# Copyright (C) 2009 Free Software Foundation, Inc. -+ -+# 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 . */ -+ -+# Test multiple threads stepping into a .debug_line-less function with -+# a breakpoint placed on its return-to-caller point. -+ -+set testfile simultaneous-step-resume-breakpoint -+set srcfile ${testfile}.c -+set binfile [standard_output_file ${testfile}] -+ -+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { -+ return -1 -+} -+ -+gdb_exit -+gdb_start -+gdb_reinitialize_dir $srcdir/$subdir -+ -+# Ensure we have no debuginfo for the `sleep' call itself (=for libc). -+gdb_test "set debug-file-directory /DoesNotExist" -+ -+gdb_load ${binfile} -+if ![runto_main] { -+ return -1 -+} -+ -+# Red Hat vendor patch does set it to "step" by default. -+gdb_test "set scheduler-locking off" -+ -+gdb_breakpoint [gdb_get_line_number "final-exit"] -+ -+gdb_breakpoint [gdb_get_line_number "sleep-call"] -+gdb_continue_to_breakpoint "sleep-call" -+ -+gdb_test "step" "sleep-call.*" "step thread 1" -+gdb_test "step" "sleep-call.*" "step thread 2" -+gdb_test "step" "sleep-after.*" "step thread 3" -+ -+set test "first continue" -+gdb_test_multiple "continue" $test { -+ -re "final-exit.*$gdb_prompt $" { -+ # gdb-7.0. -+ pass $test -+ return -+ } -+ -re "sleep-after.*$gdb_prompt $" { -+ # Fedora/RHEL branch. -+ pass $test -+ } -+} -+ -+gdb_test "continue" "sleep-after.*" "second continue" -+gdb_test "continue" "final-exit.*" "third continue" diff --git a/gdb-symtab-add-producer_is_gas.patch b/gdb-symtab-add-producer_is_gas.patch deleted file mode 100644 index 3ede8a8..0000000 --- a/gdb-symtab-add-producer_is_gas.patch +++ /dev/null @@ -1,125 +0,0 @@ -From aa8ba17b9a3fdfeeb65df4c3e0731a0e9e96cbf7 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Wed, 1 Nov 2023 00:33:12 +0100 -Subject: [PATCH 1/2] [gdb/symtab] Add producer_is_gas - -Add producer_is_gas, a generic way to get the gas version from the -producer string. - -Tested on x86_64-linux. ---- - gdb/dwarf2/read.c | 4 ++-- - gdb/producer.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++ - gdb/producer.h | 5 +++++ - 3 files changed, 63 insertions(+), 2 deletions(-) - -diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c -index 970dd54c7a5..472684a5817 100644 ---- a/gdb/dwarf2/read.c -+++ b/gdb/dwarf2/read.c -@@ -13376,8 +13376,8 @@ check_producer (struct dwarf2_cu *cu) - cu->producer_is_codewarrior = true; - else if (producer_is_clang (cu->producer, &major, &minor)) - cu->producer_is_clang = true; -- else if (startswith (cu->producer, "GNU AS 2.39.0")) -- cu->producer_is_gas_2_39 = true; -+ else if (producer_is_gas (cu->producer, &major, &minor)) -+ cu->producer_is_gas_2_39 = major == 2 && minor == 39; - else - { - /* For other non-GCC compilers, expect their behavior is DWARF version -diff --git a/gdb/producer.c b/gdb/producer.c -index 9fcf749e3d4..cd83dfce128 100644 ---- a/gdb/producer.c -+++ b/gdb/producer.c -@@ -81,6 +81,45 @@ producer_is_gcc (const char *producer, int *major, int *minor) - - /* See producer.h. */ - -+bool -+producer_is_gas (const char *producer, int *major, int *minor) -+{ -+ if (producer == nullptr) -+ { -+ /* No producer, don't know. */ -+ return false; -+ } -+ -+ /* Detect prefix. */ -+ const char prefix[] = "GNU AS "; -+ if (!startswith (producer, prefix)) -+ { -+ /* Producer is not gas. */ -+ return false; -+ } -+ -+ /* Skip prefix. */ -+ const char *cs = &producer[strlen (prefix)]; -+ -+ /* Ensure that major/minor are not nullptrs. */ -+ int maj, min; -+ if (major == nullptr) -+ major = &maj; -+ if (minor == nullptr) -+ minor = &min; -+ -+ int scanned = sscanf (cs, "%d.%d", major, minor); -+ if (scanned != 2) -+ { -+ /* Unable to scan major/minor version. */ -+ return false; -+ } -+ -+ return true; -+} -+ -+ /* See producer.h. */ -+ - bool - producer_is_icc_ge_19 (const char *producer) - { -@@ -251,6 +290,23 @@ Version 18.0 Beta"; - SELF_CHECK (!producer_is_gcc (flang_llvm_exp, &major, &minor)); - SELF_CHECK (producer_is_llvm (flang_llvm_exp)); - } -+ -+ { -+ static const char gas_exp[] = "GNU AS 2.39.0"; -+ int major = 0, minor = 0; -+ SELF_CHECK (!producer_is_gcc (gas_exp, &major, &minor)); -+ SELF_CHECK (producer_is_gas (gas_exp, &major, &minor)); -+ SELF_CHECK (major == 2 && minor == 39); -+ -+ static const char gas_incomplete_exp[] = "GNU AS "; -+ SELF_CHECK (!producer_is_gas (gas_incomplete_exp, &major, &minor)); -+ SELF_CHECK (!producer_is_gcc (gas_incomplete_exp, &major, &minor)); -+ -+ static const char gas_incomplete_exp_2[] = "GNU AS 2"; -+ SELF_CHECK (!producer_is_gas (gas_incomplete_exp_2, &major, &minor)); -+ SELF_CHECK (!producer_is_gcc (gas_incomplete_exp_2, &major, &minor)); -+ } -+ - } - } - } -diff --git a/gdb/producer.h b/gdb/producer.h -index c915979b122..00718511775 100644 ---- a/gdb/producer.h -+++ b/gdb/producer.h -@@ -30,6 +30,11 @@ extern int producer_is_gcc_ge_4 (const char *producer); - is NULL or it isn't GCC. */ - extern int producer_is_gcc (const char *producer, int *major, int *minor); - -+/* Returns nonzero if the given PRODUCER string is GAS and sets the MAJOR -+ and MINOR versions when not NULL. Returns zero if the given PRODUCER -+ is NULL or it isn't GAS. */ -+bool producer_is_gas (const char *producer, int *major, int *minor); -+ - /* Check for Intel compilers >= 19.0. */ - extern bool producer_is_icc_ge_19 (const char *producer); - - -base-commit: 39553c1e285c426946188ec2a890c1c1cb933060 --- -2.35.3 - diff --git a/gdb-symtab-don-t-defer-backward-refs-inter-cu-intra-.patch b/gdb-symtab-don-t-defer-backward-refs-inter-cu-intra-.patch deleted file mode 100644 index 5bf0f52..0000000 --- a/gdb-symtab-don-t-defer-backward-refs-inter-cu-intra-.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 0218e033b415df76be0a14871447bbd94dce62a3 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Sat, 16 Sep 2023 04:07:22 +0200 -Subject: [PATCH 10/13] [gdb/symtab] Don't defer backward refs, inter-cu - intra-shard case - -In patch "[gdb/symtab] Resolve deferred entries, inter-shard case" we've -solved the generic case of handling deferred entries. - -Add an optimization that doesn't defer inter-CU intra-shard dependencies that -are present in the shard's parent map. - -Tested on x86_64-linux. ---- - gdb/dwarf2/read.c | 29 ++++++++++++++++++++++++++++- - 1 file changed, 28 insertions(+), 1 deletion(-) - -diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c -index a97f738a54e..e7904532434 100644 ---- a/gdb/dwarf2/read.c -+++ b/gdb/dwarf2/read.c -@@ -4709,6 +4709,12 @@ class cooked_index_storage - m_index->set_parent_valid (start, end); - } - -+ /* Return true if find_parents can be relied upon. */ -+ bool parent_valid (CORE_ADDR addr) -+ { -+ return m_index->parent_valid (addr); -+ } -+ - private: - - /* Hash function for a cutu_reader. */ -@@ -4857,6 +4863,12 @@ class cooked_indexer - { - m_index_storage->set_parent_valid (start, end); - } -+ -+ /* Return true if find_parents can be relied upon. */ -+ bool parent_valid (CORE_ADDR addr) -+ { -+ return m_index_storage->parent_valid (addr); -+ } - }; - - /* Subroutine of dwarf2_build_psymtabs_hard to simplify it. -@@ -16482,7 +16494,22 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu, - else - { - /* Inter-CU case. */ -- *maybe_defer = addr; -+ if (parent_valid (addr)) -+ { -+ auto tmp = find_parent (addr); -+ if (tmp == &parent_map::deferred) -+ { -+ /* Defer because origin is deferred. */ -+ *maybe_defer = addr; -+ } -+ else -+ *parent_entry = tmp; -+ } -+ else -+ { -+ /* Defer because origin is in other shard. */ -+ *maybe_defer = addr; -+ } - } - } - --- -2.35.3 - diff --git a/gdb-symtab-factor-out-m_deferred_entries-usage.patch b/gdb-symtab-factor-out-m_deferred_entries-usage.patch deleted file mode 100644 index a3dfe4f..0000000 --- a/gdb-symtab-factor-out-m_deferred_entries-usage.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 8a444a93d4bd78355fc4e6ecb1935cc2b0a6a997 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Fri, 15 Sep 2023 08:38:00 +0200 -Subject: [PATCH 04/13] [gdb/symtab] Factor out m_deferred_entries usage - -Factor out usage of cooked_indexer::m_deferred_entries in new member -functions defer_entry, handle_deferred_entries and resolve_deferred_entry. - -Tested on x86_64-linux. ---- - gdb/dwarf2/read.c | 35 ++++++++++++++++++++++++++++------- - 1 file changed, 28 insertions(+), 7 deletions(-) - -diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c -index d48f3010063..afdf9e870a8 100644 ---- a/gdb/dwarf2/read.c -+++ b/gdb/dwarf2/read.c -@@ -4822,6 +4822,32 @@ class cooked_indexer - we'll know the containing context of all the DIEs that we might - have scanned. This vector stores these deferred entries. */ - std::vector m_deferred_entries; -+ -+ /* Defer creating a cooked_index_entry corresponding to deferred_entry DE. */ -+ void defer_entry (const deferred_entry &de) -+ { -+ m_deferred_entries.push_back (de); -+ } -+ -+ /* Create a cooked_index_entry corresponding to deferred_entry DE with -+ parent PARENT_ENTRY. */ -+ const cooked_index_entry *resolve_deferred_entry -+ (const deferred_entry &de, const cooked_index_entry *parent_entry) -+ { -+ return m_index_storage->add (de.die_offset, de.tag, de.flags, de.name, -+ parent_entry, m_per_cu); -+ } -+ -+ /* Create cooked_index_entries for the deferred entries. */ -+ void handle_deferred_entries () -+ { -+ for (const auto &entry : m_deferred_entries) -+ { -+ const cooked_index_entry *parent_entry -+ = find_parent (entry.spec_offset); -+ resolve_deferred_entry (entry, parent_entry); -+ } -+ } - }; - - /* Subroutine of dwarf2_build_psymtabs_hard to simplify it. -@@ -16611,7 +16637,7 @@ cooked_indexer::index_dies (cutu_reader *reader, - if (name != nullptr) - { - if (defer != 0) -- m_deferred_entries.push_back ({ -+ defer_entry ({ - this_die, name, defer, abbrev->tag, flags - }); - else -@@ -16716,12 +16742,7 @@ cooked_indexer::make_index (cutu_reader *reader) - return; - index_dies (reader, reader->info_ptr, nullptr, false); - -- for (const auto &entry : m_deferred_entries) -- { -- const cooked_index_entry *parent = find_parent (entry.spec_offset); -- m_index_storage->add (entry.die_offset, entry.tag, entry.flags, -- entry.name, parent, m_per_cu); -- } -+ handle_deferred_entries (); - } - - /* An implementation of quick_symbol_functions for the cooked DWARF --- -2.35.3 - diff --git a/gdb-symtab-factor-out-m_die_range_map-usage.patch b/gdb-symtab-factor-out-m_die_range_map-usage.patch deleted file mode 100644 index c827f0e..0000000 --- a/gdb-symtab-factor-out-m_die_range_map-usage.patch +++ /dev/null @@ -1,151 +0,0 @@ -From b2f260d117dc11b8e90d4e9bf7f4b2cbd63d1d49 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Tue, 22 Aug 2023 13:17:47 +0200 -Subject: [PATCH 02/13] [gdb/symtab] Factor out m_die_range_map usage - -Factor out usage of cooked_indexer::m_die_range_map into new class parent_map -with member functions find_parent and set_parent, and static member function -form_addr. - -Tested on x86_64-linux. ---- - gdb/dwarf2/cooked-index.h | 32 +++++++++++++++++++++++++++ - gdb/dwarf2/read.c | 46 ++++++++++++++++++++------------------- - 2 files changed, 56 insertions(+), 22 deletions(-) - -diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h -index 5aacb321c91..979541fbf60 100644 ---- a/gdb/dwarf2/cooked-index.h -+++ b/gdb/dwarf2/cooked-index.h -@@ -239,6 +239,38 @@ struct cooked_index_entry : public allocate_on_obstack - bool for_name) const; - }; - -+class parent_map -+{ -+public: -+ /* A helper function to turn a section offset into an address that -+ can be used in a parent_map. */ -+ static CORE_ADDR form_addr (sect_offset offset, bool is_dwz) -+ { -+ CORE_ADDR value = to_underlying (offset); -+ if (is_dwz) -+ value |= ((CORE_ADDR) 1) << (8 * sizeof (CORE_ADDR) - 1); -+ return value; -+ } -+ -+ /* Find the parent of DIE LOOKUP. */ -+ const cooked_index_entry *find_parent (CORE_ADDR lookup) const -+ { -+ const void *obj = m_parent_map.find (lookup); -+ return static_cast (obj); -+ } -+ -+ /* Set the parent of DIES in range [START, END] to PARENT_ENTRY. */ -+ void set_parent (CORE_ADDR start, CORE_ADDR end, -+ const cooked_index_entry *parent_entry) -+ { -+ m_parent_map.set_empty (start, end, (void *)parent_entry); -+ } -+ -+private: -+ /* An addrmap that maps from section offsets to cooked_index_entry *. */ -+ addrmap_mutable m_parent_map; -+}; -+ - class cooked_index; - - /* An index of interesting DIEs. This is "cooked", in contrast to a -diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c -index 466d3e59878..d48f3010063 100644 ---- a/gdb/dwarf2/read.c -+++ b/gdb/dwarf2/read.c -@@ -4722,16 +4722,6 @@ class cooked_indexer - - private: - -- /* A helper function to turn a section offset into an address that -- can be used in an addrmap. */ -- CORE_ADDR form_addr (sect_offset offset, bool is_dwz) -- { -- CORE_ADDR value = to_underlying (offset); -- if (is_dwz) -- value |= ((CORE_ADDR) 1) << (8 * sizeof (CORE_ADDR) - 1); -- return value; -- } -- - /* A helper function to scan the PC bounds of READER and record them - in the storage's addrmap. */ - void check_bounds (cutu_reader *reader); -@@ -4799,7 +4789,20 @@ class cooked_indexer - /* An addrmap that maps from section offsets (see the form_addr - method) to newly-created entries. See m_deferred_entries to - understand this. */ -- addrmap_mutable m_die_range_map; -+ parent_map m_die_range_map; -+ -+ /* Find the parent of DIE LOOKUP. */ -+ const cooked_index_entry *find_parent (CORE_ADDR lookup) const -+ { -+ return m_die_range_map.find_parent (lookup); -+ } -+ -+ /* Set the parent of DIES in range [START, END] to PARENT_ENTRY. */ -+ void set_parent (CORE_ADDR start, CORE_ADDR end, -+ const cooked_index_entry *parent_entry) -+ { -+ m_die_range_map.set_parent (start, end, parent_entry); -+ } - - /* A single deferred entry. */ - struct deferred_entry -@@ -16412,15 +16415,13 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu, - - if (*parent_entry == nullptr) - { -- CORE_ADDR addr = form_addr (origin_offset, origin_is_dwz); -+ CORE_ADDR addr -+ = parent_map::form_addr (origin_offset, origin_is_dwz); - if (new_reader->cu == reader->cu - && new_info_ptr > watermark_ptr) - *maybe_defer = addr; - else -- { -- void *obj = m_die_range_map.find (addr); -- *parent_entry = static_cast (obj); -- } -+ *parent_entry = find_parent (addr); - } - - unsigned int bytes_read; -@@ -16538,11 +16539,13 @@ cooked_indexer::recurse (cutu_reader *reader, - { - /* Both start and end are inclusive, so use both "+ 1" and "- 1" to - limit the range to the children of parent_entry. */ -- CORE_ADDR start = form_addr (parent_entry->die_offset + 1, -- reader->cu->per_cu->is_dwz); -- CORE_ADDR end = form_addr (sect_offset (info_ptr - 1 - reader->buffer), -+ CORE_ADDR start -+ = parent_map::form_addr (parent_entry->die_offset + 1, -+ reader->cu->per_cu->is_dwz); -+ CORE_ADDR end -+ = parent_map::form_addr (sect_offset (info_ptr - 1 - reader->buffer), - reader->cu->per_cu->is_dwz); -- m_die_range_map.set_empty (start, end, (void *) parent_entry); -+ set_parent (start, end, parent_entry); - } - - return info_ptr; -@@ -16715,8 +16718,7 @@ cooked_indexer::make_index (cutu_reader *reader) - - for (const auto &entry : m_deferred_entries) - { -- void *obj = m_die_range_map.find (entry.spec_offset); -- cooked_index_entry *parent = static_cast (obj); -+ const cooked_index_entry *parent = find_parent (entry.spec_offset); - m_index_storage->add (entry.die_offset, entry.tag, entry.flags, - entry.name, parent, m_per_cu); - } --- -2.35.3 - diff --git a/gdb-symtab-fix-dw_tag_inlined_subroutine-entries-in-.patch b/gdb-symtab-fix-dw_tag_inlined_subroutine-entries-in-.patch deleted file mode 100644 index 0f20941..0000000 --- a/gdb-symtab-fix-dw_tag_inlined_subroutine-entries-in-.patch +++ /dev/null @@ -1,112 +0,0 @@ -From c79ecacd3f75cfb0ec1a3afc49ca3f30b1759009 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Fri, 11 Aug 2023 01:36:50 +0200 -Subject: [PATCH 13/13] [gdb/symtab] Fix DW_TAG_inlined_subroutine entries in - the cooked index - -We get incorrect qualified names in the cooked index for -DW_TAG_inlined_subroutine DIEs with abstract origin, due to the fact that the -DIE parent is used instead of the abstract origin. - -Fix this by preferring the abstract origin parent, if available. - -Tested on x86_64-linux. - -PR symtab/30728 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30728 ---- - gdb/dwarf2/read.c | 67 ++++++++++++++++++++++------------------------- - 1 file changed, 32 insertions(+), 35 deletions(-) - -diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c -index 93708ef11b9..a4f982962ae 100644 ---- a/gdb/dwarf2/read.c -+++ b/gdb/dwarf2/read.c -@@ -16464,52 +16464,49 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu, - const gdb_byte *new_info_ptr = (new_reader->buffer - + to_underlying (origin_offset)); - -- if (*parent_entry == nullptr) -+ gdb_assert (reader->cu->per_cu->is_debug_types -+ == new_reader->cu->per_cu->is_debug_types); -+ CORE_ADDR addr -+ = parent_map::form_addr (origin_offset, origin_is_dwz, -+ reader->cu->per_cu->is_debug_types); -+ if (new_reader->cu == reader->cu) - { -- gdb_assert (reader->cu->per_cu->is_debug_types -- == new_reader->cu->per_cu->is_debug_types); -- CORE_ADDR addr -- = parent_map::form_addr (origin_offset, origin_is_dwz, -- reader->cu->per_cu->is_debug_types); -- if (new_reader->cu == reader->cu) -+ /* Intra-CU case. */ -+ if (new_info_ptr > watermark_ptr) - { -- /* Intra-CU case. */ -- if (new_info_ptr > watermark_ptr) -- { -- /* Defer because origin is not read yet. */ -- *maybe_defer = addr; -- } -- else -- { -- auto tmp = find_parent (addr); -- if (tmp == &parent_map::deferred) -- { -- /* Defer because origin is deferred. */ -- *maybe_defer = addr; -- } -- else -- *parent_entry = tmp; -- } -+ /* Defer because origin is not read yet. */ -+ *maybe_defer = addr; - } - else - { -- /* Inter-CU case. */ -- if (parent_valid (addr)) -+ auto tmp = find_parent (addr); -+ if (tmp == &parent_map::deferred) - { -- auto tmp = find_parent (addr); -- if (tmp == &parent_map::deferred) -- { -- /* Defer because origin is deferred. */ -- *maybe_defer = addr; -- } -- else -- *parent_entry = tmp; -+ /* Defer because origin is deferred. */ -+ *maybe_defer = addr; - } - else -+ *parent_entry = tmp; -+ } -+ } -+ else -+ { -+ /* Inter-CU case. */ -+ if (parent_valid (addr)) -+ { -+ auto tmp = find_parent (addr); -+ if (tmp == &parent_map::deferred) - { -- /* Defer because origin is in other shard. */ -+ /* Defer because origin is deferred. */ - *maybe_defer = addr; - } -+ else -+ *parent_entry = tmp; -+ } -+ else -+ { -+ /* Defer because origin is in other shard. */ -+ *maybe_defer = addr; - } - } - --- -2.35.3 - diff --git a/gdb-symtab-fix-target-type-of-complex-long-double-on.patch b/gdb-symtab-fix-target-type-of-complex-long-double-on.patch new file mode 100644 index 0000000..d62996a --- /dev/null +++ b/gdb-symtab-fix-target-type-of-complex-long-double-on.patch @@ -0,0 +1,337 @@ +From e485fec626c14303a31bf7eab35c4288f9710c9d Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Wed, 19 Jun 2024 17:32:55 +0200 +Subject: [PATCH 07/46] [gdb/symtab] Fix target type of complex long double on + arm + +When running test-case gdb.base/complex-parts.exp on arm-linux, I get: +... +(gdb) p $_cimag (z3)^M +$6 = 6.5^M +(gdb) PASS: gdb.base/complex-parts.exp: long double imaginary: p $_cimag (z3) +ptype $^M +type = double^M +(gdb) FAIL: gdb.base/complex-parts.exp: long double imaginary: ptype $ +... + +Given that z3 is a complex long double, the test-case expects the type of the +imaginary part of z3 to be long double, but it's double instead. + +This is due to the fact that the dwarf info doesn't specify an explicit target +type: +... + <5b> DW_AT_name : z3 + <60> DW_AT_type : <0xa4> + ... + <1>: Abbrev Number: 2 (DW_TAG_base_type) + DW_AT_byte_size : 16 + DW_AT_encoding : 3 (complex float) + DW_AT_name : complex long double +... +and consequently we're guessing in dwarf2_init_complex_target_type based on +the size: +... + case 64: + tt = builtin_type (gdbarch)->builtin_double; + break; + case 96: /* The x86-32 ABI specifies 96-bit long double. */ + case 128: + tt = builtin_type (gdbarch)->builtin_long_double; + break; +... + +For arm-linux, complex long double is 16 bytes, so the target type is assumed +to be 8 bytes, which is handled by the "case 64", which gets us double +instead of long double. + +Fix this by searching for "long" in the name_hint parameter, and using long +double instead. + +Note that base types in dwarf are not allowed to contain references to other +types, and the complex types are base types, so the missing explicit target +type is standard-conformant. + +A gcc PR was filed to add this as a dwarf extension ( +https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115272 ). + +Tested on arm-linux. +--- + gdb/dwarf2/read.c | 10 +- + .../gdb.dwarf2/dw2-complex-parts.exp | 244 ++++++++++++++++++ + 2 files changed, 253 insertions(+), 1 deletion(-) + create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-complex-parts.exp + +diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c +index 7cd1d2b4c4e..18054d0070d 100644 +--- a/gdb/dwarf2/read.c ++++ b/gdb/dwarf2/read.c +@@ -15123,7 +15123,15 @@ dwarf2_init_complex_target_type (struct dwarf2_cu *cu, + tt = builtin_type (gdbarch)->builtin_float; + break; + case 64: +- tt = builtin_type (gdbarch)->builtin_double; ++ if (builtin_type (gdbarch)->builtin_long_double->length () == 8 ++ && name_hint != nullptr ++ && strstr (name_hint, "long") != nullptr) ++ { ++ /* Use "long double" for "complex long double". */ ++ tt = builtin_type (gdbarch)->builtin_long_double; ++ } ++ else ++ tt = builtin_type (gdbarch)->builtin_double; + break; + case 96: /* The x86-32 ABI specifies 96-bit long double. */ + case 128: +diff --git a/gdb/testsuite/gdb.dwarf2/dw2-complex-parts.exp b/gdb/testsuite/gdb.dwarf2/dw2-complex-parts.exp +new file mode 100644 +index 00000000000..281e87d2fc8 +--- /dev/null ++++ b/gdb/testsuite/gdb.dwarf2/dw2-complex-parts.exp +@@ -0,0 +1,244 @@ ++# Copyright 2024 Free Software Foundation, Inc. ++ ++# 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 . ++ ++# Test complex types, and their parts. Dwarf assembly counterpart of ++# gdb.base/complex-parts.exp. ++# ++# In dwarf, base types are not allowed to have references to other types. And ++# because complex types are modeled as base types, gdb has to figure out what ++# the part type is. ++# ++# It would be easier for gdb if compilers would add a dwarf extension and ++# supply this information, but that may or may not happen ++# ( https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115272 ). ++ ++load_lib dwarf.exp ++ ++# This test can only be run on targets which support DWARF-2 and use gas. ++require dwarf2_support ++ ++standard_testfile main.c -debug.S ++ ++if [prepare_for_testing "failed to prepare" $testfile \ ++ "${srcfile}" {}] { ++ return -1 ++} ++ ++set float_size [get_sizeof float 0] ++set double_size [get_sizeof double 0] ++set long_double_size [get_sizeof "long double" 0] ++ ++set int_size [get_sizeof int 0] ++ ++# Create the DWARF. ++set asm_file [standard_output_file $srcfile2] ++Dwarf::assemble $asm_file { ++ cu { version 2 } { ++ compile_unit {} { ++ # Main. ++ ++ declare_labels int_type ++ ++ int_type: DW_TAG_base_type { ++ {DW_AT_byte_size $::int_size DW_FORM_sdata} ++ {DW_AT_encoding @DW_ATE_signed} ++ {DW_AT_name int} ++ } ++ ++ DW_TAG_subprogram { ++ {MACRO_AT_func {main}} ++ {type :$int_type} ++ } ++ ++ # GCC complex float. ++ ++ declare_labels cf_type cd_type cld_type ++ ++ cf_type: DW_TAG_base_type { ++ {DW_AT_byte_size [expr 2 * $::float_size] DW_FORM_sdata} ++ {DW_AT_encoding @DW_ATE_complex_float} ++ {DW_AT_name "complex float"} ++ } ++ ++ cd_type: DW_TAG_base_type { ++ {DW_AT_byte_size [expr 2 * $::double_size] DW_FORM_sdata} ++ {DW_AT_encoding @DW_ATE_complex_float} ++ {DW_AT_name "complex double"} ++ } ++ ++ cld_type: DW_TAG_base_type { ++ {DW_AT_byte_size [expr 2 * $::long_double_size] DW_FORM_sdata} ++ {DW_AT_encoding @DW_ATE_complex_float} ++ {DW_AT_name "complex long double"} ++ } ++ ++ DW_TAG_variable { ++ {name var_complex_float} ++ {DW_AT_type :$cf_type} ++ } ++ ++ DW_TAG_variable { ++ {name var_complex_double} ++ {DW_AT_type :$cd_type} ++ } ++ ++ DW_TAG_variable { ++ {name var_complex_long_double} ++ {DW_AT_type :$cld_type} ++ } ++ ++ # GCC complex int. ++ # This is what gcc currently generates, see gcc PR debug/93988. ++ ++ declare_labels ci_type ++ ++ ci_type: DW_TAG_base_type { ++ {DW_AT_byte_size [expr 2 * $::int_size] DW_FORM_sdata} ++ {DW_AT_encoding @DW_ATE_lo_user} ++ {DW_AT_name "complex int"} ++ } ++ ++ DW_TAG_variable { ++ {name var_complex_int} ++ {DW_AT_type :$ci_type} ++ } ++ ++ # Clang complex float. ++ # This is what clang currently generates, see this issue ( ++ # https://github.com/llvm/llvm-project/issues/52996 ). ++ ++ declare_labels clang_cf_type clang_cd_type clang_cld_type ++ ++ clang_cf_type: DW_TAG_base_type { ++ {DW_AT_byte_size [expr 2 * $::float_size] DW_FORM_sdata} ++ {DW_AT_encoding @DW_ATE_complex_float} ++ {DW_AT_name "complex"} ++ } ++ ++ DW_TAG_variable { ++ {name var_complex_clang_float} ++ {DW_AT_type :$clang_cf_type} ++ } ++ ++ clang_cd_type: DW_TAG_base_type { ++ {DW_AT_byte_size [expr 2 * $::double_size] DW_FORM_sdata} ++ {DW_AT_encoding @DW_ATE_complex_float} ++ {DW_AT_name "complex"} ++ } ++ ++ DW_TAG_variable { ++ {name var_complex_clang_double} ++ {DW_AT_type :$clang_cd_type} ++ } ++ ++ clang_cld_type: DW_TAG_base_type { ++ {DW_AT_byte_size [expr 2 * $::long_double_size] DW_FORM_sdata} ++ {DW_AT_encoding @DW_ATE_complex_float} ++ {DW_AT_name "complex"} ++ } ++ ++ DW_TAG_variable { ++ {name var_complex_clang_long_double} ++ {DW_AT_type :$clang_cld_type} ++ } ++ } ++ } ++} ++ ++if [prepare_for_testing "failed to prepare" $testfile \ ++ "${asm_file} ${srcfile}" {}] { ++ return -1 ++} ++ ++if ![runto_main] { ++ return -1 ++} ++ ++proc do_test { type {clang 0}} { ++ with_test_prefix $type { ++ with_test_prefix clang=$clang { ++ ++ if { $clang } { ++ set type_id [regsub -all " " $type _] ++ set var "var_complex_clang_$type_id" ++ ++ # Gdb could try to synthesize better names, see enhancement ++ # PR symtab/31858. ++ set ctype "complex" ++ set ctype_id "complex" ++ } else { ++ set ctype "complex $type" ++ set type_id [regsub -all " " $type _] ++ set ctype_id [regsub -all " " $ctype _] ++ set var "var_$ctype_id" ++ } ++ ++ gdb_test "ptype '$type'" \ ++ "type = $type" ++ ++ gdb_test "ptype '$ctype'" \ ++ "type = $ctype" ++ ++ eval set type_size \$::${type_id}_size ++ ++ gdb_test "p sizeof ('$type')" \ ++ " = $type_size" ++ ++ if { ! $clang } { ++ # With clang, the ctype name does not uniquely map to a type, ++ # so the size is unpredictable. ++ gdb_test "p sizeof ('$ctype')" \ ++ " = [expr 2 * $type_size]" ++ } ++ ++ set re_kfail \ ++ [string_to_regexp \ ++ "'var_complex_int' has unknown type; cast it to its declared type"] ++ ++ foreach f { {$_cimag} {$_creal} } { ++ gdb_test_multiple "p $f ($var)" "" { ++ -re -wrap " = " { ++ pass $gdb_test_name ++ } ++ -re -wrap $re_kfail { ++ kfail gdb/31857 $gdb_test_name ++ } ++ } ++ ++ if { $clang } { ++ # Without a specific complex type name, it's ++ # unpredictable which type name the part will have. ++ gdb_test {ptype $} \ ++ "type = (float|double|long double)" \ ++ "ptype $f" ++ } else { ++ gdb_test {ptype $} \ ++ "type = $type" \ ++ "ptype $f" ++ } ++ } ++ } ++ } ++} ++ ++do_test "float" ++do_test "double" ++do_test "long double" ++ ++do_test "int" ++ ++do_test "float" 1 ++do_test "double" 1 ++do_test "long double" 1 +-- +2.43.0 + diff --git a/gdb-symtab-handle-nullptr-parent-in-parent_map-set_p.patch b/gdb-symtab-handle-nullptr-parent-in-parent_map-set_p.patch deleted file mode 100644 index 21f26df..0000000 --- a/gdb-symtab-handle-nullptr-parent-in-parent_map-set_p.patch +++ /dev/null @@ -1,37 +0,0 @@ -From bc970668f83cf142c4955d1cbeaa24e8bcc4b238 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Fri, 25 Aug 2023 09:30:54 +0200 -Subject: [PATCH 03/13] [gdb/symtab] Handle nullptr parent in - parent_map::set_parent - -Set_parent uses m_die_range_map.set_empty, which doesn't allow -parent_entry == nullptr. - -So it may be necessary to guard calls to set_parent with -"if (parent_entry != nullptr)". - -Fix this by handling the parent_entry == nullptr case in set_parent. - -Tested on x86_64-linux. ---- - gdb/dwarf2/cooked-index.h | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h -index 979541fbf60..79fbfe88c03 100644 ---- a/gdb/dwarf2/cooked-index.h -+++ b/gdb/dwarf2/cooked-index.h -@@ -263,7 +263,9 @@ class parent_map - void set_parent (CORE_ADDR start, CORE_ADDR end, - const cooked_index_entry *parent_entry) - { -- m_parent_map.set_empty (start, end, (void *)parent_entry); -+ /* Calling set_empty with nullptr is currently not allowed. */ -+ if (parent_entry != nullptr) -+ m_parent_map.set_empty (start, end, (void *)parent_entry); - } - - private: --- -2.35.3 - diff --git a/gdb-symtab-keep-track-of-all-parents-for-cooked-inde.patch b/gdb-symtab-keep-track-of-all-parents-for-cooked-inde.patch deleted file mode 100644 index 03acf13..0000000 --- a/gdb-symtab-keep-track-of-all-parents-for-cooked-inde.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0e706742f37ee90629350780263b573f326f1a5f Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Thu, 7 Dec 2023 10:38:05 +0100 -Subject: [PATCH 12/13] [gdb/symtab] Keep track of all parents for cooked index - -Keep track of all parents for cooked index. - -Tested on x86_64-linux. ---- - gdb/dwarf2/read.c | 12 +++++++++--- - 1 file changed, 9 insertions(+), 3 deletions(-) - -diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c -index de7b655d26c..93708ef11b9 100644 ---- a/gdb/dwarf2/read.c -+++ b/gdb/dwarf2/read.c -@@ -16718,9 +16718,15 @@ cooked_indexer::index_dies (cutu_reader *reader, - }); - } - else -- this_entry = m_index_storage->add (this_die, abbrev->tag, flags, -- name, this_parent_entry, -- m_per_cu); -+ { -+ CORE_ADDR addr -+ = parent_map::form_addr (this_die, reader->cu->per_cu->is_dwz, -+ reader->cu->per_cu->is_debug_types); -+ set_parent (addr, addr, this_parent_entry); -+ this_entry = m_index_storage->add (this_die, abbrev->tag, flags, -+ name, this_parent_entry, -+ m_per_cu); -+ } - } - - if (linkage_name != nullptr) --- -2.35.3 - diff --git a/gdb-symtab-keep-track-of-processed-dies-in-shard.patch b/gdb-symtab-keep-track-of-processed-dies-in-shard.patch deleted file mode 100644 index 371363a..0000000 --- a/gdb-symtab-keep-track-of-processed-dies-in-shard.patch +++ /dev/null @@ -1,126 +0,0 @@ -From e8285c8b37d28033209cad6579db4b9f6a48a01a Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Sun, 24 Sep 2023 11:41:39 +0200 -Subject: [PATCH 08/13] [gdb/symtab] Keep track of processed DIEs in shard - -For optimizations in two following patches, we keep track in each shard which -DIEs have been processed. - -Tested on x86_64-linux. ---- - gdb/dwarf2/cooked-index.c | 1 + - gdb/dwarf2/cooked-index.h | 15 +++++++++++++++ - gdb/dwarf2/read.c | 24 ++++++++++++++++++++++++ - 3 files changed, 40 insertions(+) - -diff --git a/gdb/dwarf2/cooked-index.c b/gdb/dwarf2/cooked-index.c -index 3231d25db5a..c096da57d62 100644 ---- a/gdb/dwarf2/cooked-index.c -+++ b/gdb/dwarf2/cooked-index.c -@@ -723,6 +723,7 @@ cooked_index::handle_deferred_entries () - { - shard->m_die_range_map.reset (nullptr); - shard->m_deferred_entries.reset (nullptr); -+ shard->m_die_range_map_valid.reset (nullptr); - } - } - -diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h -index 66424c37f7c..fa895233035 100644 ---- a/gdb/dwarf2/cooked-index.h -+++ b/gdb/dwarf2/cooked-index.h -@@ -316,6 +316,7 @@ class cooked_index_shard - { - m_die_range_map.reset (new parent_map); - m_deferred_entries.reset (new std::vector); -+ m_die_range_map_valid.reset (new addrmap_mutable); - } - - DISABLE_COPY_AND_ASSIGN (cooked_index_shard); -@@ -407,6 +408,18 @@ class cooked_index_shard - const cooked_index_entry *resolve_deferred_entry - (const deferred_entry &entry, const cooked_index_entry *parent_entry); - -+ /* Mark parents in range [START, END] as valid . */ -+ void set_parent_valid (CORE_ADDR start, CORE_ADDR end) -+ { -+ m_die_range_map_valid->set_empty (start, end, (void *) 1); -+ } -+ -+ /* Return true if find_parents can be relied upon. */ -+ bool parent_valid (CORE_ADDR addr) -+ { -+ return m_die_range_map_valid->find (addr) != nullptr; -+ } -+ - private: - - /* Return the entry that is believed to represent the program's -@@ -470,6 +483,8 @@ class cooked_index_shard - understand this. */ - std::unique_ptr m_die_range_map; - -+ std::unique_ptr m_die_range_map_valid; -+ - /* The generated DWARF can sometimes have the declaration for a - method in a class (or perhaps namespace) scope, with the - definition appearing outside this scope... just one of the many -diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c -index 5b7c0969ed7..09598e702bc 100644 ---- a/gdb/dwarf2/read.c -+++ b/gdb/dwarf2/read.c -@@ -4697,6 +4697,12 @@ class cooked_index_storage - m_index->defer_entry (de); - } - -+ /* Mark parents in range [START, END] as valid . */ -+ void set_parent_valid (CORE_ADDR start, CORE_ADDR end) -+ { -+ m_index->set_parent_valid (start, end); -+ } -+ - private: - - /* Hash function for a cutu_reader. */ -@@ -4840,6 +4846,11 @@ class cooked_indexer - { - m_index_storage->defer_entry (de); - } -+ -+ void set_parent_valid (CORE_ADDR start, CORE_ADDR end) -+ { -+ m_index_storage->set_parent_valid (start, end); -+ } - }; - - /* Subroutine of dwarf2_build_psymtabs_hard to simplify it. -@@ -16604,6 +16615,11 @@ cooked_indexer::index_dies (cutu_reader *reader, - + to_underlying (reader->cu->header.sect_off) - + reader->cu->header.get_length_with_initial ()); - -+ const CORE_ADDR start_cu -+ = parent_map::form_addr (sect_offset (info_ptr - reader->buffer), -+ reader->cu->per_cu->is_dwz, -+ reader->cu->per_cu->is_debug_types); -+ - while (info_ptr < end_ptr) - { - sect_offset this_die = (sect_offset) (info_ptr - reader->buffer); -@@ -16754,6 +16770,14 @@ cooked_indexer::index_dies (cutu_reader *reader, - } - } - -+ { -+ CORE_ADDR end_prev_die -+ = parent_map::form_addr (sect_offset (info_ptr - reader->buffer - 1), -+ reader->cu->per_cu->is_dwz, -+ reader->cu->per_cu->is_debug_types); -+ set_parent_valid (start_cu, end_prev_die); -+ } -+ - return info_ptr; - } - --- -2.35.3 - diff --git a/gdb-symtab-refactor-condition-in-scan_attributes.patch b/gdb-symtab-refactor-condition-in-scan_attributes.patch deleted file mode 100644 index 169e8f4..0000000 --- a/gdb-symtab-refactor-condition-in-scan_attributes.patch +++ /dev/null @@ -1,70 +0,0 @@ -From f72f115b4c012e3748a2e702d7b970be19974885 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Mon, 11 Dec 2023 15:41:26 +0100 -Subject: [PATCH 01/13] [gdb/symtab] Refactor condition in scan_attributes - -In scan_attributes there's code: -... - if (new_reader->cu == reader->cu - && new_info_ptr > watermark_ptr - && *parent_entry == nullptr) - ... - else if (*parent_entry == nullptr) - ... -... -that uses the "*parent_entry == nullptr" condition twice. - -Make this somewhat more readable by factoring out the condition: -... - if (*parent_entry == nullptr) - { - if (new_reader->cu == reader->cu - && new_info_ptr > watermark_ptr) - ... - else - ... - } -... - -This also allows us to factor out "form_addr (origin_offset, origin_is_dwz)". - -Tested on x86_64-linux. ---- - gdb/dwarf2/read.c | 18 ++++++++++-------- - 1 file changed, 10 insertions(+), 8 deletions(-) - -diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c -index 50fa302b43a..466d3e59878 100644 ---- a/gdb/dwarf2/read.c -+++ b/gdb/dwarf2/read.c -@@ -16410,15 +16410,17 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu, - const gdb_byte *new_info_ptr = (new_reader->buffer - + to_underlying (origin_offset)); - -- if (new_reader->cu == reader->cu -- && new_info_ptr > watermark_ptr -- && *parent_entry == nullptr) -- *maybe_defer = form_addr (origin_offset, origin_is_dwz); -- else if (*parent_entry == nullptr) -+ if (*parent_entry == nullptr) - { -- CORE_ADDR lookup = form_addr (origin_offset, origin_is_dwz); -- void *obj = m_die_range_map.find (lookup); -- *parent_entry = static_cast (obj); -+ CORE_ADDR addr = form_addr (origin_offset, origin_is_dwz); -+ if (new_reader->cu == reader->cu -+ && new_info_ptr > watermark_ptr) -+ *maybe_defer = addr; -+ else -+ { -+ void *obj = m_die_range_map.find (addr); -+ *parent_entry = static_cast (obj); -+ } - } - - unsigned int bytes_read; - -base-commit: 3490f51a80a10d46dc1885ba672d9390a8221170 --- -2.35.3 - diff --git a/gdb-symtab-resolve-deferred-entries-inter-shard-case.patch b/gdb-symtab-resolve-deferred-entries-inter-shard-case.patch deleted file mode 100644 index cc4f6f3..0000000 --- a/gdb-symtab-resolve-deferred-entries-inter-shard-case.patch +++ /dev/null @@ -1,500 +0,0 @@ -From e2d7097cf236c9ea6959785754d067833fc302af Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Tue, 22 Aug 2023 14:24:42 +0200 -Subject: [PATCH 05/13] [gdb/symtab] Resolve deferred entries, inter-shard case - -Generically solve the case of inter-CU dependencies, including inter-shard -dependencies: -- mark deferred entries in new data structure m_deferred, -- return &parent_map::deferred in find_parent for deferred entries, -- defer all intra-CU dependencies that depend on deferred entries, -- defer all inter-CU dependencies (note that two subsequent patches implement - optimizations to deal with this more optimally), -- move m_die_range_map and m_deferred_dies to cooked_index_shard, and -- move handle_deferred_dies to the cooked_index, where it is called in the - constructor, and update it to handle the intra-shard case. - -Handling units from the .debug_info section alongside units from the -.debug_types section requires us to extend form_addr to take is_debug_types -into account. - -Tested on x86_64-linux. - -PR symtab/30846 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30846 ---- - gdb/dwarf2/cooked-index.c | 77 +++++++++++++++++++++++ - gdb/dwarf2/cooked-index.h | 105 ++++++++++++++++++++++++++++++- - gdb/dwarf2/read.c | 128 ++++++++++++++++++++++---------------- - 3 files changed, 254 insertions(+), 56 deletions(-) - -diff --git a/gdb/dwarf2/cooked-index.c b/gdb/dwarf2/cooked-index.c -index 58ea541a5c9..3231d25db5a 100644 ---- a/gdb/dwarf2/cooked-index.c -+++ b/gdb/dwarf2/cooked-index.c -@@ -228,6 +228,12 @@ cooked_index_entry::write_scope (struct obstack *storage, - - /* See cooked-index.h. */ - -+cooked_index_entry parent_map::deferred((sect_offset)0, (dwarf_tag)0, -+ (cooked_index_flag)0, nullptr, -+ nullptr, nullptr); -+ -+/* See cooked-index.h. */ -+ - const cooked_index_entry * - cooked_index_shard::add (sect_offset die_offset, enum dwarf_tag tag, - cooked_index_flag flags, const char *name, -@@ -446,6 +452,8 @@ cooked_index_shard::wait (bool allow_quit) const - cooked_index::cooked_index (vec_type &&vec) - : m_vector (std::move (vec)) - { -+ handle_deferred_entries (); -+ - for (auto &idx : m_vector) - idx->finalize (); - -@@ -649,6 +657,75 @@ cooked_index::maybe_write_index (dwarf2_per_bfd *per_bfd, - global_index_cache.store (per_bfd, ctx); - } - -+/* See cooked-index.h. */ -+ -+const cooked_index_entry * -+cooked_index_shard::resolve_deferred_entry -+ (const deferred_entry &de, const cooked_index_entry *parent_entry) -+{ -+ reset_parent_deferred (parent_map::form_addr (de.die_offset, de.per_cu_2->is_dwz, -+ de.per_cu_2->is_debug_types)); -+ return add (de.die_offset, de.tag, de.flags, de.name, -+ parent_entry, de.per_cu); -+} -+ -+/* See cooked-index.h. */ -+ -+const cooked_index_entry * -+cooked_index::find_parent_deferred_entry -+ (const cooked_index_shard::deferred_entry &entry) const -+{ -+ const cooked_index_entry *parent_entry = nullptr; -+ for (auto &parent_map_shard : m_vector) -+ { -+ auto res = parent_map_shard->find_parent (entry.spec_offset); -+ if (res != nullptr) -+ { -+ parent_entry = res; -+ break; -+ } -+ } -+ -+ return parent_entry; -+} -+ -+/* See cooked-index.h. */ -+ -+void -+cooked_index::handle_deferred_entries () -+{ -+ bool changed; -+ bool deferred; -+ do -+ { -+ deferred = false; -+ changed = false; -+ for (auto &shard : m_vector) -+ for (auto it = shard->m_deferred_entries->begin (); -+ it != shard->m_deferred_entries->end (); ) -+ { -+ const cooked_index_entry *parent_entry -+ = find_parent_deferred_entry (*it); -+ if (parent_entry == &parent_map::deferred) -+ { -+ deferred = true; -+ it++; -+ continue; -+ } -+ shard->resolve_deferred_entry (*it, parent_entry); -+ it = shard->m_deferred_entries->erase (it); -+ changed = true; -+ } -+ } -+ while (changed && deferred); -+ -+ for (auto &shard : m_vector) -+ { -+ shard->m_die_range_map.reset (nullptr); -+ shard->m_deferred_entries.reset (nullptr); -+ } -+} -+ - /* Wait for all the index cache entries to be written before gdb - exits. */ - static void -diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h -index 79fbfe88c03..66424c37f7c 100644 ---- a/gdb/dwarf2/cooked-index.h -+++ b/gdb/dwarf2/cooked-index.h -@@ -34,6 +34,7 @@ - #include "dwarf2/mapped-index.h" - #include "dwarf2/tag.h" - #include "gdbsupport/range-chain.h" -+#include - - struct dwarf2_per_cu_data; - struct dwarf2_per_bfd; -@@ -242,19 +243,29 @@ struct cooked_index_entry : public allocate_on_obstack - class parent_map - { - public: -+ /* A dummy cooked_index_entry to mark that computing the parent has been -+ deferred. */ -+ static cooked_index_entry deferred; -+ - /* A helper function to turn a section offset into an address that - can be used in a parent_map. */ -- static CORE_ADDR form_addr (sect_offset offset, bool is_dwz) -+ static CORE_ADDR form_addr (sect_offset offset, bool is_dwz, -+ bool is_debug_types) - { - CORE_ADDR value = to_underlying (offset); - if (is_dwz) - value |= ((CORE_ADDR) 1) << (8 * sizeof (CORE_ADDR) - 1); -+ if (is_debug_types) -+ value |= ((CORE_ADDR) 1) << (8 * sizeof (CORE_ADDR) - 2); - return value; - } - - /* Find the parent of DIE LOOKUP. */ - const cooked_index_entry *find_parent (CORE_ADDR lookup) const - { -+ if (m_deferred.find (lookup) != m_deferred.end ()) -+ return &parent_map::deferred; -+ - const void *obj = m_parent_map.find (lookup); - return static_cast (obj); - } -@@ -265,12 +276,28 @@ class parent_map - { - /* Calling set_empty with nullptr is currently not allowed. */ - if (parent_entry != nullptr) -- m_parent_map.set_empty (start, end, (void *)parent_entry); -+ { -+ gdb_assert (parent_entry != &parent_map::deferred); -+ m_parent_map.set_empty (start, end, (void *)parent_entry); -+ } -+ } -+ -+ void set_parent_deferred (CORE_ADDR addr) -+ { -+ m_deferred.emplace (addr); -+ } -+ -+ void reset_parent_deferred (CORE_ADDR addr) -+ { -+ m_deferred.erase (addr); - } - - private: - /* An addrmap that maps from section offsets to cooked_index_entry *. */ - addrmap_mutable m_parent_map; -+ -+ /* DIEs that are deffered. */ -+ std::unordered_set m_deferred; - }; - - class cooked_index; -@@ -285,7 +312,12 @@ class cooked_index; - class cooked_index_shard - { - public: -- cooked_index_shard () = default; -+ cooked_index_shard () -+ { -+ m_die_range_map.reset (new parent_map); -+ m_deferred_entries.reset (new std::vector); -+ } -+ - DISABLE_COPY_AND_ASSIGN (cooked_index_shard); - - /* Create a new cooked_index_entry and register it with this object. -@@ -329,6 +361,52 @@ class cooked_index_shard - for completion, will be returned. */ - range find (const std::string &name, bool completing) const; - -+ /* Find the parent of DIE LOOKUP. */ -+ const cooked_index_entry * -+ find_parent (CORE_ADDR lookup) const -+ { -+ return m_die_range_map->find_parent (lookup); -+ } -+ -+ /* Set the parent of DIES in range [START, END] to PARENT_ENTRY. */ -+ void set_parent (CORE_ADDR start, CORE_ADDR end, -+ const cooked_index_entry *parent_entry) -+ { -+ m_die_range_map->set_parent (start, end, parent_entry); -+ } -+ -+ void set_parent_deferred (CORE_ADDR addr) -+ { -+ m_die_range_map->set_parent_deferred (addr); -+ } -+ -+ void reset_parent_deferred (CORE_ADDR addr) -+ { -+ m_die_range_map->reset_parent_deferred (addr); -+ } -+ -+ /* A single deferred entry. See m_deferred_entries. */ -+ struct deferred_entry -+ { -+ sect_offset die_offset; -+ const char *name; -+ CORE_ADDR spec_offset; -+ dwarf_tag tag; -+ cooked_index_flag flags; -+ dwarf2_per_cu_data *per_cu; -+ dwarf2_per_cu_data *per_cu_2; -+ }; -+ -+ /* Defer creating a cooked_index_entry corresponding to DEFERRED. */ -+ void defer_entry (deferred_entry de) -+ { -+ m_deferred_entries->push_back (de); -+ } -+ -+ /* Variant of add that takes a deferred_entry as parameter. */ -+ const cooked_index_entry *resolve_deferred_entry -+ (const deferred_entry &entry, const cooked_index_entry *parent_entry); -+ - private: - - /* Return the entry that is believed to represent the program's -@@ -386,6 +464,20 @@ class cooked_index_shard - that the 'get' method is never called on this future, only - 'wait'. */ - gdb::future m_future; -+ -+ /* An addrmap that maps from section offsets (see the form_addr -+ method) to newly-created entries. See m_deferred_entries to -+ understand this. */ -+ std::unique_ptr m_die_range_map; -+ -+ /* The generated DWARF can sometimes have the declaration for a -+ method in a class (or perhaps namespace) scope, with the -+ definition appearing outside this scope... just one of the many -+ bad things about DWARF. In order to handle this situation, we -+ defer certain entries until the end of scanning, at which point -+ we'll know the containing context of all the DIEs that we might -+ have scanned. This vector stores these deferred entries. */ -+ std::unique_ptr> m_deferred_entries; - }; - - /* The main index of DIEs. The parallel DIE indexers create -@@ -469,6 +561,13 @@ class cooked_index : public dwarf_scanner_base - - private: - -+ /* Find the parent corresponding to deferred entry ENTRY. */ -+ const cooked_index_entry *find_parent_deferred_entry -+ (const cooked_index_shard::deferred_entry &entry) const; -+ -+ /* Create cooked_index_entries for the deferred entries. */ -+ void handle_deferred_entries (); -+ - /* Maybe write the index to the index cache. */ - void maybe_write_index (dwarf2_per_bfd *per_bfd, - const index_cache_store_context &); -diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c -index afdf9e870a8..5b7c0969ed7 100644 ---- a/gdb/dwarf2/read.c -+++ b/gdb/dwarf2/read.c -@@ -4672,6 +4672,31 @@ class cooked_index_storage - return &m_addrmap; - } - -+ /* Find the parent of DIE LOOKUP. */ -+ const cooked_index_entry *find_parent (CORE_ADDR lookup) -+ { -+ return m_index->find_parent (lookup); -+ } -+ -+ /* Set the parent of DIES in range [START, END] to PARENT_ENTRY. */ -+ void set_parent (CORE_ADDR start, CORE_ADDR end, -+ const cooked_index_entry *parent_entry) -+ { -+ m_index->set_parent (start, end, parent_entry); -+ } -+ -+ /* Set the parent of DIE at ADDR as deferred. */ -+ void set_parent_deferred (CORE_ADDR addr) -+ { -+ m_index->set_parent_deferred (addr); -+ } -+ -+ /* Defer creating a cooked_index_entry corresponding to deferred_entry DE. */ -+ void defer_entry (cooked_index_shard::deferred_entry de) -+ { -+ m_index->defer_entry (de); -+ } -+ - private: - - /* Hash function for a cutu_reader. */ -@@ -4794,59 +4819,26 @@ class cooked_indexer - /* Find the parent of DIE LOOKUP. */ - const cooked_index_entry *find_parent (CORE_ADDR lookup) const - { -- return m_die_range_map.find_parent (lookup); -+ return m_index_storage->find_parent (lookup); - } - - /* Set the parent of DIES in range [START, END] to PARENT_ENTRY. */ - void set_parent (CORE_ADDR start, CORE_ADDR end, - const cooked_index_entry *parent_entry) - { -- m_die_range_map.set_parent (start, end, parent_entry); -+ m_index_storage->set_parent (start, end, parent_entry); - } - -- /* A single deferred entry. */ -- struct deferred_entry -- { -- sect_offset die_offset; -- const char *name; -- CORE_ADDR spec_offset; -- dwarf_tag tag; -- cooked_index_flag flags; -- }; -- -- /* The generated DWARF can sometimes have the declaration for a -- method in a class (or perhaps namespace) scope, with the -- definition appearing outside this scope... just one of the many -- bad things about DWARF. In order to handle this situation, we -- defer certain entries until the end of scanning, at which point -- we'll know the containing context of all the DIEs that we might -- have scanned. This vector stores these deferred entries. */ -- std::vector m_deferred_entries; -- -- /* Defer creating a cooked_index_entry corresponding to deferred_entry DE. */ -- void defer_entry (const deferred_entry &de) -+ /* Set the parent of DIE at ADDR as deferred. */ -+ void set_parent_deferred (CORE_ADDR addr) - { -- m_deferred_entries.push_back (de); -+ m_index_storage->set_parent_deferred (addr); - } - -- /* Create a cooked_index_entry corresponding to deferred_entry DE with -- parent PARENT_ENTRY. */ -- const cooked_index_entry *resolve_deferred_entry -- (const deferred_entry &de, const cooked_index_entry *parent_entry) -- { -- return m_index_storage->add (de.die_offset, de.tag, de.flags, de.name, -- parent_entry, m_per_cu); -- } -- -- /* Create cooked_index_entries for the deferred entries. */ -- void handle_deferred_entries () -+ /* Defer creating a cooked_index_entry corresponding to deferred_entry DE. */ -+ void defer_entry (const cooked_index_shard::deferred_entry &de) - { -- for (const auto &entry : m_deferred_entries) -- { -- const cooked_index_entry *parent_entry -- = find_parent (entry.spec_offset); -- resolve_deferred_entry (entry, parent_entry); -- } -+ m_index_storage->defer_entry (de); - } - }; - -@@ -16441,13 +16433,36 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu, - - if (*parent_entry == nullptr) - { -+ gdb_assert (reader->cu->per_cu->is_debug_types -+ == new_reader->cu->per_cu->is_debug_types); - CORE_ADDR addr -- = parent_map::form_addr (origin_offset, origin_is_dwz); -- if (new_reader->cu == reader->cu -- && new_info_ptr > watermark_ptr) -- *maybe_defer = addr; -+ = parent_map::form_addr (origin_offset, origin_is_dwz, -+ reader->cu->per_cu->is_debug_types); -+ if (new_reader->cu == reader->cu) -+ { -+ /* Intra-CU case. */ -+ if (new_info_ptr > watermark_ptr) -+ { -+ /* Defer because origin is not read yet. */ -+ *maybe_defer = addr; -+ } -+ else -+ { -+ auto tmp = find_parent (addr); -+ if (tmp == &parent_map::deferred) -+ { -+ /* Defer because origin is deferred. */ -+ *maybe_defer = addr; -+ } -+ else -+ *parent_entry = tmp; -+ } -+ } - else -- *parent_entry = find_parent (addr); -+ { -+ /* Inter-CU case. */ -+ *maybe_defer = addr; -+ } - } - - unsigned int bytes_read; -@@ -16567,10 +16582,12 @@ cooked_indexer::recurse (cutu_reader *reader, - limit the range to the children of parent_entry. */ - CORE_ADDR start - = parent_map::form_addr (parent_entry->die_offset + 1, -- reader->cu->per_cu->is_dwz); -+ reader->cu->per_cu->is_dwz, -+ reader->cu->per_cu->is_debug_types); - CORE_ADDR end - = parent_map::form_addr (sect_offset (info_ptr - 1 - reader->buffer), -- reader->cu->per_cu->is_dwz); -+ reader->cu->per_cu->is_dwz, -+ reader->cu->per_cu->is_debug_types); - set_parent (start, end, parent_entry); - } - -@@ -16637,9 +16654,16 @@ cooked_indexer::index_dies (cutu_reader *reader, - if (name != nullptr) - { - if (defer != 0) -- defer_entry ({ -- this_die, name, defer, abbrev->tag, flags -- }); -+ { -+ CORE_ADDR addr -+ = parent_map::form_addr (this_die, reader->cu->per_cu->is_dwz, -+ reader->cu->per_cu->is_debug_types); -+ set_parent_deferred (addr); -+ defer_entry ({ -+ this_die, name, defer, abbrev->tag, flags, m_per_cu, -+ reader->cu->per_cu -+ }); -+ } - else - this_entry = m_index_storage->add (this_die, abbrev->tag, flags, - name, this_parent_entry, -@@ -16741,8 +16765,6 @@ cooked_indexer::make_index (cutu_reader *reader) - if (!reader->comp_unit_die->has_children) - return; - index_dies (reader, reader->info_ptr, nullptr, false); -- -- handle_deferred_entries (); - } - - /* An implementation of quick_symbol_functions for the cooked DWARF --- -2.35.3 - diff --git a/gdb-symtab-resolve-deferred-entries-intra-shard-case.patch b/gdb-symtab-resolve-deferred-entries-intra-shard-case.patch deleted file mode 100644 index a18108a..0000000 --- a/gdb-symtab-resolve-deferred-entries-intra-shard-case.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 3b2f2b376bb80edadacc582161c362612947e3a6 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Sun, 24 Sep 2023 11:43:24 +0200 -Subject: [PATCH 09/13] [gdb/symtab] Resolve deferred entries, intra-shard case - -In patch "[gdb/symtab] Resolve deferred entries, inter-shard case" we've -solved the generic case of handling deferred entries. - -Now add an optimization that handles deferred entries with an intra-shard -dependency in the parallel for. - -Tested on x86_64-linux. ---- - gdb/dwarf2/cooked-index.c | 35 +++++++++++++++++++++++++++++++++++ - gdb/dwarf2/cooked-index.h | 7 +++++++ - gdb/dwarf2/read.c | 10 ++++++++++ - 3 files changed, 52 insertions(+) - -diff --git a/gdb/dwarf2/cooked-index.c b/gdb/dwarf2/cooked-index.c -index c096da57d62..ebed21d510c 100644 ---- a/gdb/dwarf2/cooked-index.c -+++ b/gdb/dwarf2/cooked-index.c -@@ -452,6 +452,7 @@ cooked_index_shard::wait (bool allow_quit) const - cooked_index::cooked_index (vec_type &&vec) - : m_vector (std::move (vec)) - { -+ /* Handle deferred entries, inter-cu case. */ - handle_deferred_entries (); - - for (auto &idx : m_vector) -@@ -659,6 +660,40 @@ cooked_index::maybe_write_index (dwarf2_per_bfd *per_bfd, - - /* See cooked-index.h. */ - -+const cooked_index_entry * -+cooked_index_shard::find_parent_deferred_entry -+ (const cooked_index_shard::deferred_entry &entry) const -+{ -+ return find_parent (entry.spec_offset); -+} -+ -+/* See cooked-index.h. */ -+ -+void -+cooked_index_shard::handle_deferred_entries () -+{ -+ for (auto it = m_deferred_entries->begin (); it != m_deferred_entries->end (); ) -+ { -+ const deferred_entry & deferred_entry = *it; -+ if (!parent_valid (deferred_entry.spec_offset)) -+ { -+ it++; -+ continue; -+ } -+ const cooked_index_entry *parent_entry -+ = find_parent_deferred_entry (deferred_entry); -+ if (parent_entry == &parent_map::deferred) -+ { -+ it++; -+ continue; -+ } -+ resolve_deferred_entry (deferred_entry, parent_entry); -+ it = m_deferred_entries->erase (it); -+ } -+} -+ -+/* See cooked-index.h. */ -+ - const cooked_index_entry * - cooked_index_shard::resolve_deferred_entry - (const deferred_entry &de, const cooked_index_entry *parent_entry) -diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h -index fa895233035..106e3091a90 100644 ---- a/gdb/dwarf2/cooked-index.h -+++ b/gdb/dwarf2/cooked-index.h -@@ -408,6 +408,13 @@ class cooked_index_shard - const cooked_index_entry *resolve_deferred_entry - (const deferred_entry &entry, const cooked_index_entry *parent_entry); - -+ /* Find the parent entry for deferred_entry ENTRY. */ -+ const cooked_index_entry *find_parent_deferred_entry -+ (const cooked_index_shard::deferred_entry &entry) const; -+ -+ /* Create cooked_index_entries for the deferred entries. */ -+ void handle_deferred_entries (); -+ - /* Mark parents in range [START, END] as valid . */ - void set_parent_valid (CORE_ADDR start, CORE_ADDR end) - { -diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c -index 09598e702bc..a97f738a54e 100644 ---- a/gdb/dwarf2/read.c -+++ b/gdb/dwarf2/read.c -@@ -4697,6 +4697,12 @@ class cooked_index_storage - m_index->defer_entry (de); - } - -+ /* Handle deferred entries, intra-cu case. */ -+ void handle_deferred_entries () -+ { -+ m_index->handle_deferred_entries (); -+ } -+ - /* Mark parents in range [START, END] as valid . */ - void set_parent_valid (CORE_ADDR start, CORE_ADDR end) - { -@@ -5183,6 +5189,10 @@ dwarf2_build_psymtabs_hard (dwarf2_per_objfile *per_objfile) - errors.push_back (std::move (except)); - } - } -+ -+ /* Handle deferred entries, intra-cu case. */ -+ thread_storage.handle_deferred_entries (); -+ - return result_type (thread_storage.release (), std::move (errors)); - }, task_size); - --- -2.35.3 - diff --git a/gdb-symtab-work-around-gas-pr28629.patch b/gdb-symtab-work-around-gas-pr28629.patch deleted file mode 100644 index 9bcab94..0000000 --- a/gdb-symtab-work-around-gas-pr28629.patch +++ /dev/null @@ -1,278 +0,0 @@ -From 1b878333913343630472f89b4bc42f51b1619308 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Wed, 1 Nov 2023 00:33:12 +0100 -Subject: [PATCH 1/2] [gdb/symtab] Work around gas PR28629 - -When running test-case gdb.tui/tui-layout-asm-short-prog.exp on AlmaLinux 9.2 -ppc64le, I run into: -... -FAIL: gdb.tui/tui-layout-asm-short-prog.exp: check asm box contents -... - -The problem is that we get: -... - 7 [ No Assembly Available ] -... -because tui_get_begin_asm_address doesn't succeed. - -In more detail, tui_get_begin_asm_address calls: -... - find_line_pc (sal.symtab, sal.line, &addr); -... -with: -... -(gdb) p *sal.symtab -$5 = {next = 0x130393c0, m_compunit = 0x130392f0, m_linetable = 0x0, - filename = "tui-layout-asm-short-prog.S", - filename_for_id = "$gdb/build/gdb/testsuite/tui-layout-asm-short-prog.S", - m_language = language_asm, fullname = 0x0} -(gdb) p sal.line -$6 = 1 -... - -The problem is the filename_for_id which is the source file prefixed with the -compilation dir rather than the source dir. - -This is due to faulty debug info generated by gas, PR28629: -... - <1a> DW_AT_name : tui-layout-asm-short-prog.S - <1e> DW_AT_comp_dir : $gdb/build/gdb/testsuite - <22> DW_AT_producer : GNU AS 2.35.2 -... - -The DW_AT_name is relative, and it's relative to the DW_AT_comp_dir entry, -making the effective name $gdb/build/gdb/testsuite/tui-layout-asm-short-prog.S. - -The bug is fixed starting version 2.38, where we get instead: -... - <1a> DW_AT_name : - $gdb/src/gdb/testsuite/gdb.tui/tui-layout-asm-short-prog.S - <1e> DW_AT_comp_dir : $gdb/build/gdb/testsuite - <22> DW_AT_producer : GNU AS 2.38 -... - -Work around the faulty debug info by constructing the filename_for_id using -the second directory from the directory table in the .debug_line header: -... - The Directory Table (offset 0x22, lines 2, columns 1): - Entry Name - 0 $gdb/build/gdb/testsuite - 1 $gdb/src/gdb/testsuite/gdb.tui -... - -Note that the used gas contains a backport of commit 3417bfca676 ("GAS: -DWARF-5: Ensure that the 0'th entry in the directory table contains the -current working directory."), because directory 0 is correct. With the -unpatched 2.35.2 release the directory 0 entry is incorrect: it's a copy of -entry 1. - -Add a dwarf assembly test-case that reflects the debug info as generated by -unpatched gas 2.35.2. - -Tested on x86_64-linux. - -Approved-By: Tom Tromey ---- - gdb/dwarf2/cu.c | 1 + - gdb/dwarf2/cu.h | 1 + - gdb/dwarf2/read.c | 37 +++++++- - .../gdb.dwarf2/dw2-gas-workaround.exp | 92 +++++++++++++++++++ - 4 files changed, 130 insertions(+), 1 deletion(-) - create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-gas-workaround.exp - -diff --git a/gdb/dwarf2/cu.c b/gdb/dwarf2/cu.c -index a908ec908cd..f9b05dfc709 100644 ---- a/gdb/dwarf2/cu.c -+++ b/gdb/dwarf2/cu.c -@@ -40,6 +40,7 @@ dwarf2_cu::dwarf2_cu (dwarf2_per_cu_data *per_cu, - producer_is_icc_lt_14 (false), - producer_is_codewarrior (false), - producer_is_clang (false), -+ producer_is_gas_lt_2_38 (false), - producer_is_gas_2_39 (false), - processing_has_namespace_info (false), - load_all_dies (false) -diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h -index 6c611710503..ef8db480e3f 100644 ---- a/gdb/dwarf2/cu.h -+++ b/gdb/dwarf2/cu.h -@@ -265,6 +265,7 @@ struct dwarf2_cu - bool producer_is_icc_lt_14 : 1; - bool producer_is_codewarrior : 1; - bool producer_is_clang : 1; -+ bool producer_is_gas_lt_2_38 : 1; - bool producer_is_gas_2_39 : 1; - - /* When true, the file that we're processing is known to have -diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c -index fc4667b782f..50fa302b43a 100644 ---- a/gdb/dwarf2/read.c -+++ b/gdb/dwarf2/read.c -@@ -147,6 +147,8 @@ static int dwarf2_locexpr_block_index; - static int dwarf2_loclist_block_index; - static int ada_block_index; - -+static bool producer_is_gas_lt_2_38 (struct dwarf2_cu *cu); -+ - /* Size of .debug_loclists section header for 32-bit DWARF format. */ - #define LOCLIST_HEADER_SIZE32 12 - -@@ -7665,6 +7667,27 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu) - - file_and_directory &fnd = find_file_and_directory (die, cu); - -+ /* GAS supports generating dwarf-5 info starting version 2.35. Versions -+ 2.35-2.37 generate an incorrect CU name attribute: it's relative, -+ implicitly prefixing it with the compilation dir. Work around this by -+ prefixing it with the source dir instead. */ -+ if (cu->header.version == 5 && !IS_ABSOLUTE_PATH (fnd.get_name ()) -+ && producer_is_gas_lt_2_38 (cu)) -+ { -+ attr = dwarf2_attr (die, DW_AT_stmt_list, cu); -+ if (attr != nullptr && attr->form_is_unsigned ()) -+ { -+ sect_offset line_offset = (sect_offset) attr->as_unsigned (); -+ line_header_up lh = dwarf_decode_line_header (line_offset, cu, -+ fnd.get_comp_dir ()); -+ if (lh->version == 5 && lh->is_valid_file_index (1)) -+ { -+ std::string dir = lh->include_dir_at (1); -+ fnd.set_comp_dir (std::move (dir)); -+ } -+ } -+ } -+ - cu->start_compunit_symtab (fnd.get_name (), fnd.intern_comp_dir (objfile), - lowpc); - -@@ -11427,7 +11450,10 @@ check_producer (struct dwarf2_cu *cu) - else if (producer_is_clang (cu->producer, &major, &minor)) - cu->producer_is_clang = true; - else if (producer_is_gas (cu->producer, &major, &minor)) -- cu->producer_is_gas_2_39 = major == 2 && minor == 39; -+ { -+ cu->producer_is_gas_lt_2_38 = major < 2 || (major == 2 && minor < 38); -+ cu->producer_is_gas_2_39 = major == 2 && minor == 39; -+ } - else - { - /* For other non-GCC compilers, expect their behavior is DWARF version -@@ -11463,6 +11489,15 @@ producer_is_codewarrior (struct dwarf2_cu *cu) - return cu->producer_is_codewarrior; - } - -+static bool -+producer_is_gas_lt_2_38 (struct dwarf2_cu *cu) -+{ -+ if (!cu->checked_producer) -+ check_producer (cu); -+ -+ return cu->producer_is_gas_lt_2_38; -+} -+ - static bool - producer_is_gas_2_39 (struct dwarf2_cu *cu) - { -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-gas-workaround.exp b/gdb/testsuite/gdb.dwarf2/dw2-gas-workaround.exp -new file mode 100644 -index 00000000000..ca2b10f23b3 ---- /dev/null -+++ b/gdb/testsuite/gdb.dwarf2/dw2-gas-workaround.exp -@@ -0,0 +1,92 @@ -+# Copyright 2023 Free Software Foundation, Inc. -+ -+# 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 . -+ -+# Test line number information in various configurations. -+ -+load_lib dwarf.exp -+ -+# This test can only be run on targets which support DWARF-2 and use gas. -+require dwarf2_support -+ -+standard_testfile dw2-lines.c -dw2.S -+ -+with_shared_gdb { -+ set func_info_vars [get_func_info bar] -+} -+ -+# Helper function. -+proc line_for { l } { -+ global srcfile -+ set line [gdb_get_line_number "$l:" $srcfile] -+ return [expr $line + 1] -+} -+ -+set asm_file [standard_output_file $srcfile2] -+Dwarf::assemble $asm_file { -+ declare_labels Llines -+ global srcdir subdir srcfile objdir -+ global func_info_vars -+ foreach var $func_info_vars { -+ global $var -+ } -+ -+ cu { version 5 } { -+ compile_unit { -+ {language @DW_LANG_Mips_Assembler} -+ {name $srcfile} -+ {comp_dir $objdir} -+ {stmt_list $Llines DW_FORM_sec_offset} -+ {producer "GNU AS 2.35.2"} -+ } { -+ subprogram { -+ {external 1 flag} -+ {name bar} -+ {low_pc $bar_start addr} -+ {high_pc "$bar_start + $bar_len" addr} -+ } -+ } -+ } -+ -+ lines [list version 5] Llines { -+ set diridx1 [include_dir "${srcdir}/${subdir}"] -+ set diridx2 [include_dir "${srcdir}/${subdir}"] -+ file_name "$srcfile" $diridx1 -+ file_name "$srcfile" $diridx2 -+ -+ program { -+ DW_LNE_set_address bar_label -+ line [line_for bar_label] -+ DW_LNS_copy -+ -+ DW_LNE_set_address bar_label_2 -+ DW_LNE_end_sequence -+ } -+ } -+} -+ -+if { [prepare_for_testing "failed to prepare" ${testfile} \ -+ [list $srcfile $asm_file] {nodebug}] } { -+ return -1 -+} -+ -+gdb_test_no_output "set debug symtab-create 1" -+gdb_test_multiple "ptype bar" "" { -+ -re -wrap "$objdir.*" { -+ fail $gdb_test_name -+ } -+ -re -wrap "" { -+ pass $gdb_test_name -+ } -+} - -base-commit: d9951c3c9ea2e542d071710e9706ed505046fe36 --- -2.35.3 - diff --git a/gdb-symtab-work-around-pr-gas-29517-dwarf2-case.patch b/gdb-symtab-work-around-pr-gas-29517-dwarf2-case.patch deleted file mode 100644 index be57664..0000000 --- a/gdb-symtab-work-around-pr-gas-29517-dwarf2-case.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 582fc35843fdf71b82d645d83d2903e2546cc21a Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Wed, 1 May 2024 15:10:50 +0200 -Subject: [PATCH 2/2] [gdb/symtab] Work around PR gas/29517, dwarf2 case - -In commit 1d45d90934b ("[gdb/symtab] Work around PR gas/29517") we added a -workaround for PR gas/29517. - -The problem is present in gas version 2.39, and fixed in 2.40, so the -workaround is only active for gas version == 2.39. - -However, the problem in gas is only fixed for dwarf version >= 3, which -supports DW_TAG_unspecified_type. - -Fix this by also activating the workaround for dwarf version == 2. - -Tested on x86_64-linux. - -PR symtab/31689 -https://sourceware.org/bugzilla/show_bug.cgi?id=31689 ---- - gdb/dwarf2/read.c | 5 +++- - .../gdb.dwarf2/dw2-unspecified-type-foo.c | 7 ++++++ - .../gdb.dwarf2/dw2-unspecified-type.c | 3 ++- - .../gdb.dwarf2/dw2-unspecified-type.exp | 23 ++++++++++++++++++- - 4 files changed, 35 insertions(+), 3 deletions(-) - -diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c -index 761437f6631..fc4667b782f 100644 ---- a/gdb/dwarf2/read.c -+++ b/gdb/dwarf2/read.c -@@ -14646,10 +14646,13 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu) - - type = die_type (die, cu); - -+ /* PR gas/29517 occurs in 2.39, and is fixed in 2.40, but it's only fixed -+ for dwarf version >= 3 which supports DW_TAG_unspecified_type. */ - if (type->code () == TYPE_CODE_VOID - && !type->is_stub () - && die->child == nullptr -- && producer_is_gas_2_39 (cu)) -+ && (cu->per_cu->version () == 2 -+ || producer_is_gas_2_39 (cu))) - { - /* Work around PR gas/29517, pretend we have an DW_TAG_unspecified_type - return type. */ -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type-foo.c b/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type-foo.c -index 164e781c9f0..bcf525a4d2e 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type-foo.c -+++ b/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type-foo.c -@@ -21,3 +21,10 @@ foo (void) - asm ("foo_label: .globl foo_label"); - return 0; - } -+ -+int -+foo2 (void) -+{ -+ asm ("foo2_label: .globl foo2_label"); -+ return 0; -+} -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.c b/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.c -index e07d9517ff2..9e600f9dcce 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.c -+++ b/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.c -@@ -16,6 +16,7 @@ - along with this program. If not, see . */ - - extern int foo (void); -+extern int foo2 (void); - - int - bar (void) -@@ -27,6 +28,6 @@ bar (void) - int - main (void) - { -- int res = foo () + bar (); -+ int res = foo () + bar () + foo2 (); - return res; - } -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.exp b/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.exp -index a6f2a57e33e..947246ba44d 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.exp -+++ b/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.exp -@@ -34,11 +34,19 @@ lassign $bar_res \ - bar_start bar_len - set bar_end "$bar_start + $bar_len" - -+set foo2_res \ -+ [function_range foo2 \ -+ [list ${srcdir}/${subdir}/$srcfile ${srcdir}/${subdir}/$srcfile2]] -+lassign $foo2_res \ -+ foo2_start foo2_len -+set foo2_end "$foo2_start + $foo2_len" -+ - # Create the DWARF. - set asm_file [standard_output_file $srcfile3] - Dwarf::assemble $asm_file { - global foo_start foo_end - global bar_start bar_end -+ global foo2_start foo2_end - declare_labels unspecified_type_label - - cu {} { -@@ -68,6 +76,19 @@ Dwarf::assemble $asm_file { - } - } - } -+ -+ cu { version 2 } { -+ compile_unit { -+ {language @DW_LANG_Mips_Assembler} -+ {producer "GNU AS 2.40.0"} -+ } { -+ DW_TAG_subprogram { -+ {name foo2} -+ {low_pc $foo2_start addr} -+ {high_pc $foo2_end addr} -+ } -+ } -+ } - } - - if [prepare_for_testing "failed to prepare" $testfile \ -@@ -79,7 +100,7 @@ if ![runto_main] { - return -1 - } - --foreach f {foo bar} { -+foreach f {foo bar foo2} { - # Print the function type. Return type should be stub type, which is printed - # as void. - gdb_test "ptype $f" "type = void \\(void\\)" --- -2.35.3 - diff --git a/gdb-symtab-work-around-pr-gas-29517.patch b/gdb-symtab-work-around-pr-gas-29517.patch deleted file mode 100644 index 54fc9de..0000000 --- a/gdb-symtab-work-around-pr-gas-29517.patch +++ /dev/null @@ -1,256 +0,0 @@ -From 7a2731d9d1c0926d22905b9d07e32a7b63c43b34 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Thu, 28 Sep 2023 13:55:07 +0200 -Subject: [PATCH 57/65] Work around PR gas/29517 - -When using glibc debuginfo generated with gas 2.39, we run into PR gas/29517: -... -$ gdb -q -batch a.out -ex start -ex "p (char *)strstr (\"haha\", \"ah\")" -Temporary breakpoint 1 at 0x40051b: file hello.c, line 6. - -Temporary breakpoint 1, main () at hello.c:6 -6 printf ("hello\n"); -Invalid cast. -... -while without glibc debuginfo installed we get the expected result: -... -$n = 0x7ffff7daa1b1 "aha" -... -and likewise with glibc debuginfo generated with gas 2.40. - -The strstr ifunc resolves to __strstr_sse2_unaligned. The problem is that gas -generates dwarf that states that the return type is void: -... -<1><3e1e58>: Abbrev Number: 2 (DW_TAG_subprogram) - <3e1e59> DW_AT_name : __strstr_sse2_unaligned - <3e1e5d> DW_AT_external : 1 - <3e1e5e> DW_AT_low_pc : 0xbbd2e - <3e1e66> DW_AT_high_pc : 0xbc1c3 -... -while the return type should be a DW_TAG_unspecified_type, as is the case -with gas 2.40. - -We can still use the workaround of casting to another function type for both -__strstr_sse2_unaligned: -... -(gdb) p ((char * (*) (const char *, const char *))__strstr_sse2_unaligned) \ - ("haha", "ah") -$n = 0x7ffff7daa211 "aha" -... -and strstr (which requires using *strstr to dereference the ifunc before we -cast): -... -gdb) p ((char * (*) (const char *, const char *))*strstr) ("haha", "ah") -$n = 0x7ffff7daa251 "aha" -... -but that's a bit cumbersome to use. - -Work around this in the dwarf reader, such that we have instead: -... -(gdb) p (char *)strstr ("haha", "ah") -$n = 0x7ffff7daa1b1 "aha" -... - -This also requires fixing producer_is_gcc to stop returning true for -producer "GNU AS 2.39.0". - -Tested on x86_64-linux. - -PR symtab/30911 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30911 ---- - gdb/dwarf2/cu.c | 1 + - gdb/dwarf2/cu.h | 1 + - gdb/dwarf2/read.c | 23 ++++++++++++ - gdb/producer.c | 8 ++++- - .../gdb.dwarf2/dw2-unspecified-type.c | 9 ++++- - .../gdb.dwarf2/dw2-unspecified-type.exp | 36 +++++++++++++++---- - 6 files changed, 69 insertions(+), 9 deletions(-) - -diff --git a/gdb/dwarf2/cu.c b/gdb/dwarf2/cu.c -index 89de40daab0..a908ec908cd 100644 ---- a/gdb/dwarf2/cu.c -+++ b/gdb/dwarf2/cu.c -@@ -40,6 +40,7 @@ dwarf2_cu::dwarf2_cu (dwarf2_per_cu_data *per_cu, - producer_is_icc_lt_14 (false), - producer_is_codewarrior (false), - producer_is_clang (false), -+ producer_is_gas_2_39 (false), - processing_has_namespace_info (false), - load_all_dies (false) - { -diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h -index 0c15d8b02db..6c611710503 100644 ---- a/gdb/dwarf2/cu.h -+++ b/gdb/dwarf2/cu.h -@@ -265,6 +265,7 @@ struct dwarf2_cu - bool producer_is_icc_lt_14 : 1; - bool producer_is_codewarrior : 1; - bool producer_is_clang : 1; -+ bool producer_is_gas_2_39 : 1; - - /* When true, the file that we're processing is known to have - debugging info for C++ namespaces. GCC 3.3.x did not produce -diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c -index a5c48baa6f8..e5e557c17d3 100644 ---- a/gdb/dwarf2/read.c -+++ b/gdb/dwarf2/read.c -@@ -11426,6 +11426,8 @@ check_producer (struct dwarf2_cu *cu) - cu->producer_is_codewarrior = true; - else if (producer_is_clang (cu->producer, &major, &minor)) - cu->producer_is_clang = true; -+ else if (startswith (cu->producer, "GNU AS 2.39.0")) -+ cu->producer_is_gas_2_39 = true; - else - { - /* For other non-GCC compilers, expect their behavior is DWARF version -@@ -11461,6 +11463,15 @@ producer_is_codewarrior (struct dwarf2_cu *cu) - return cu->producer_is_codewarrior; - } - -+static bool -+producer_is_gas_2_39 (struct dwarf2_cu *cu) -+{ -+ if (!cu->checked_producer) -+ check_producer (cu); -+ -+ return cu->producer_is_gas_2_39; -+} -+ - /* Return the accessibility of DIE, as given by DW_AT_accessibility. - If that attribute is not available, return the appropriate - default. */ -@@ -14635,6 +14646,18 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu) - - type = die_type (die, cu); - -+ if (type->code () == TYPE_CODE_VOID -+ && !type->is_stub () -+ && die->child == nullptr -+ && producer_is_gas_2_39 (cu)) -+ { -+ /* Work around PR gas/29517, pretend we have an DW_TAG_unspecified_type -+ return type. */ -+ type = (type_allocator (cu->per_objfile->objfile, cu->lang ()) -+ .new_type (TYPE_CODE_VOID, 0, nullptr)); -+ type->set_is_stub (true); -+ } -+ - /* The die_type call above may have already set the type for this DIE. */ - ftype = get_die_type (die, cu); - if (ftype) -diff --git a/gdb/producer.c b/gdb/producer.c -index 655eb971283..9fcf749e3d4 100644 ---- a/gdb/producer.c -+++ b/gdb/producer.c -@@ -54,13 +54,19 @@ producer_is_gcc (const char *producer, int *major, int *minor) - if (minor == NULL) - minor = &min; - -+ /* Skip GNU. */ -+ cs = &producer[strlen ("GNU ")]; -+ -+ /* Bail out for GNU AS. */ -+ if (startswith (cs, "AS ")) -+ return 0; -+ - /* Skip any identifier after "GNU " - such as "C11" "C++" or "Java". - A full producer string might look like: - "GNU C 4.7.2" - "GNU Fortran 4.8.2 20140120 (Red Hat 4.8.2-16) -mtune=generic ..." - "GNU C++14 5.0.0 20150123 (experimental)" - */ -- cs = &producer[strlen ("GNU ")]; - while (*cs && !isspace (*cs)) - cs++; - if (*cs && isspace (*cs)) -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.c b/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.c -index 1df09214d4a..e07d9517ff2 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.c -+++ b/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.c -@@ -17,9 +17,16 @@ - - extern int foo (void); - -+int -+bar (void) -+{ -+ asm ("bar_label: .globl bar_label"); -+ return 0; -+} -+ - int - main (void) - { -- int res = foo (); -+ int res = foo () + bar (); - return res; - } -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.exp b/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.exp -index 5fa6ee544b2..a6f2a57e33e 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.exp -+++ b/gdb/testsuite/gdb.dwarf2/dw2-unspecified-type.exp -@@ -27,10 +27,18 @@ lassign $foo_res \ - foo_start foo_len - set foo_end "$foo_start + $foo_len" - -+set bar_res \ -+ [function_range bar \ -+ [list ${srcdir}/${subdir}/$srcfile ${srcdir}/${subdir}/$srcfile2]] -+lassign $bar_res \ -+ bar_start bar_len -+set bar_end "$bar_start + $bar_len" -+ - # Create the DWARF. - set asm_file [standard_output_file $srcfile3] - Dwarf::assemble $asm_file { - global foo_start foo_end -+ global bar_start bar_end - declare_labels unspecified_type_label - - cu {} { -@@ -45,7 +53,19 @@ Dwarf::assemble $asm_file { - {high_pc $foo_end addr} - {type :$unspecified_type_label} - } -+ } -+ } - -+ cu {} { -+ compile_unit { -+ {language @DW_LANG_Mips_Assembler} -+ {producer "GNU AS 2.39.0"} -+ } { -+ DW_TAG_subprogram { -+ {name bar} -+ {low_pc $bar_start addr} -+ {high_pc $bar_end addr} -+ } - } - } - } -@@ -59,12 +79,14 @@ if ![runto_main] { - return -1 - } - --# Print the function type. Return type should be stub type, which is printed --# as void. --gdb_test "ptype foo" "type = void \\(void\\)" -+foreach f {foo bar} { -+ # Print the function type. Return type should be stub type, which is printed -+ # as void. -+ gdb_test "ptype $f" "type = void \\(void\\)" - --# Call the function, casting the function to the correct function type. --gdb_test "p ((int (*) ()) foo) ()" " = 0" -+ # Call the function, casting the function to the correct function type. -+ gdb_test "p ((int (*) ()) $f) ()" " = 0" - --# Call the function, casting the function result to the correct type. --gdb_test "p (int) foo ()" " = 0" -+ # Call the function, casting the function result to the correct type. -+ gdb_test "p (int) $f ()" " = 0" -+} --- -2.35.3 - diff --git a/gdb-symtab-workaround-pr-gas-31115.patch b/gdb-symtab-workaround-pr-gas-31115.patch deleted file mode 100644 index d5869cf..0000000 --- a/gdb-symtab-workaround-pr-gas-31115.patch +++ /dev/null @@ -1,122 +0,0 @@ -From d25e3f4ed05c3a6c207263d7e532f829860b83f0 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Wed, 20 Mar 2024 09:57:49 +0100 -Subject: [PATCH 1/7] [gdb/symtab] Workaround PR gas/31115 - -On arm-linux, with gas 2.40, I run into: -... -(gdb) x /i main+8^M - 0x4e1 : vrhadd.u16 d14, d14, d31^M -(gdb) FAIL: gdb.arch/pr25124.exp: disassemble thumb instruction (1st try) -... - -This is a regression due to PR gas/31115, which makes gas produce a low_pc -with the thumb bit set (0x4d8 & 0x1): -... - <1><24>: Abbrev Number: 2 (DW_TAG_subprogram) - <25> DW_AT_name : main - <29> DW_AT_external : 1 - <29> DW_AT_type : <0x2f> - <2a> DW_AT_low_pc : 0x4d9 - <2e> DW_AT_high_pc : 12 -... - -The regression was introduced in 2.39, and is also present in 2.40 and 2.41, -and hasn't been fixed yet. - -Work around this in read_func_scope, by using gdbarch_addr_bits_remove on -low_pc and high_pc. - -Tested on arm-linux and x86_64-linux. - -PR tdep/31453 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31453 ---- - gdb/dwarf2/cu.c | 1 + - gdb/dwarf2/cu.h | 1 + - gdb/dwarf2/read.c | 22 ++++++++++++++++++++++ - 3 files changed, 24 insertions(+) - -diff --git a/gdb/dwarf2/cu.c b/gdb/dwarf2/cu.c -index f9b05dfc709..7f89500effd 100644 ---- a/gdb/dwarf2/cu.c -+++ b/gdb/dwarf2/cu.c -@@ -42,6 +42,7 @@ dwarf2_cu::dwarf2_cu (dwarf2_per_cu_data *per_cu, - producer_is_clang (false), - producer_is_gas_lt_2_38 (false), - producer_is_gas_2_39 (false), -+ producer_is_gas_ge_2_40 (false), - processing_has_namespace_info (false), - load_all_dies (false) - { -diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h -index ef8db480e3f..1b02f89ed2f 100644 ---- a/gdb/dwarf2/cu.h -+++ b/gdb/dwarf2/cu.h -@@ -267,6 +267,7 @@ struct dwarf2_cu - bool producer_is_clang : 1; - bool producer_is_gas_lt_2_38 : 1; - bool producer_is_gas_2_39 : 1; -+ bool producer_is_gas_ge_2_40 : 1; - - /* When true, the file that we're processing is known to have - debugging info for C++ namespaces. GCC 3.3.x did not produce -diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c -index a4f982962ae..8f2d7a34aef 100644 ---- a/gdb/dwarf2/read.c -+++ b/gdb/dwarf2/read.c -@@ -148,6 +148,7 @@ static int dwarf2_loclist_block_index; - static int ada_block_index; - - static bool producer_is_gas_lt_2_38 (struct dwarf2_cu *cu); -+static bool producer_is_gas_ge_2_39 (struct dwarf2_cu *cu); - - /* Size of .debug_loclists section header for 32-bit DWARF format. */ - #define LOCLIST_HEADER_SIZE32 12 -@@ -10223,6 +10224,15 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) - lowpc = per_objfile->relocate (unrel_low); - highpc = per_objfile->relocate (unrel_high); - -+ if (gdbarch_bfd_arch_info (gdbarch)->arch == bfd_arch_arm -+ && producer_is_gas_ge_2_39 (cu)) -+ { -+ /* Gas version 2.39 produces DWARF for a Thumb subprogram with a low_pc -+ attribute with the thumb bit set (PR gas/31115). Work around this. */ -+ lowpc = gdbarch_addr_bits_remove (gdbarch, lowpc); -+ highpc = gdbarch_addr_bits_remove (gdbarch, highpc); -+ } -+ - /* If we have any template arguments, then we must allocate a - different sort of symbol. */ - for (child_die = die->child; child_die; child_die = child_die->sibling) -@@ -11507,6 +11517,7 @@ check_producer (struct dwarf2_cu *cu) - { - cu->producer_is_gas_lt_2_38 = major < 2 || (major == 2 && minor < 38); - cu->producer_is_gas_2_39 = major == 2 && minor == 39; -+ cu->producer_is_gas_ge_2_40 = major > 2 || (major == 2 && minor >= 40); - } - else - { -@@ -11561,6 +11572,17 @@ producer_is_gas_2_39 (struct dwarf2_cu *cu) - return cu->producer_is_gas_2_39; - } - -+/* Return true if CU is produced by GAS 2.39 or later. */ -+ -+static bool -+producer_is_gas_ge_2_39 (struct dwarf2_cu *cu) -+{ -+ if (!cu->checked_producer) -+ check_producer (cu); -+ -+ return cu->producer_is_gas_2_39 || cu->producer_is_gas_ge_2_40; -+} -+ - /* Return the accessibility of DIE, as given by DW_AT_accessibility. - If that attribute is not available, return the appropriate - default. */ - -base-commit: c79ecacd3f75cfb0ec1a3afc49ca3f30b1759009 --- -2.35.3 - diff --git a/gdb-tdep-backport-i386_canonicalize_syscall-rewrite-.patch b/gdb-tdep-backport-i386_canonicalize_syscall-rewrite-.patch new file mode 100644 index 0000000..56bb646 --- /dev/null +++ b/gdb-tdep-backport-i386_canonicalize_syscall-rewrite-.patch @@ -0,0 +1,192 @@ +From 32c2e500525b91b2771022252f79e1c5c29ddf48 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Thu, 13 Mar 2025 09:39:51 +0100 +Subject: [PATCH 2/2] [gdb/tdep] Backport i386_canonicalize_syscall rewrite to + gdb-16-branch + +Commit fbfb29b304e ("[gdb/tdep] Rewrite i386_canonicalize_syscall") fixes +PR32770, which reproduces on the gdb-16-branch, but the commit is not ideal +for backporting because it completely rewrites i386_canonicalize_syscall. + +Instead, this is a version of the patch that adds a single line entry for each +syscall value for which i386_canonicalize_syscall gives a different result +with and without the patch. + +Consequently, the two versions give identical results. I've checked this for +syscalls 0 to 466. + +Tested on x86_64-linux with target board unix/-m32, on top of gdb-16-branch. + +PR tdep/32770 +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32770 +--- + gdb/i386-linux-tdep.c | 153 +++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 152 insertions(+), 1 deletion(-) + +diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c +index a78f03fac8d..b0ca8694ba5 100644 +--- a/gdb/i386-linux-tdep.c ++++ b/gdb/i386-linux-tdep.c +@@ -376,7 +376,158 @@ i386_all_but_ip_registers_record (struct regcache *regcache) + static enum gdb_syscall + i386_canonicalize_syscall (int syscall) + { +- enum { i386_syscall_max = 499 }; ++ enum { i386_syscall_max = 466 }; ++ ++ switch (syscall) ++ { ++ case 359 /* socket */: return gdb_sys_socket; ++ case 360 /* socketpair */: return gdb_sys_socketpair; ++ case 361 /* bind */: return gdb_sys_bind; ++ case 362 /* connect */: return gdb_sys_connect; ++ case 363 /* listen */: return gdb_sys_listen; ++ case 365 /* getsockopt */: return gdb_sys_getsockopt; ++ case 366 /* setsockopt */: return gdb_sys_setsockopt; ++ case 367 /* getsockname */: return gdb_sys_getsockname; ++ case 368 /* getpeername */: return gdb_sys_getpeername; ++ case 369 /* sendto */: return gdb_sys_sendto; ++ case 370 /* sendmsg */: return gdb_sys_sendmsg; ++ case 371 /* recvfrom */: return gdb_sys_recvfrom; ++ case 372 /* recvmsg */: return gdb_sys_recvmsg; ++ case 373 /* shutdown */: return gdb_sys_shutdown; ++ case 393 /* semget */: return gdb_sys_semget; ++ case 394 /* semctl */: return gdb_sys_semctl; ++ case 395 /* shmget */: return gdb_sys_shmget; ++ case 396 /* shmctl */: return gdb_sys_shmctl; ++ case 397 /* shmat */: return gdb_sys_shmat; ++ case 398 /* shmdt */: return gdb_sys_shmdt; ++ case 399 /* msgget */: return gdb_sys_msgget; ++ case 400 /* msgsnd */: return gdb_sys_msgsnd; ++ case 401 /* msgrcv */: return gdb_sys_msgrcv; ++ case 402 /* msgctl */: return gdb_sys_msgctl; ++ case 420 /* semtimedop_time64 */: return gdb_sys_semtimedop; ++ ++ case 320 /* utimensat */: return gdb_sys_no_syscall; ++ case 321 /* signalfd */: return gdb_sys_no_syscall; ++ case 322 /* timerfd_create */: return gdb_sys_no_syscall; ++ case 323 /* eventfd */: return gdb_sys_no_syscall; ++ case 325 /* timerfd_settime */: return gdb_sys_no_syscall; ++ case 326 /* timerfd_gettime */: return gdb_sys_no_syscall; ++ case 327 /* signalfd4 */: return gdb_sys_no_syscall; ++ case 333 /* preadv */: return gdb_sys_no_syscall; ++ case 334 /* pwritev */: return gdb_sys_no_syscall; ++ case 335 /* rt_tgsigqueueinfo */: return gdb_sys_no_syscall; ++ case 336 /* perf_event_open */: return gdb_sys_no_syscall; ++ case 337 /* recvmmsg */: return gdb_sys_no_syscall; ++ case 338 /* fanotify_init */: return gdb_sys_no_syscall; ++ case 339 /* fanotify_mark */: return gdb_sys_no_syscall; ++ case 340 /* prlimit64 */: return gdb_sys_no_syscall; ++ case 341 /* name_to_handle_at */: return gdb_sys_no_syscall; ++ case 342 /* open_by_handle_at */: return gdb_sys_no_syscall; ++ case 343 /* clock_adjtime */: return gdb_sys_no_syscall; ++ case 344 /* syncfs */: return gdb_sys_no_syscall; ++ case 345 /* sendmmsg */: return gdb_sys_no_syscall; ++ case 346 /* setns */: return gdb_sys_no_syscall; ++ case 347 /* process_vm_readv */: return gdb_sys_no_syscall; ++ case 348 /* process_vm_writev */: return gdb_sys_no_syscall; ++ case 349 /* kcmp */: return gdb_sys_no_syscall; ++ case 350 /* finit_module */: return gdb_sys_no_syscall; ++ case 351 /* sched_setattr */: return gdb_sys_no_syscall; ++ case 352 /* sched_getattr */: return gdb_sys_no_syscall; ++ case 353 /* renameat2 */: return gdb_sys_no_syscall; ++ case 354 /* seccomp */: return gdb_sys_no_syscall; ++ case 356 /* memfd_create */: return gdb_sys_no_syscall; ++ case 357 /* bpf */: return gdb_sys_no_syscall; ++ case 358 /* execveat */: return gdb_sys_no_syscall; ++ case 364 /* accept4 */: return gdb_sys_no_syscall; ++ case 374 /* userfaultfd */: return gdb_sys_no_syscall; ++ case 375 /* membarrier */: return gdb_sys_no_syscall; ++ case 376 /* mlock2 */: return gdb_sys_no_syscall; ++ case 377 /* copy_file_range */: return gdb_sys_no_syscall; ++ case 378 /* preadv2 */: return gdb_sys_no_syscall; ++ case 379 /* pwritev2 */: return gdb_sys_no_syscall; ++ case 380 /* pkey_mprotect */: return gdb_sys_no_syscall; ++ case 381 /* pkey_alloc */: return gdb_sys_no_syscall; ++ case 382 /* pkey_free */: return gdb_sys_no_syscall; ++ case 384 /* arch_prctl */: return gdb_sys_no_syscall; ++ case 385 /* io_pgetevents */: return gdb_sys_no_syscall; ++ case 386 /* rseq */: return gdb_sys_no_syscall; ++ case 404 /* clock_settime64 */: return gdb_sys_no_syscall; ++ case 405 /* clock_adjtime64 */: return gdb_sys_no_syscall; ++ case 406 /* clock_getres_time64 */: return gdb_sys_no_syscall; ++ case 407 /* clock_nanosleep_time64 */: return gdb_sys_no_syscall; ++ case 408 /* timer_gettime64 */: return gdb_sys_no_syscall; ++ case 409 /* timer_settime64 */: return gdb_sys_no_syscall; ++ case 410 /* timerfd_gettime64 */: return gdb_sys_no_syscall; ++ case 411 /* timerfd_settime64 */: return gdb_sys_no_syscall; ++ case 412 /* utimensat_time64 */: return gdb_sys_no_syscall; ++ case 413 /* pselect6_time64 */: return gdb_sys_no_syscall; ++ case 414 /* ppoll_time64 */: return gdb_sys_no_syscall; ++ case 416 /* io_pgetevents_time64 */: return gdb_sys_no_syscall; ++ case 417 /* recvmmsg_time64 */: return gdb_sys_no_syscall; ++ case 418 /* mq_timedsend_time64 */: return gdb_sys_no_syscall; ++ case 419 /* mq_timedreceive_time64 */: return gdb_sys_no_syscall; ++ case 421 /* rt_sigtimedwait_time64 */: return gdb_sys_no_syscall; ++ case 422 /* futex_time64 */: return gdb_sys_no_syscall; ++ case 423 /* sched_rr_get_interval_time64 */: return gdb_sys_no_syscall; ++ case 424 /* pidfd_send_signal */: return gdb_sys_no_syscall; ++ case 425 /* io_uring_setup */: return gdb_sys_no_syscall; ++ case 426 /* io_uring_enter */: return gdb_sys_no_syscall; ++ case 427 /* io_uring_register */: return gdb_sys_no_syscall; ++ case 428 /* open_tree */: return gdb_sys_no_syscall; ++ case 429 /* move_mount */: return gdb_sys_no_syscall; ++ case 430 /* fsopen */: return gdb_sys_no_syscall; ++ case 431 /* fsconfig */: return gdb_sys_no_syscall; ++ case 432 /* fsmount */: return gdb_sys_no_syscall; ++ case 433 /* fspick */: return gdb_sys_no_syscall; ++ case 434 /* pidfd_open */: return gdb_sys_no_syscall; ++ case 435 /* clone3 */: return gdb_sys_no_syscall; ++ case 436 /* close_range */: return gdb_sys_no_syscall; ++ case 437 /* openat2 */: return gdb_sys_no_syscall; ++ case 438 /* pidfd_getfd */: return gdb_sys_no_syscall; ++ case 439 /* faccessat2 */: return gdb_sys_no_syscall; ++ case 440 /* process_madvise */: return gdb_sys_no_syscall; ++ case 441 /* epoll_pwait2 */: return gdb_sys_no_syscall; ++ case 442 /* mount_setattr */: return gdb_sys_no_syscall; ++ case 443 /* quotactl_fd */: return gdb_sys_no_syscall; ++ case 444 /* landlock_create_ruleset */: return gdb_sys_no_syscall; ++ case 445 /* landlock_add_rule */: return gdb_sys_no_syscall; ++ case 446 /* landlock_restrict_self */: return gdb_sys_no_syscall; ++ case 447 /* memfd_secret */: return gdb_sys_no_syscall; ++ case 448 /* process_mrelease */: return gdb_sys_no_syscall; ++ case 449 /* futex_waitv */: return gdb_sys_no_syscall; ++ case 450 /* set_mempolicy_home_node */: return gdb_sys_no_syscall; ++ case 451 /* cachestat */: return gdb_sys_no_syscall; ++ case 452 /* fchmodat2 */: return gdb_sys_no_syscall; ++ case 453 /* map_shadow_stack */: return gdb_sys_no_syscall; ++ case 454 /* futex_wake */: return gdb_sys_no_syscall; ++ case 455 /* futex_wait */: return gdb_sys_no_syscall; ++ case 456 /* futex_requeue */: return gdb_sys_no_syscall; ++ case 457 /* statmount */: return gdb_sys_no_syscall; ++ case 458 /* listmount */: return gdb_sys_no_syscall; ++ case 459 /* lsm_get_self_attr */: return gdb_sys_no_syscall; ++ case 460 /* lsm_set_self_attr */: return gdb_sys_no_syscall; ++ case 461 /* lsm_list_modules */: return gdb_sys_no_syscall; ++ case 462 /* mseal */: return gdb_sys_no_syscall; ++ case 463 /* setxattrat */: return gdb_sys_no_syscall; ++ case 464 /* getxattrat */: return gdb_sys_no_syscall; ++ case 465 /* listxattrat */: return gdb_sys_no_syscall; ++ case 466 /* removexattrat */: return gdb_sys_no_syscall; ++ ++ case 222 /* unused */: return gdb_sys_no_syscall; ++ case 223 /* unused */: return gdb_sys_no_syscall; ++ case 251 /* unused */: return gdb_sys_no_syscall; ++ case 285 /* unused */: return gdb_sys_no_syscall; ++ case 387 /* unused */: return gdb_sys_no_syscall; ++ case 388 /* unused */: return gdb_sys_no_syscall; ++ case 389 /* unused */: return gdb_sys_no_syscall; ++ case 390 /* unused */: return gdb_sys_no_syscall; ++ case 391 /* unused */: return gdb_sys_no_syscall; ++ case 392 /* unused */: return gdb_sys_no_syscall; ++ case 415 /* unused */: return gdb_sys_no_syscall; ++ ++ default: ++ break; ++ } + + if (syscall <= i386_syscall_max) + return (enum gdb_syscall) syscall; +-- +2.43.0 + diff --git a/gdb-tdep-fix-arm-thumb2-hw-breakpoint.patch b/gdb-tdep-fix-arm-thumb2-hw-breakpoint.patch new file mode 100644 index 0000000..d0f7ca0 --- /dev/null +++ b/gdb-tdep-fix-arm-thumb2-hw-breakpoint.patch @@ -0,0 +1,264 @@ +From 64dc13a4571b4092726291f3ee30bf5c2166fa13 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Sat, 27 Jul 2024 10:05:20 +0200 +Subject: [PATCH 09/46] [gdb/tdep] Fix arm thumb2 hw breakpoint + +On an aarch64-linux system with 32-bit userland running in a chroot, and using +target board unix/mthumb I get: +... +(gdb) hbreak hbreak.c:27^M +Hardware assisted breakpoint 2 at 0x4004e2: file hbreak.c, line 27.^M +(gdb) PASS: gdb.base/hbreak.exp: hbreak +continue^M +Continuing.^M +Unexpected error setting breakpoint: Invalid argument.^M +(gdb) XFAIL: gdb.base/hbreak.exp: continue to break-at-exit after hbreak +... +due to this call in arm_linux_nat_target::low_prepare_to_resume: +... + if (ptrace (PTRACE_SETHBPREGS, pid, + (PTRACE_TYPE_ARG3) ((i << 1) + 1), &bpts[i].address) < 0) + perror_with_name (_("Unexpected error setting breakpoint")); +... + +This problem does not happen if instead we use a 4-byte aligned address. + +This may or may not be a kernel bug. + +Work around this by first using an inoffensive address bpts[i].address & ~0x7. + +Likewise in arm_target::low_prepare_to_resume, which fixes the same fail on +target board native-gdbserver/mthumb. + +While we're at it: +- use arm_hwbp_control_is_initialized in + arm_linux_nat_target::low_prepare_to_resume, +- handle the !arm_hwbp_control_is_initialized case explicitly, +- add missing '_()' in arm_target::low_prepare_to_resume, +- make error messages identical between arm_target::low_prepare_to_resume and + arm_linux_nat_target::low_prepare_to_resume, +- factor out sethbpregs_hwbp_address and sethbpregs_hwbp_control to + make the implementation more readable. + +Remove the tentative xfail added in d0af16d5a10 ("[gdb/testsuite] Add xfail in +gdb.base/hbreak.exp") by simply reverting the commit. + +Tested on arm-linux. + +Approved-By: Luis Machado +Tested-By: Luis Machado +--- + gdb/arm-linux-nat.c | 98 ++++++++++++++++++++++++++++++++++---- + gdbserver/linux-arm-low.cc | 65 ++++++++++++++++++++----- + 2 files changed, 141 insertions(+), 22 deletions(-) + +diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c +index ac53bed72d7..7b4faacd601 100644 +--- a/gdb/arm-linux-nat.c ++++ b/gdb/arm-linux-nat.c +@@ -876,6 +876,14 @@ arm_hwbp_control_is_enabled (arm_hwbp_control_t control) + return control & 0x1; + } + ++/* Is the breakpoint control value CONTROL initialized? */ ++ ++static int ++arm_hwbp_control_is_initialized (arm_hwbp_control_t control) ++{ ++ return control != 0; ++} ++ + /* Change a breakpoint control word so that it is in the disabled state. */ + static arm_hwbp_control_t + arm_hwbp_control_disable (arm_hwbp_control_t control) +@@ -1234,6 +1242,34 @@ arm_linux_nat_target::low_delete_thread (struct arch_lwp_info *arch_lwp) + xfree (arch_lwp); + } + ++/* For PID, set the address register of hardware breakpoint pair I to ++ ADDRESS. */ ++ ++static void ++sethbpregs_hwbp_address (int pid, int i, unsigned int address) ++{ ++ PTRACE_TYPE_ARG3 address_reg = (PTRACE_TYPE_ARG3) ((i << 1) + 1); ++ ++ errno = 0; ++ ++ if (ptrace (PTRACE_SETHBPREGS, pid, address_reg, &address) < 0) ++ perror_with_name (_("Unexpected error updating breakpoint address")); ++} ++ ++/* For PID, set the control register of hardware breakpoint pair I to ++ CONTROL. */ ++ ++static void ++sethbpregs_hwbp_control (int pid, int i, arm_hwbp_control_t control) ++{ ++ PTRACE_TYPE_ARG3 control_reg = (PTRACE_TYPE_ARG3) ((i << 1) + 2); ++ ++ errno = 0; ++ ++ if (ptrace (PTRACE_SETHBPREGS, pid, control_reg, &control) < 0) ++ perror_with_name (_("Unexpected error setting breakpoint control")); ++} ++ + /* Called when resuming a thread. + The hardware debug registers are updated when there is any change. */ + +@@ -1257,16 +1293,58 @@ arm_linux_nat_target::low_prepare_to_resume (struct lwp_info *lwp) + for (i = 0; i < arm_linux_get_hw_breakpoint_count (); i++) + if (arm_lwp_info->bpts_changed[i]) + { +- errno = 0; +- if (arm_hwbp_control_is_enabled (bpts[i].control)) +- if (ptrace (PTRACE_SETHBPREGS, pid, +- (PTRACE_TYPE_ARG3) ((i << 1) + 1), &bpts[i].address) < 0) +- perror_with_name (_("Unexpected error setting breakpoint")); +- +- if (bpts[i].control != 0) +- if (ptrace (PTRACE_SETHBPREGS, pid, +- (PTRACE_TYPE_ARG3) ((i << 1) + 2), &bpts[i].control) < 0) +- perror_with_name (_("Unexpected error setting breakpoint")); ++ unsigned int address = bpts[i].address; ++ arm_hwbp_control_t control = bpts[i].control; ++ ++ if (!arm_hwbp_control_is_initialized (control)) ++ { ++ /* Nothing to do. */ ++ } ++ else if (!arm_hwbp_control_is_enabled (control)) ++ { ++ /* Disable hardware breakpoint, just write the control ++ register. */ ++ sethbpregs_hwbp_control (pid, i, control); ++ } ++ else ++ { ++ /* We used to do here simply: ++ 1. address_reg = address ++ 2. control_reg = control ++ but the write to address_reg can fail for thumb2 instructions if ++ the address is not 4-byte aligned. ++ ++ It's not clear whether this is a kernel bug or not, partly ++ because PTRACE_SETHBPREGS is undocumented. ++ ++ The context is that we're using two ptrace calls to set the two ++ halves of a register pair. For each ptrace call, the kernel must ++ check the arguments, and return -1 and set errno appropriately if ++ something is wrong. One of the aspects that needs validation is ++ whether, in terms of hw_breakpoint_arch_parse, the breakpoint ++ address matches the breakpoint length. This aspect can only be ++ checked by looking in both registers, which only makes sense ++ once a pair is written in full. ++ ++ The problem is that the kernel checks this aspect after each ++ ptrace call, and consequently for the first call it may be ++ checking this aspect using a default or previous value for the ++ part of the pair not written by the call. A possible fix for ++ this would be to only check this aspect when writing the ++ control reg. ++ ++ Work around this by first using an inoffensive address, which is ++ guaranteed to hit the offset == 0 case in ++ hw_breakpoint_arch_parse. */ ++ unsigned int aligned_address = address & ~0x7U; ++ if (aligned_address != address) ++ { ++ sethbpregs_hwbp_address (pid, i, aligned_address); ++ sethbpregs_hwbp_control (pid, i, control); ++ } ++ sethbpregs_hwbp_address (pid, i, address); ++ sethbpregs_hwbp_control (pid, i, control); ++ } + + arm_lwp_info->bpts_changed[i] = 0; + } +diff --git a/gdbserver/linux-arm-low.cc b/gdbserver/linux-arm-low.cc +index eec4649b235..ee89949a2a2 100644 +--- a/gdbserver/linux-arm-low.cc ++++ b/gdbserver/linux-arm-low.cc +@@ -819,6 +819,34 @@ arm_target::low_new_fork (process_info *parent, process_info *child) + child_lwp_info->wpts_changed[i] = 1; + } + ++/* For PID, set the address register of hardware breakpoint pair I to ++ ADDRESS. */ ++ ++static void ++sethbpregs_hwbp_address (int pid, int i, unsigned int address) ++{ ++ PTRACE_TYPE_ARG3 address_reg = (PTRACE_TYPE_ARG3) ((i << 1) + 1); ++ ++ errno = 0; ++ ++ if (ptrace (PTRACE_SETHBPREGS, pid, address_reg, &address) < 0) ++ perror_with_name (_("Unexpected error updating breakpoint address")); ++} ++ ++/* For PID, set the control register of hardware breakpoint pair I to ++ CONTROL. */ ++ ++static void ++sethbpregs_hwbp_control (int pid, int i, arm_hwbp_control_t control) ++{ ++ PTRACE_TYPE_ARG3 control_reg = (PTRACE_TYPE_ARG3) ((i << 1) + 2); ++ ++ errno = 0; ++ ++ if (ptrace (PTRACE_SETHBPREGS, pid, control_reg, &control) < 0) ++ perror_with_name (_("Unexpected error setting breakpoint control")); ++} ++ + /* Called when resuming a thread. + If the debug regs have changed, update the thread's copies. */ + void +@@ -834,19 +862,32 @@ arm_target::low_prepare_to_resume (lwp_info *lwp) + for (i = 0; i < arm_linux_get_hw_breakpoint_count (); i++) + if (lwp_info->bpts_changed[i]) + { +- errno = 0; ++ unsigned int address = proc_info->bpts[i].address; ++ arm_hwbp_control_t control = proc_info->bpts[i].control; + +- if (arm_hwbp_control_is_enabled (proc_info->bpts[i].control)) +- if (ptrace (PTRACE_SETHBPREGS, pid, +- (PTRACE_TYPE_ARG3) ((i << 1) + 1), +- &proc_info->bpts[i].address) < 0) +- perror_with_name ("Unexpected error setting breakpoint address"); +- +- if (arm_hwbp_control_is_initialized (proc_info->bpts[i].control)) +- if (ptrace (PTRACE_SETHBPREGS, pid, +- (PTRACE_TYPE_ARG3) ((i << 1) + 2), +- &proc_info->bpts[i].control) < 0) +- perror_with_name ("Unexpected error setting breakpoint"); ++ if (!arm_hwbp_control_is_initialized (control)) ++ { ++ /* Nothing to do. */ ++ } ++ else if (!arm_hwbp_control_is_enabled (control)) ++ { ++ /* Disable hardware breakpoint, just write the control ++ register. */ ++ sethbpregs_hwbp_control (pid, i, control); ++ } ++ else ++ { ++ /* See arm_linux_nat_target::low_prepare_to_resume for detailed ++ comment. */ ++ unsigned int aligned_address = address & ~0x7U; ++ if (aligned_address != address) ++ { ++ sethbpregs_hwbp_address (pid, i, aligned_address); ++ sethbpregs_hwbp_control (pid, i, control); ++ } ++ sethbpregs_hwbp_address (pid, i, address); ++ sethbpregs_hwbp_control (pid, i, control); ++ } + + lwp_info->bpts_changed[i] = 0; + } +-- +2.43.0 + diff --git a/gdb-tdep-fix-catching-syscall-execve-exit-for-arm.patch b/gdb-tdep-fix-catching-syscall-execve-exit-for-arm.patch deleted file mode 100644 index 3aa1420..0000000 --- a/gdb-tdep-fix-catching-syscall-execve-exit-for-arm.patch +++ /dev/null @@ -1,130 +0,0 @@ -From e2a2cb30bc4e85f462b817bac5393b3fee1ecf9f Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Tue, 21 Nov 2023 11:44:07 +0100 -Subject: [PATCH 3/7] [gdb/tdep] Fix catching syscall execve exit for arm - -When running test-case gdb.base/catch-syscall.exp on a pinebook (64-bit -aarch64 kernel, 32-bit userland) I run into: -... -(gdb) PASS: $exp: execve: syscall(s) execve appears in 'info breakpoints' -continue^M -Continuing.^M -^M -Catchpoint 18 (call to syscall execve), 0xf7726318 in execve () from \ - /lib/arm-linux-gnueabihf/libc.so.6^M -(gdb) PASS: gdb.base/catch-syscall.exp: execve: program has called execve -continue^M -Continuing.^M -process 32392 is executing new program: catch-syscall^M -Cannot access memory at address 0xf77c6a7c^M -(gdb) FAIL: $exp: execve: syscall execve has returned -... - -The memory error is thrown by arm_linux_get_syscall_number, when doing: -... - /* PC gets incremented before the syscall-stop, so read the - previous instruction. */ - unsigned long this_instr = - read_memory_unsigned_integer (pc - 4, 4, byte_order_for_code); -... - -The reason for the error is that we're stopped at the syscall exit of syscall -execve, and the pc is at the first insn of the new exec, which also happens to -be the first insn in the code segment, so consequently we cannot read the -previous insn. - -Fix this by detecting the situation by looking at the register state, similar -to what is done in aarch64_linux_get_syscall_number. - -Furthermore, catch the memory error by using safe_read_memory_unsigned_integer -and return -1 instead, matching the documented behaviour of -arm_linux_get_syscall_number. - -Finally, rather than using a hardcoded constant 11, introduce an ad-hoc -arm_sys_execve. - -Tested on pinebook. - -PR tdep/31071 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31071 ---- - gdb/arm-linux-tdep.c | 42 ++++++++++++++++++++++++++++++++++++++---- - 1 file changed, 38 insertions(+), 4 deletions(-) - -diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c -index 33748731cfd..8116c1368ff 100644 ---- a/gdb/arm-linux-tdep.c -+++ b/gdb/arm-linux-tdep.c -@@ -813,6 +813,32 @@ arm_linux_sigreturn_next_pc (struct regcache *regcache, - return next_pc; - } - -+/* Return true if we're at execve syscall-exit-stop. */ -+ -+static bool -+is_execve_syscall_exit (struct regcache *regs) -+{ -+ ULONGEST reg = -1; -+ -+ /* Check that lr is 0. */ -+ regcache_cooked_read_unsigned (regs, ARM_LR_REGNUM, ®); -+ if (reg != 0) -+ return false; -+ -+ /* Check that r0-r8 is 0. */ -+ for (int i = 0; i <= 8; ++i) -+ { -+ reg = -1; -+ regcache_cooked_read_unsigned (regs, ARM_A1_REGNUM + i, ®); -+ if (reg != 0) -+ return false; -+ } -+ -+ return true; -+} -+ -+#define arm_sys_execve 11 -+ - /* At a ptrace syscall-stop, return the syscall number. This either - comes from the SWI instruction (OABI) or from r7 (EABI). - -@@ -830,6 +856,9 @@ arm_linux_get_syscall_number (struct gdbarch *gdbarch, - int is_thumb; - ULONGEST svc_number = -1; - -+ if (is_execve_syscall_exit (regs)) -+ return arm_sys_execve; -+ - regcache_cooked_read_unsigned (regs, ARM_PC_REGNUM, &pc); - regcache_cooked_read_unsigned (regs, ARM_PS_REGNUM, &cpsr); - is_thumb = (cpsr & t_bit) != 0; -@@ -845,9 +874,14 @@ arm_linux_get_syscall_number (struct gdbarch *gdbarch, - - /* PC gets incremented before the syscall-stop, so read the - previous instruction. */ -- unsigned long this_instr = -- read_memory_unsigned_integer (pc - 4, 4, byte_order_for_code); -- -+ unsigned long this_instr; -+ { -+ ULONGEST val; -+ if (!safe_read_memory_unsigned_integer (pc - 4, 4, byte_order_for_code, -+ &val)) -+ return -1; -+ this_instr = val; -+ } - unsigned long svc_operand = (0x00ffffff & this_instr); - - if (svc_operand) -@@ -1265,7 +1299,7 @@ arm_canonicalize_syscall (int syscall) - case 8: return gdb_sys_creat; - case 9: return gdb_sys_link; - case 10: return gdb_sys_unlink; -- case 11: return gdb_sys_execve; -+ case arm_sys_execve: return gdb_sys_execve; - case 12: return gdb_sys_chdir; - case 13: return gdb_sys_time; - case 14: return gdb_sys_mknod; --- -2.35.3 - diff --git a/gdb-tdep-fix-gdb.base-watch-bitfields.exp-on-aarch64.patch b/gdb-tdep-fix-gdb.base-watch-bitfields.exp-on-aarch64.patch deleted file mode 100644 index 2b4fcd5..0000000 --- a/gdb-tdep-fix-gdb.base-watch-bitfields.exp-on-aarch64.patch +++ /dev/null @@ -1,349 +0,0 @@ -From 83b2b88c96f87a3649b4440f43a088dc6e292181 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Tue, 12 Mar 2024 17:08:18 +0100 -Subject: [PATCH 08/48] [gdb/tdep] Fix gdb.base/watch-bitfields.exp on aarch64 - -On aarch64-linux, with test-case gdb.base/watch-bitfields.exp I run into: -... -(gdb) continue^M -Continuing.^M -^M -Hardware watchpoint 2: -location q.a^M -^M -Old value = 1^M -New value = 0^M -main () at watch-bitfields.c:42^M -42 q.h--;^M -(gdb) FAIL: $exp: -location watch against bitfields: q.e: 0->5: continue -... - -In a minimal form, if we step past line 37 which sets q.e, and we have a -watchpoint set on q.e, it triggers: -... -$ gdb -q -batch watch-bitfields -ex "b 37" -ex run -ex "watch q.e" -ex step -Breakpoint 1 at 0x410204: file watch-bitfields.c, line 37. - -Breakpoint 1, main () at watch-bitfields.c:37 -37 q.e = 5; -Hardware watchpoint 2: q.e - -Hardware watchpoint 2: q.e - -Old value = 0 -New value = 5 -main () at /home/vries/gdb/src/gdb/testsuite/gdb.base/watch-bitfields.c:38 -38 q.f = 6; -... - -However, if we set in addition a watchpoint on q.a, the watchpoint on q.e -doesn't trigger. - -How does this happen? - -Bitfield q.a is just bit 0 of byte 0, and bitfield q.e is bit 4..7 of byte 1 -and bit 1 of byte 2. So, watch q.a should watch byte 0, and watch q.e should -watch bytes 1 and 2. - -Using "maint set show-debug-regs on" (and some more detailed debug prints) we -get: -... -WP2: addr=0x440028 (orig=0x440029), ctrl=0x000000d5, ref.count=1 - ctrl: enabled=1, offset=1, len=2 -WP3: addr=0x440028 (orig=0x440028), ctrl=0x00000035, ref.count=1 - ctrl: enabled=1, offset=0, len=1 -... -which matches that. - -When executing line 37, a hardware watchpoint trap triggers and we hit -aarch64_stopped_data_address with addr_trap == 0x440028: -... -(gdb) p /x addr_trap -$1 = 0x440028 -.... -and since the loop in aarch64_stopped_data_address walks backward, we check -WP3 first, which matches, and consequently target_stopped_by_watchpoint -returns true in watchpoints_triggered. - -Likewise for target_stopped_data_address, which also returns addr == 0x440028. -Watchpoints_triggered matches watchpoint q.a to that address, and sets -watch_triggered_yes. - -However, subsequently the value of q.a is checked, and it's the same value as -before (becase the insn in line 37 didn't change q.a), so the watchpoint -hardware trap is not reported to the user. - -The problem originates from that fact that aarch64_stopped_data_address picked -WP3 instead of WP2. - -There's something we can do about this. In the example above, both -target_stopped_by_watchpoint and target_stopped_data_address returned true. -Instead we can return true in target_stopped_by_watchpoint but false in -target_stopped_data_address. This lets watchpoints_triggered known that a -watchpoint was triggered, but we don't know where, and both watchpoints -get set to watch_triggered_unknown. - -Subsequently, the values of both q.a and q.e are checked, and since q.e is not -the same value as before, the watchpoint hardware trap is reported to the user. - -Note that this works well for regular (write) watchpoints (watch command), but -not for read watchpoints (rwatch command), because for those no value is -checked. Likewise for access watchpoints (awatch command). - -So, fix this by: -- passing a nullptr in aarch64_fbsd_nat_target::stopped_by_watchpoint and - aarch64_linux_nat_target::stopped_by_watchpoint to make clear we're not - interested in the stop address, -- introducing a two-phase approach in aarch64_stopped_data_address, where: - - phase one handles access and read watchpoints, as before, and - - phase two handles write watchpoints, where multiple matches cause: - - return true if addr_p == null, and - - return false if addr_p != null. - -Tested on aarch64-linux. - -Approved-By: Luis Machado - -PR tdep/31214 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31214 ---- - gdb/aarch64-fbsd-nat.c | 4 +- - gdb/aarch64-linux-nat.c | 4 +- - gdb/aarch64-nat.c | 132 ++++++++++++++++++++++++++----------- - gdb/nat/aarch64-hw-point.c | 25 +++++++ - gdb/nat/aarch64-hw-point.h | 2 + - 5 files changed, 123 insertions(+), 44 deletions(-) - -diff --git a/gdb/aarch64-fbsd-nat.c b/gdb/aarch64-fbsd-nat.c -index 38fb093f139..58518248248 100644 ---- a/gdb/aarch64-fbsd-nat.c -+++ b/gdb/aarch64-fbsd-nat.c -@@ -164,9 +164,7 @@ aarch64_fbsd_nat_target::stopped_data_address (CORE_ADDR *addr_p) - bool - aarch64_fbsd_nat_target::stopped_by_watchpoint () - { -- CORE_ADDR addr; -- -- return stopped_data_address (&addr); -+ return stopped_data_address (nullptr); - } - - /* Implement the "stopped_by_hw_breakpoint" target_ops method. */ -diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c -index c1d59b5d77c..768748a20db 100644 ---- a/gdb/aarch64-linux-nat.c -+++ b/gdb/aarch64-linux-nat.c -@@ -972,9 +972,7 @@ aarch64_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p) - bool - aarch64_linux_nat_target::stopped_by_watchpoint () - { -- CORE_ADDR addr; -- -- return stopped_data_address (&addr); -+ return stopped_data_address (nullptr); - } - - /* Implement the "can_do_single_step" target_ops method. */ -diff --git a/gdb/aarch64-nat.c b/gdb/aarch64-nat.c -index ee8c5a1e21d..89d1ba6acc6 100644 ---- a/gdb/aarch64-nat.c -+++ b/gdb/aarch64-nat.c -@@ -231,46 +231,102 @@ bool - aarch64_stopped_data_address (const struct aarch64_debug_reg_state *state, - CORE_ADDR addr_trap, CORE_ADDR *addr_p) - { -- int i; -- -- for (i = aarch64_num_wp_regs - 1; i >= 0; --i) -- { -- const unsigned int offset -- = aarch64_watchpoint_offset (state->dr_ctrl_wp[i]); -- const unsigned int len = aarch64_watchpoint_length (state->dr_ctrl_wp[i]); -- const CORE_ADDR addr_watch = state->dr_addr_wp[i] + offset; -- const CORE_ADDR addr_watch_aligned = align_down (state->dr_addr_wp[i], 8); -- const CORE_ADDR addr_orig = state->dr_addr_orig_wp[i]; -- -- if (state->dr_ref_count_wp[i] -- && DR_CONTROL_ENABLED (state->dr_ctrl_wp[i]) -- && addr_trap >= addr_watch_aligned -- && addr_trap < addr_watch + len) -- { -- /* ADDR_TRAP reports the first address of the memory range -- accessed by the CPU, regardless of what was the memory -- range watched. Thus, a large CPU access that straddles -- the ADDR_WATCH..ADDR_WATCH+LEN range may result in an -- ADDR_TRAP that is lower than the -- ADDR_WATCH..ADDR_WATCH+LEN range. E.g.: -- -- addr: | 4 | 5 | 6 | 7 | 8 | -- |---- range watched ----| -- |----------- range accessed ------------| -- -- In this case, ADDR_TRAP will be 4. -- -- To match a watchpoint known to GDB core, we must never -- report *ADDR_P outside of any ADDR_WATCH..ADDR_WATCH+LEN -- range. ADDR_WATCH <= ADDR_TRAP < ADDR_ORIG is a false -- positive on kernels older than 4.10. See PR -- external/20207. */ -+ bool found = false; -+ for (int phase = 0; phase <= 1; ++phase) -+ for (int i = aarch64_num_wp_regs - 1; i >= 0; --i) -+ { -+ if (!(state->dr_ref_count_wp[i] -+ && DR_CONTROL_ENABLED (state->dr_ctrl_wp[i]))) -+ { -+ /* Watchpoint disabled. */ -+ continue; -+ } -+ -+ const enum target_hw_bp_type type -+ = aarch64_watchpoint_type (state->dr_ctrl_wp[i]); -+ if (type == hw_execute) -+ { -+ /* Watchpoint disabled. */ -+ continue; -+ } -+ -+ if (phase == 0) -+ { -+ /* Phase 0: No hw_write. */ -+ if (type == hw_write) -+ continue; -+ } -+ else -+ { -+ /* Phase 1: Only hw_write. */ -+ if (type != hw_write) -+ continue; -+ } -+ -+ const unsigned int offset -+ = aarch64_watchpoint_offset (state->dr_ctrl_wp[i]); -+ const unsigned int len -+ = aarch64_watchpoint_length (state->dr_ctrl_wp[i]); -+ const CORE_ADDR addr_watch = state->dr_addr_wp[i] + offset; -+ const CORE_ADDR addr_watch_aligned -+ = align_down (state->dr_addr_wp[i], 8); -+ const CORE_ADDR addr_orig = state->dr_addr_orig_wp[i]; -+ -+ /* ADDR_TRAP reports the first address of the memory range -+ accessed by the CPU, regardless of what was the memory -+ range watched. Thus, a large CPU access that straddles -+ the ADDR_WATCH..ADDR_WATCH+LEN range may result in an -+ ADDR_TRAP that is lower than the -+ ADDR_WATCH..ADDR_WATCH+LEN range. E.g.: -+ -+ addr: | 4 | 5 | 6 | 7 | 8 | -+ |---- range watched ----| -+ |----------- range accessed ------------| -+ -+ In this case, ADDR_TRAP will be 4. */ -+ if (!(addr_trap >= addr_watch_aligned -+ && addr_trap < addr_watch + len)) -+ { -+ /* Not a match. */ -+ continue; -+ } -+ -+ /* To match a watchpoint known to GDB core, we must never -+ report *ADDR_P outside of any ADDR_WATCH..ADDR_WATCH+LEN -+ range. ADDR_WATCH <= ADDR_TRAP < ADDR_ORIG is a false -+ positive on kernels older than 4.10. See PR -+ external/20207. */ -+ if (addr_p != nullptr) - *addr_p = addr_orig; -- return true; -- } -- } - -- return false; -+ if (phase == 0) -+ { -+ /* Phase 0: Return first match. */ -+ return true; -+ } -+ -+ /* Phase 1. */ -+ if (addr_p == nullptr) -+ { -+ /* First match, and we don't need to report an address. No need -+ to look for other matches. */ -+ return true; -+ } -+ -+ if (!found) -+ { -+ /* First match, and we need to report an address. Look for other -+ matches. */ -+ found = true; -+ continue; -+ } -+ -+ /* More than one match, and we need to return an address. No need to -+ look for further matches. */ -+ return false; -+ } -+ -+ return found; - } - - /* Define AArch64 maintenance commands. */ -diff --git a/gdb/nat/aarch64-hw-point.c b/gdb/nat/aarch64-hw-point.c -index 6747e61e026..3b8cdcba23b 100644 ---- a/gdb/nat/aarch64-hw-point.c -+++ b/gdb/nat/aarch64-hw-point.c -@@ -73,6 +73,31 @@ aarch64_watchpoint_length (unsigned int ctrl) - return retval; - } - -+/* Utility function that returns the type of a watchpoint according to the -+ content of a hardware debug control register CTRL. */ -+ -+enum target_hw_bp_type -+aarch64_watchpoint_type (unsigned int ctrl) -+{ -+ unsigned int type = DR_CONTROL_TYPE (ctrl); -+ -+ switch (type) -+ { -+ case 1: -+ return hw_read; -+ case 2: -+ return hw_write; -+ case 3: -+ return hw_access; -+ case 0: -+ /* Reserved for a watchpoint. It must behave as if the watchpoint is -+ disabled. */ -+ return hw_execute; -+ default: -+ gdb_assert_not_reached (""); -+ } -+} -+ - /* Given the hardware breakpoint or watchpoint type TYPE and its - length LEN, return the expected encoding for a hardware - breakpoint/watchpoint control register. */ -diff --git a/gdb/nat/aarch64-hw-point.h b/gdb/nat/aarch64-hw-point.h -index 2ff9ccb5c1c..71ae2864927 100644 ---- a/gdb/nat/aarch64-hw-point.h -+++ b/gdb/nat/aarch64-hw-point.h -@@ -73,6 +73,7 @@ - - #define DR_CONTROL_ENABLED(ctrl) (((ctrl) & 0x1) == 1) - #define DR_CONTROL_MASK(ctrl) (((ctrl) >> 5) & 0xff) -+#define DR_CONTROL_TYPE(ctrl) (((ctrl) >> 3) & 0x3) - - /* Structure for managing the hardware breakpoint/watchpoint resources. - DR_ADDR_* stores the address, DR_CTRL_* stores the control register -@@ -107,6 +108,7 @@ void aarch64_notify_debug_reg_change (ptid_t ptid, int is_watchpoint, - - unsigned int aarch64_watchpoint_offset (unsigned int ctrl); - unsigned int aarch64_watchpoint_length (unsigned int ctrl); -+enum target_hw_bp_type aarch64_watchpoint_type (unsigned int ctrl); - - int aarch64_handle_breakpoint (enum target_hw_bp_type type, CORE_ADDR addr, - int len, int is_insert, ptid_t ptid, --- -2.35.3 - diff --git a/gdb-tdep-fix-gdb.base-watchpoint-running-on-arm-ppc6.patch b/gdb-tdep-fix-gdb.base-watchpoint-running-on-arm-ppc6.patch deleted file mode 100644 index 74340f0..0000000 --- a/gdb-tdep-fix-gdb.base-watchpoint-running-on-arm-ppc6.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 1e64a66f72c79874016e78a4672b85cdeb506b9f Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Tue, 4 Jun 2024 09:30:03 +0000 -Subject: [PATCH] [gdb/tdep] Fix gdb.base/watchpoint-running on - {arm,ppc64le}-linux - -When running test-case gdb.base/watchpoint-running on ppc64le-linux, we get: -... -(gdb) watch global_var^M -warning: Error when detecting the debug register interface. \ - Debug registers will be unavailable.^M -Watchpoint 2: global_var^M -(gdb) FAIL: $exp: all-stop: hardware: watch global_var -FAIL: $exp: all-stop: hardware: watchpoint hit (timeout) -... - -The problem is that ppc_linux_dreg_interface::detect fails to detect the -hardware watchpoint interface, because the calls to ptrace return with errno -set to ESRCH. - -This is a feature of ptrace: if a call is done while the tracee is not -ptrace-stopped, it returns ESRCH. - -Indeed, in the test-case "watch global_var" is executed while the inferior is -running, and that triggers the first call to ppc_linux_dreg_interface::detect. - -And because the detection failure is cached, subsequent attempts at setting -hardware watchpoints will also fail, even if the tracee is ptrace-stopped. - -Fix this by calling target_can_use_hardware_watchpoint from -linux_init_ptrace_procfs, which is called from both: -- linux_nat_target::post_attach, and -- linux_nat_target::post_startup_inferior. - -By fixing this here, we also fix the same problem for arm-linux. - -Tested on ppc64le-linux and arm-linux. - -PR tdep/31834 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31834 -PR tdep/31705 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31705 - -(cherry picked from commit bbc92bfbf25ad42548100e31e491ed3c32fbfa3e) ---- - gdb/linux-nat.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c -index c8991cc3da4..47d74d27e11 100644 ---- a/gdb/linux-nat.c -+++ b/gdb/linux-nat.c -@@ -385,6 +385,18 @@ linux_init_ptrace_procfs (pid_t pid, int attached) - linux_ptrace_init_warnings (); - linux_proc_init_warnings (); - proc_mem_file_is_writable (); -+ -+ /* Some targets (for instance ppc and arm) may call ptrace to answer a -+ target_can_use_hardware_watchpoint query, and cache the result. However, -+ the ptrace call will fail with errno ESRCH if the tracee is not -+ ptrace-stopped, making the query fail. And if the caching mechanism does -+ not disregard an ESRCH result, all subsequent queries will also fail. -+ Call it now, where we known the tracee is ptrace-stopped. -+ -+ Other targets (for instance aarch64) do the relevant ptrace call and -+ caching in their implementation of post_attach and post_startup_inferior, -+ in which case this call is expected to have no effect. */ -+ target_can_use_hardware_watchpoint (bp_hardware_watchpoint, 1, 0); - } - - linux_nat_target::~linux_nat_target () - -base-commit: a6800d9c8145f25001dd39afc3571e3350573e81 --- -2.35.3 - diff --git a/gdb-tdep-fix-gdb.base-watchpoint-unaligned.exp-on-aa.patch b/gdb-tdep-fix-gdb.base-watchpoint-unaligned.exp-on-aa.patch deleted file mode 100644 index aed0238..0000000 --- a/gdb-tdep-fix-gdb.base-watchpoint-unaligned.exp-on-aa.patch +++ /dev/null @@ -1,262 +0,0 @@ -From 3efde6721b362fe0acad348443e4b961d7485717 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Thu, 14 Mar 2024 11:25:10 +0100 -Subject: [PATCH 09/48] [gdb/tdep] Fix gdb.base/watchpoint-unaligned.exp on - aarch64 - -On aarch64-linux, with test-case gdb.base/watchpoint-unaligned.exp I run into: -... -(gdb) watch data.u.size8twice[1]^M -Hardware watchpoint 241: data.u.size8twice[1]^M -(gdb) PASS: gdb.base/watchpoint-unaligned.exp: watch data.u.size8twice[1] -continue^M -Continuing.^M -FAIL: gdb.base/watchpoint-unaligned.exp: continue (timeout) -FAIL: gdb.base/watchpoint-unaligned.exp: size8twice write -... - -This happens as follows. - -We start the exec and set an 8-byte hardware watchpoint on -data.u.size8twice[1] at address 0x440048: -... -(gdb) p sizeof (data.u.size8twice[1]) -$1 = 8 -(gdb) p &data.u.size8twice[1] -$2 = (uint64_t *) 0x440048 -... - -We continue execution, and a 16-byte write at address 0x440040 triggers the -hardware watchpoint: -... - 4101c8: a9000801 stp x1, x2, [x0] -... - -When checking whether a watchpoint has triggered in -aarch64_stopped_data_address, we check against address 0x440040 (passed in -parameter addr_trap). This behaviour is documented: -... - /* ADDR_TRAP reports the first address of the memory range - accessed by the CPU, regardless of what was the memory - range watched. ... */ -... -and consequently the matching logic compares against an addr_watch_aligned: -... - && addr_trap >= addr_watch_aligned - && addr_trap < addr_watch + len) -... - -However, the comparison fails: -... -(gdb) p /x addr_watch_aligned -$3 = 0x440048 -(gdb) p addr_trap >= addr_watch_aligned -$4 = false -... - -Consequently, aarch64_stopped_data_address returns false, and -stopped_by_watchpoint returns false, and watchpoints_triggered returns 0, -which make infrun think it's looking at a delayed hardware -breakpoint/watchpoint trap: -... - [infrun] handle_signal_stop: stop_pc=0x4101c8 - [infrun] handle_signal_stop: delayed hardware breakpoint/watchpoint trap, ignoring -... -Infrun then ignores the trap and continues, but runs into the same situation -again and again, causing a hang which then causes the test timeout. - -Fix this by allowing a match 8 bytes below addr_watch_aligned. This -introduces the possibility for false positives, so we only do this for regular -"value changed" watchpoints. - -An earlier version of this patch worked by aligning addr_watch_aligned to 16 -instead of 8: -... -- const CORE_ADDR addr_watch_aligned = align_down (state->dr_addr_wp[i], 8); -+ const CORE_ADDR addr_watch_aligned = align_down (state->dr_addr_wp[i], 16); -... -but while that fixed the test-case, it didn't fix the problem completely, so -extend the test-case to check more scenarios. - -Tested on aarch64-linux. - -Tested-By: Luis Machado -Approved-By: Luis Machado - -PR tdep/29423 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29423 ---- - gdb/aarch64-nat.c | 17 +++- - gdb/testsuite/gdb.base/watchpoint-unaligned.c | 11 +-- - .../gdb.base/watchpoint-unaligned.exp | 78 ++++++++++++------- - 3 files changed, 68 insertions(+), 38 deletions(-) - -diff --git a/gdb/aarch64-nat.c b/gdb/aarch64-nat.c -index 89d1ba6acc6..a173e4e18d5 100644 ---- a/gdb/aarch64-nat.c -+++ b/gdb/aarch64-nat.c -@@ -269,7 +269,7 @@ aarch64_stopped_data_address (const struct aarch64_debug_reg_state *state, - = aarch64_watchpoint_length (state->dr_ctrl_wp[i]); - const CORE_ADDR addr_watch = state->dr_addr_wp[i] + offset; - const CORE_ADDR addr_watch_aligned -- = align_down (state->dr_addr_wp[i], 8); -+ = align_down (state->dr_addr_wp[i], AARCH64_HWP_MAX_LEN_PER_REG); - const CORE_ADDR addr_orig = state->dr_addr_orig_wp[i]; - - /* ADDR_TRAP reports the first address of the memory range -@@ -283,8 +283,19 @@ aarch64_stopped_data_address (const struct aarch64_debug_reg_state *state, - |---- range watched ----| - |----------- range accessed ------------| - -- In this case, ADDR_TRAP will be 4. */ -- if (!(addr_trap >= addr_watch_aligned -+ In this case, ADDR_TRAP will be 4. -+ -+ The access size also can be larger than that of the watchpoint -+ itself. For instance, the access size of an stp instruction is 16. -+ So, if we use stp to store to address p, and set a watchpoint on -+ address p + 8, the reported ADDR_TRAP can be p + 8 (observed on -+ RK3399 SOC). But it also can be p (observed on M1 SOC). Checking -+ for this situation introduces the possibility of false positives, -+ so we only do this for hw_write watchpoints. */ -+ const CORE_ADDR max_access_size = type == hw_write ? 16 : 8; -+ const CORE_ADDR addr_watch_base = addr_watch_aligned - -+ (max_access_size - AARCH64_HWP_MAX_LEN_PER_REG); -+ if (!(addr_trap >= addr_watch_base - && addr_trap < addr_watch + len)) - { - /* Not a match. */ -diff --git a/gdb/testsuite/gdb.base/watchpoint-unaligned.c b/gdb/testsuite/gdb.base/watchpoint-unaligned.c -index b60025a64f4..d854c376be9 100644 ---- a/gdb/testsuite/gdb.base/watchpoint-unaligned.c -+++ b/gdb/testsuite/gdb.base/watchpoint-unaligned.c -@@ -29,7 +29,7 @@ static volatile struct - uint32_t size4[2]; - uint16_t size2[4]; - uint8_t size1[8]; -- uint64_t size8twice[2]; -+ uint64_t size8twice[3]; - } - u; - } data; -@@ -44,13 +44,14 @@ write_size8twice (void) - static const uint64_t second = 2; - - #ifdef __aarch64__ -+ volatile void *p = &data.u.size8twice[offset]; - asm volatile ("stp %1, %2, [%0]" - : /* output */ -- : "r" (data.u.size8twice), "r" (first), "r" (second) /* input */ -+ : "r" (p), "r" (first), "r" (second) /* input */ - : "memory" /* clobber */); - #else -- data.u.size8twice[0] = first; -- data.u.size8twice[1] = second; -+ data.u.size8twice[offset] = first; -+ data.u.size8twice[offset + 1] = second; - #endif - } - -@@ -59,7 +60,7 @@ main (void) - { - volatile uint64_t local; - -- assert (sizeof (data) == 8 + 2 * 8); -+ assert (sizeof (data) == 8 + 3 * 8); - - write_size8twice (); - -diff --git a/gdb/testsuite/gdb.base/watchpoint-unaligned.exp b/gdb/testsuite/gdb.base/watchpoint-unaligned.exp -index d31a9cdc2c8..c58704d033d 100644 ---- a/gdb/testsuite/gdb.base/watchpoint-unaligned.exp -+++ b/gdb/testsuite/gdb.base/watchpoint-unaligned.exp -@@ -151,38 +151,56 @@ foreach wpcount {4 7} { - gdb_assert $got_hit $test - } - --if ![runto_main] { -- return -1 --} --gdb_breakpoint [gdb_get_line_number "final_return"] "Breakpoint $decimal at $hex" "final_return" --set test {watch data.u.size8twice[1]} --set wpnum 0 --gdb_test_multiple $test $test { -- -re "Hardware watchpoint (\[0-9\]+): .*\r\n$gdb_prompt $" { -- set wpnum $expect_out(1,string) -- pass $gdb_test_name -- } -- -re "Watchpoint (\[0-9\]+): .*\r\n$gdb_prompt $" { -- if {[istarget "arm*-*-*"]} { -- untested $gdb_test_name -- } else { -- fail $gdb_test_name -- } -- } --} --if {$wpnum} { -- set test "continue" -- set got_hit 0 -- gdb_test_multiple $test $test { -- -re "\r\nCould not insert hardware watchpoint .*\r\n$gdb_prompt $" { -+# We've got an array with 3 8-byte elements. Do a store of 16 bytes, -+# to: -+# - elements 0 and 1 (offset == 0), and -+# - elements 1 and 2 (offset == 1). -+# For each case, check setting a watchpoint at: -+# - the first written element (index == 0), and -+# - the second element (index == 1). -+foreach_with_prefix offset { 0 1 } { -+ foreach_with_prefix index { 0 1 } { -+ -+ clean_restart $binfile -+ -+ if ![runto_main] { -+ return -1 - } -- -re "Hardware watchpoint $wpnum:.*New value = .*\r\n$gdb_prompt $" { -- set got_hit 1 -- send_gdb "continue\n" -- exp_continue -+ -+ gdb_test_no_output "set var offset = $offset" -+ gdb_breakpoint [gdb_get_line_number "final_return"] \ -+ "Breakpoint $decimal at $hex" "final_return" -+ set watch_index [expr $offset + $index] -+ set test "watch data.u.size8twice\[$watch_index\]" -+ set wpnum 0 -+ gdb_test_multiple $test $test { -+ -re "Hardware watchpoint (\[0-9\]+): .*\r\n$gdb_prompt $" { -+ set wpnum $expect_out(1,string) -+ pass $gdb_test_name -+ } -+ -re "Watchpoint (\[0-9\]+): .*\r\n$gdb_prompt $" { -+ if {[istarget "arm*-*-*"]} { -+ untested $gdb_test_name -+ } else { -+ fail $gdb_test_name -+ } -+ } - } -- -re " final_return .*\r\n$gdb_prompt $" { -+ if {$wpnum} { -+ set test "continue" -+ set got_hit 0 -+ gdb_test_multiple $test $test { -+ -re "\r\nCould not insert hardware watchpoint .*\r\n$gdb_prompt $" { -+ } -+ -re "Hardware watchpoint $wpnum:.*New value = .*\r\n$gdb_prompt $" { -+ set got_hit 1 -+ send_gdb "continue\n" -+ exp_continue -+ } -+ -re " final_return .*\r\n$gdb_prompt $" { -+ } -+ } -+ gdb_assert $got_hit "size8twice write" - } - } -- gdb_assert $got_hit "size8twice write" - } --- -2.35.3 - diff --git a/gdb-tdep-fix-gdb.cp-non-trivial-retval.exp-on-riscv6.patch b/gdb-tdep-fix-gdb.cp-non-trivial-retval.exp-on-riscv6.patch new file mode 100644 index 0000000..04fe29a --- /dev/null +++ b/gdb-tdep-fix-gdb.cp-non-trivial-retval.exp-on-riscv6.patch @@ -0,0 +1,191 @@ +From 680379be6e3bcd4f8e1fcc85055e9dd0d6bbbaff Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Fri, 10 Jan 2025 10:32:00 +0100 +Subject: [PATCH 28/46] [gdb/tdep] Fix gdb.cp/non-trivial-retval.exp on + riscv64-linux +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +With test-case gdb.cp/non-trivial-retval.exp on riscv64-linux, I ran into: +... +(gdb) finish^M +Run till exit from #0 f1 (i1=i1@entry=23, i2=i2@entry=100) \ + at non-trivial-retval.cc:34^M +main () at non-trivial-retval.cc:163^M +163 B b = f2 (i1, i2);^M +Value returned is $6 = {a = -5856}^M +(gdb) FAIL: $exp: finish from f1 +... +where "Value returned is $6 = {a = 123}" is expected. + +The problem is that gdb thinks that the return value is in $a0: +... +$ gdb -q -batch non-trivial-retval \ + -ex "b f1" \ + -ex run \ + -ex "set debug riscv infcall on" \ + -ex finish +Breakpoint 1 at 0x80a: file non-trivial-retval.cc, line 34. +[Thread debugging using libthread_db enabled] +Using host libthread_db library "/lib/riscv64-linux-gnu/libthread_db.so.1". + +Breakpoint 1, f1 (i1=i1@entry=23, i2=i2@entry=100) at non-trivial-retval.cc:34 +34 { +[riscv-infcall] riscv_return_value: \ + [R] type: 'A', length: 0x4, alignment: 0x4, register a0 +[riscv-infcall] riscv_return_value: \ + [R] type: 'A', length: 0x4, alignment: 0x4, register a0 +[riscv-infcall] riscv_return_value: \ + [R] type: 'A', length: 0x4, alignment: 0x4, register a0 +main () at non-trivial-retval.cc:163 +163 B b = f2 (i1, i2); +Value returned is $1 = {a = -3568} +... +while $a0 actually contains a pointer to the returned value 123: +... +(gdb) p /x $a0 +$3 = 0x3ffffff210 +(gdb) p *((unsigned int *)$a0) +$5 = 123 +... + +The returned type is: +... +class A +{ +public: + A () {} + A (A &obj); + + int a; +}; +... +which is a C++ aggregate with a nontrivial (because it's user-defined) copy +constructor: + +According to the ABI [1], indeed this is returned by reference: +... +Values are returned in the same manner as a first named argument of the same +type would be passed. If such an argument would have been passed by +reference, the caller allocates memory for the return value, and passes the +address as an implicit first parameter. + ... +Aggregates larger than 2×XLEN bits are passed by reference and are replaced in +the argument list with the address, as are C++ aggregates with nontrivial copy +constructors, destructors, or vtables. +... + +Fix this in riscv_call_arg_scalar_int by checking for +language_pass_by_reference ().trivially_copy_constructible. + +The vtable case is explictly mentioned in the ABI, but AFAIU already covered +by the nontrivial copy constructor case. + +The nontrivial destructor case is also not supported, but the testsuite +doesn't seem to trigger this. + +Fix this by: +- extending the test-case to cover this scenario, and +- fixing it in riscv_call_arg_scalar_int by checking for + language_pass_by_reference ().trivially_destructible. + +Tested on riscv64-linux. + +PR tdep/32152 +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32152 + +Approved-By: Andrew Burgess + +[1] https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc +--- + gdb/riscv-tdep.c | 6 +++++- + gdb/testsuite/gdb.cp/non-trivial-retval.cc | 19 +++++++++++++++++++ + gdb/testsuite/gdb.cp/non-trivial-retval.exp | 6 ++++++ + 3 files changed, 30 insertions(+), 1 deletion(-) + +diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c +index d592d2dc0c4..edb40d6babf 100644 +--- a/gdb/riscv-tdep.c ++++ b/gdb/riscv-tdep.c +@@ -2857,8 +2857,12 @@ static void + riscv_call_arg_scalar_int (struct riscv_arg_info *ainfo, + struct riscv_call_info *cinfo) + { ++ auto lang_req = language_pass_by_reference (ainfo->type); ++ + if (TYPE_HAS_DYNAMIC_LENGTH (ainfo->type) +- || ainfo->length > (2 * cinfo->xlen)) ++ || ainfo->length > (2 * cinfo->xlen) ++ || !lang_req.trivially_copy_constructible ++ || !lang_req.trivially_destructible) + { + /* Argument is going to be passed by reference. */ + ainfo->argloc[0].loc_type +diff --git a/gdb/testsuite/gdb.cp/non-trivial-retval.cc b/gdb/testsuite/gdb.cp/non-trivial-retval.cc +index 4bba0f1c3af..4e812516d63 100644 +--- a/gdb/testsuite/gdb.cp/non-trivial-retval.cc ++++ b/gdb/testsuite/gdb.cp/non-trivial-retval.cc +@@ -142,6 +142,24 @@ f4 (int i1, int i2) + return e; + } + ++class F ++{ ++public: ++ ~F () {} ++ ++ int f; ++}; ++ ++F ++f5 (int i1, int i2) ++{ ++ F f; ++ ++ f.f = i1 + i2; ++ ++ return f; ++} ++ + /* We place a breakpoint on the call to this function. */ + + void +@@ -164,6 +182,7 @@ main (void) + B1 b1 = f22 (i1, i2); + C c = f3 (i1, i2); + E e = f4 (i1, i2); ++ F f = f5 (i1, i2); + + return 0; + } +diff --git a/gdb/testsuite/gdb.cp/non-trivial-retval.exp b/gdb/testsuite/gdb.cp/non-trivial-retval.exp +index 89035e178ed..6c9f7e13d2a 100644 +--- a/gdb/testsuite/gdb.cp/non-trivial-retval.exp ++++ b/gdb/testsuite/gdb.cp/non-trivial-retval.exp +@@ -42,12 +42,14 @@ gdb_test "p f2 (i1, i2)" ".* = {b = 123}" + gdb_test "p f22 (i1, i2)" ".* = {b1 = 123}" + gdb_test "p f3 (i1, i2)" ".* = {.* c = 123}" + gdb_test "p f4 (i1, i2)" ".* = {.* e = 123}" ++gdb_test "p f5 (i1, i2)" ".* = {f = 123}" + + gdb_breakpoint "f1" + gdb_breakpoint "f2" + gdb_breakpoint "f22" + gdb_breakpoint "f3" + gdb_breakpoint "f4" ++gdb_breakpoint "f5" + + gdb_continue_to_breakpoint "Break in f1" + gdb_test "finish" " = {a = 123}" \ +@@ -68,3 +70,7 @@ gdb_test "finish" " = {.* c = 123}" \ + gdb_continue_to_breakpoint "Break in f4" + gdb_test "finish" " = {.* e = 123}" \ + "finish from f4" ++ ++gdb_continue_to_breakpoint "Break in f5" ++gdb_test "finish" " = {f = 123}" \ ++ "finish from f5" +-- +2.43.0 + diff --git a/gdb-tdep-fix-nr-array-elements-in-ppc64_aggregate_ca.patch b/gdb-tdep-fix-nr-array-elements-in-ppc64_aggregate_ca.patch deleted file mode 100644 index 0b91eaf..0000000 --- a/gdb-tdep-fix-nr-array-elements-in-ppc64_aggregate_ca.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 3f0c512dc37dbede372a018732d315726a56d10e Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Wed, 1 Nov 2023 08:07:15 +0100 -Subject: [PATCH] [gdb/tdep] Fix nr array elements in ppc64_aggregate_candidate - -On AlmaLinux 9.2 powerpc64le I run into: -... -(gdb) PASS: gdb.ada/array_return.exp: continuing to Create_Small_Float_Vector -finish^M -Run till exit from #0 pck.create_small_float_vector () at pck.adb:30^M -0x00000000100022d4 in p () at p.adb:25^M -25 Vector := Create_Small_Float_Vector;^M -Value returned is $3 = (2.80259693e-45, 2.80259693e-45)^M -(gdb) FAIL: gdb.ada/array_return.exp: value printed by finish of Create_Small_Float_Vector -... -while this is expected: -... -Value returned is $3 = (4.25, 4.25)^M -... - -The problem is here in ppc64_aggregate_candidate: -... - if (!get_array_bounds (type, &low_bound, &high_bound)) - return -1; - count *= high_bound - low_bound -... - -The array type (containing 2 elements) is: -... - type Small_Float_Vector is array (1 .. 2) of Float; -... -so we have: -... -(gdb) p low_bound -$1 = 1 -(gdb) p high_bound -$2 = 2 -... -but we calculate the number of elements in the array using -"high_bound - low_bound", which is 1. - -Consequently, gdb fails to correctly classify the type as a ELFv2 homogeneous -aggregate. - -Fix this by calculating the number of elements in the array by using -"high_bound - low_bound + 1" instead. - -Furthermore, high_bound can (in general, though perhaps not here) be also be -smaller than low_bound, so to be safe take that into account as well: -... - LONGEST nr_array_elements = (low_bound > high_bound - ? 0 - : (high_bound - low_bound + 1)); - count *= nr_array_elements; -... - -Tested on powerpc64le-linux. - -PR tdep/31015 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31015 ---- - gdb/ppc-sysv-tdep.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c -index 9cea63307e6..dc89201eed2 100644 ---- a/gdb/ppc-sysv-tdep.c -+++ b/gdb/ppc-sysv-tdep.c -@@ -1126,7 +1126,11 @@ ppc64_aggregate_candidate (struct type *type, - - if (!get_array_bounds (type, &low_bound, &high_bound)) - return -1; -- count *= high_bound - low_bound; -+ -+ LONGEST nr_array_elements = (low_bound > high_bound -+ ? 0 -+ : (high_bound - low_bound + 1)); -+ count *= nr_array_elements; - - /* There must be no padding. */ - if (count == 0) - -base-commit: b1136560e772dd4c74f1fbb41f6ba840b92fb9d6 --- -2.35.3 - diff --git a/gdb-tdep-fix-recording-of-t1-push.patch b/gdb-tdep-fix-recording-of-t1-push.patch new file mode 100644 index 0000000..33673a4 --- /dev/null +++ b/gdb-tdep-fix-recording-of-t1-push.patch @@ -0,0 +1,69 @@ +From 0494211cb5f418654ca3a4ac1b9f10518426732f Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Wed, 13 Nov 2024 19:44:21 +0100 +Subject: [PATCH 15/46] [gdb/tdep] Fix recording of T1 push + +When running test-case gdb.reverse/recursion.exp on arm-linux with target +board unix/-mthumb, I run into: +... +(gdb) PASS: gdb.reverse/recursion.exp: Skipping recursion from inside +reverse-next^M +bar (x=4195569) at /home/linux/gdb/src/gdb/testsuite/gdb.reverse/recursion.c:34^M +34 int r = foo (x);^M +(gdb) FAIL: gdb.reverse/recursion.exp: print frame when stepping out +... + +The problem is the recording of the T1 push instruction [1,2], specifically: +... +000004d8 : + 4d8: b580 push {r7, lr} +... + +The current code fails to add a memory record for the memory written with the +value of the lr register. + +Fix this by adding the missing memory record. + +Tested on arm-linux. + +Reviewed-By: Guinevere Larsen +Approved-By: Luis Machado + +[1] https://developer.arm.com/documentation/ddi0406/c/Application-Level-Architecture/Instruction-Details/Encoding-of-lists-of-ARM-core-registers +[2] https://developer.arm.com/documentation/ddi0597/2024-09/T32-Instructions-by-Encoding/16-bit?lang=en#pushpop16 +--- + gdb/arm-tdep.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c +index f36ce631a08..d898a426609 100644 +--- a/gdb/arm-tdep.c ++++ b/gdb/arm-tdep.c +@@ -13561,9 +13561,12 @@ thumb_record_misc (arm_insn_decode_record *thumb_insn_r) + record_buf[0] = bits (thumb_insn_r->arm_insn, 0, 2); + thumb_insn_r->reg_rec_count = 1; + break; +- case 4: /* fall through */ + case 5: +- /* PUSH. */ ++ /* PUSH with lr. */ ++ register_count++; ++ [[fallthrough]]; ++ case 4: ++ /* PUSH without lr. */ + register_bits = bits (thumb_insn_r->arm_insn, 0, 7); + regcache_raw_read_unsigned (reg_cache, ARM_SP_REGNUM, &u_regval); + while (register_bits) +@@ -13572,8 +13575,7 @@ thumb_record_misc (arm_insn_decode_record *thumb_insn_r) + register_count++; + register_bits = register_bits >> 1; + } +- start_address = u_regval - \ +- (4 * (bit (thumb_insn_r->arm_insn, 8) + register_count)); ++ start_address = u_regval - (4 * register_count); + thumb_insn_r->mem_rec_count = register_count; + while (register_count) + { +-- +2.43.0 + diff --git a/gdb-tdep-fix-reverse-execution-of-ldr-immediate-t4.patch b/gdb-tdep-fix-reverse-execution-of-ldr-immediate-t4.patch deleted file mode 100644 index 106bb08..0000000 --- a/gdb-tdep-fix-reverse-execution-of-ldr-immediate-t4.patch +++ /dev/null @@ -1,80 +0,0 @@ -From b8a8f319b30149f94823302d9120d83b9eee01a4 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Tue, 13 Feb 2024 09:10:54 +0100 -Subject: [PATCH 23/48] [gdb/tdep] Fix reverse execution of LDR(immediate) T4 - -When running test-case gdb.reverse/func-map-to-same-line.exp on arm-linux with -target board unix/-mthumb, we run into: -... -(gdb) reverse-step -func2 () at func-map-to-same-line.c:26 -26 { -(gdb) FAIL: gdb.reverse/func-map-to-same-line.exp: \ - column_info_flag=column-info: step-test: reverse-step into func2 -... - -The FAIL is caused by incorrect recording of this insn: -... -4f6: f85d 7b04 ldr.w r7, [sp], #4 -... - -The insn updates the sp, but we don't record this: -... -$ gdb -q -batch func-map-to-same-line \ - -ex "b *func2+8" \ - -ex run \ - -ex record \ - -ex "set debug record 2" \ - -ex stepi -Breakpoint 1 at 0x4f6: file func-map-to-same-line.c, line 27. - -Breakpoint 1, 0xaaaaa4f6 in func2 () at func-map-to-same-line.c:27 -27 } /* END FUNC2 */ -Process record: arm_process_record addr = 0xaaaaa4f6 -Process record: add register num = 15 to record list. -Process record: record_full_arch_list_add 0xabc6c460. -Process record: add register num = 7 to record list. -Process record: record_full_arch_list_add 0xabc3b868. -Process record: add register num = 25 to record list. -... -[ Note that sp is r13, and we see here only r15 (pc), r7, and r25 (ps). ] - -The problem is that the specific insn, an LDR(immediate) T4, is not handled in -thumb2_record_ld_word. - -Fix this by detecting the insn in thumb2_record_ld_word, and recording the -updated base register. - -Tested on arm-linux. - -Reported-By: Thiago Jung Bauermann -Approved-By: Luis Machado - -PR tdep/31278 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31278 ---- - gdb/arm-tdep.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c -index 04392115848..3b1682a2aea 100644 ---- a/gdb/arm-tdep.c -+++ b/gdb/arm-tdep.c -@@ -14156,6 +14156,14 @@ thumb2_record_ld_word (arm_insn_decode_record *thumb2_insn_r) - record_buf[1] = ARM_PS_REGNUM; - thumb2_insn_r->reg_rec_count = 2; - -+ if ((thumb2_insn_r->arm_insn & 0xfff00900) == 0xf8500900) -+ { -+ /* Detected LDR(immediate), T4, with write-back bit set. Record Rn -+ update. */ -+ record_buf[2] = bits (thumb2_insn_r->arm_insn, 16, 19); -+ thumb2_insn_r->reg_rec_count++; -+ } -+ - REG_ALLOC (thumb2_insn_r->arm_regs, thumb2_insn_r->reg_rec_count, - record_buf); - return ARM_RECORD_SUCCESS; --- -2.35.3 - diff --git a/gdb-tdep-handle-sycall-statx-for-arm-linux.patch b/gdb-tdep-handle-sycall-statx-for-arm-linux.patch new file mode 100644 index 0000000..b8981d5 --- /dev/null +++ b/gdb-tdep-handle-sycall-statx-for-arm-linux.patch @@ -0,0 +1,46 @@ +From 559ec501f594101dd786ce7dad1c89069934c965 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Wed, 13 Nov 2024 19:37:04 +0100 +Subject: [PATCH 14/46] [gdb/tdep] Handle sycall statx for arm-linux + +When running test-case gdb.reverse/fstatat-reverse.exp on arm-linux, I run +into: +... +(gdb) continue^M +Continuing.^M +Process record and replay target doesn't support syscall number 397^M +Process record does not support instruction 0xdf00 at address 0xf7ebf774.^M +Process record: failed to record execution log.^M +^M +Program stopped.^M +0xf7ebf774 in ?? () from /lib/arm-linux-gnueabihf/libc.so.6^M +(gdb) FAIL: gdb.reverse/fstatat-reverse.exp: continue to breakpoint: marker2 +... + +Syscall number 397 stands for statx on arm-linux. + +Fix this by handling 397 in arm_canonicalize_syscall. + +Tested on arm-linux. + +Reviewed-By: Guinevere Larsen +Approved-By: Luis Machado +--- + gdb/arm-linux-tdep.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c +index 43869e4fcfe..bb3d808bd5a 100644 +--- a/gdb/arm-linux-tdep.c ++++ b/gdb/arm-linux-tdep.c +@@ -1644,6 +1644,7 @@ arm_canonicalize_syscall (int syscall) + case 379: return gdb_sys_finit_module; + */ + case 384: return gdb_sys_getrandom; ++ case 397: return gdb_sys_statx; + case 983041: /* ARM_breakpoint */ return gdb_sys_no_syscall; + case 983042: /* ARM_cacheflush */ return gdb_sys_no_syscall; + case 983043: /* ARM_usr26 */ return gdb_sys_no_syscall; +-- +2.43.0 + diff --git a/gdb-tdep-handle-syscall-clock_gettime64-for-arm-linu.patch b/gdb-tdep-handle-syscall-clock_gettime64-for-arm-linu.patch new file mode 100644 index 0000000..ce2e115 --- /dev/null +++ b/gdb-tdep-handle-syscall-clock_gettime64-for-arm-linu.patch @@ -0,0 +1,80 @@ +From 522e3a4837eaef79fc255b29c5ed75fc6f817ce1 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Wed, 13 Nov 2024 22:41:35 +0100 +Subject: [PATCH 16/46] [gdb/tdep] Handle syscall clock_gettime64 for arm-linux + +When running test-case gdb.reverse/time-reverse.exp on arm-linux, I run into: +... +(gdb) continue^M +Continuing.^M +Process record and replay target doesn't support syscall number 403^M +Process record does not support instruction 0xdf00 at address 0xf7ebf774.^M +Process record: failed to record execution log.^M +^M +Program stopped.^M +0xf7ebf774 in ?? () from /lib/arm-linux-gnueabihf/libc.so.6^M +(gdb) FAIL: $exp: mode=c: continue to breakpoint: marker2 +... + +Syscall number 403 stands for clock_gettime64 on arm-linux. + +Fix this by handling 403 in arm_canonicalize_syscall, and handling +gdb_sys_clock_gettime64 elsewhere. + +Since i386_canonicalize_syscall is the identity function, enum value +gdb_sys_clock_gettime64 gets a value to match i386, which also happens to be +403. + +Tested on arm-linux. + +Approved-By: Guinevere Larsen (record-full) +--- + gdb/arm-linux-tdep.c | 1 + + gdb/linux-record.c | 6 ++++++ + gdb/linux-record.h | 1 + + 3 files changed, 8 insertions(+) + +diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c +index bb3d808bd5a..4dc8f00d8c2 100644 +--- a/gdb/arm-linux-tdep.c ++++ b/gdb/arm-linux-tdep.c +@@ -1645,6 +1645,7 @@ arm_canonicalize_syscall (int syscall) + */ + case 384: return gdb_sys_getrandom; + case 397: return gdb_sys_statx; ++ case 403: return gdb_sys_clock_gettime64; + case 983041: /* ARM_breakpoint */ return gdb_sys_no_syscall; + case 983042: /* ARM_cacheflush */ return gdb_sys_no_syscall; + case 983043: /* ARM_usr26 */ return gdb_sys_no_syscall; +diff --git a/gdb/linux-record.c b/gdb/linux-record.c +index 549ea1bd713..33efa026a53 100644 +--- a/gdb/linux-record.c ++++ b/gdb/linux-record.c +@@ -1820,6 +1820,12 @@ Do you want to stop the program?"), + return -1; + break; + ++ case gdb_sys_clock_gettime64: ++ /* Size of struct __timespec64 is 16. */ ++ if (record_mem_at_reg (regcache, tdep->arg2, 16)) ++ return -1; ++ break; ++ + case gdb_sys_clock_getres: + if (record_mem_at_reg (regcache, tdep->arg2, tdep->size_timespec)) + return -1; +diff --git a/gdb/linux-record.h b/gdb/linux-record.h +index 962cedc3d34..54696124bf2 100644 +--- a/gdb/linux-record.h ++++ b/gdb/linux-record.h +@@ -512,6 +512,7 @@ enum gdb_syscall { + gdb_sys_inotify_init1 = 332, + gdb_sys_getrandom = 355, + gdb_sys_statx = 383, ++ gdb_sys_clock_gettime64 = 403, + gdb_sys_socket = 500, + gdb_sys_connect = 501, + gdb_sys_accept = 502, +-- +2.43.0 + diff --git a/gdb-test-bt-cfi-without-die.patch b/gdb-test-bt-cfi-without-die.patch deleted file mode 100644 index 29b6bc0..0000000 --- a/gdb-test-bt-cfi-without-die.patch +++ /dev/null @@ -1,214 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Fedora GDB patches -Date: Fri, 27 Oct 2017 21:07:50 +0200 -Subject: gdb-test-bt-cfi-without-die.patch - -;; [delayed-symfile] Test a backtrace regression on CFIs without DIE (BZ 614604). -;;=fedoratest - -http://sourceware.org/ml/archer/2010-q3/msg00028.html - -On Wed, 25 Feb 2009 00:14:29 +0100, Jan Kratochvil wrote: -> commit 6a37c2b9962258ecf9299cc34a650e64a06acaa5 -> -> There was a regression on gdb.base/savedregs.exp. -> -> quick_addrmap/require_partial_symbols should be used even for the unwind debug -> info checking as its load has been also delayed by this branch. -[...] -> --- a/gdb/dwarf2-frame.c -> +++ b/gdb/dwarf2-frame.c -[...] -> @@ -1499,6 +1500,14 @@ dwarf2_frame_find_fde (CORE_ADDR *pc) -> struct dwarf2_fde *fde; -> CORE_ADDR offset; -> -> + if (objfile->quick_addrmap) -> + { -> + if (!addrmap_find (objfile->quick_addrmap, *pc)) -> + continue; -> + } -> + /* FIXME: Read-in only .debug_frame/.eh_frame without .debug_info? */ -> + require_partial_symbols (objfile); -> + - -but this has caused a different regression (as discussed in the confcall). - -QUICK_ADDRMAP is built only from .debug_aranges. But we can have existing -built .debug_aranges for CUs in OBJFILE but still some CUs do not need to have -DWARF at all while they can feature CFIs (.eh_frame or .debug_frame). -It has been described by Daniel Jacobowitz at: - Re: [2/4] RFC: check psymtabs_addrmap before reading FDEs - http://sourceware.org/ml/gdb-patches/2010-07/msg00012.html - -Sorry for this regression by me (in that fix of a different regression). - -Fixed it the "slow way" as this branch is now obsoleted by .gdb-index. - -No regressions on {x86_64,x86_64-m32,i686}-fedora13-linux-gnu. - -Checked-in. - -Thanks, -Jan - -eb8df8566acc1ed963e3e9b77c13b9c2c3db03fb - -Test CFI is parsed even for range (function) not described by any DIE. - -https://bugzilla.redhat.com/show_bug.cgi?id=614028 - -gdb/ - * dwarf2-frame.c (dwarf2_frame_find_fde): Remove the - OBJFILE->QUICK_ADDRMAP check. New comment why. - -gdb/testsuite/ - * gdb.base/cfi-without-die.exp, gdb.base/cfi-without-die-main.c, - gdb.base/cfi-without-die-caller.c: New files. - -diff --git a/gdb/testsuite/gdb.base/cfi-without-die-caller.c b/gdb/testsuite/gdb.base/cfi-without-die-caller.c -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.base/cfi-without-die-caller.c -@@ -0,0 +1,28 @@ -+/* This testcase is part of GDB, the GNU debugger. -+ -+ Copyright 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. -+ -+ 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 . */ -+ -+typedef int (*callback_t) (void); -+ -+int -+caller (callback_t callback) -+{ -+ /* Ensure some frame content to push away the return address. */ -+ volatile const long one = 1; -+ -+ /* Modify the return value to prevent any tail-call optimization. */ -+ return (*callback) () - one; -+} -diff --git a/gdb/testsuite/gdb.base/cfi-without-die-main.c b/gdb/testsuite/gdb.base/cfi-without-die-main.c -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.base/cfi-without-die-main.c -@@ -0,0 +1,32 @@ -+/* This testcase is part of GDB, the GNU debugger. -+ -+ Copyright 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. -+ -+ 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 . */ -+ -+typedef int (*callback_t) (void); -+ -+extern int caller (callback_t callback); -+ -+int -+callback (void) -+{ -+ return 1; -+} -+ -+int -+main (void) -+{ -+ return caller (callback); -+} -diff --git a/gdb/testsuite/gdb.base/cfi-without-die.exp b/gdb/testsuite/gdb.base/cfi-without-die.exp -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.base/cfi-without-die.exp -@@ -0,0 +1,71 @@ -+# Copyright 2010 Free Software Foundation, Inc. -+ -+# 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 . -+ -+# Test CFI is parsed even for range (function) not described by any DIE. -+ -+set testfile cfi-without-die -+set srcmainfile ${testfile}-main.c -+set srccallerfile ${testfile}-caller.c -+set executable ${testfile} -+set objmainfile [standard_output_file ${testfile}-main.o] -+set objcallerfile [standard_output_file ${testfile}-caller.o] -+set binfile [standard_output_file ${executable}] -+ -+if { [gdb_compile "${srcdir}/${subdir}/${srccallerfile}" ${objcallerfile} \ -+ object [list {additional_flags=-fomit-frame-pointer -fno-unwind-tables -fno-asynchronous-unwind-tables}]] != "" -+ || [gdb_compile "${srcdir}/${subdir}/${srcmainfile}" ${objmainfile} object {debug}] != "" -+ || [gdb_compile "${objmainfile} ${objcallerfile}" ${binfile} executable {}] != "" } { -+ untested ${testfile}.exp -+ return -1 -+} -+ -+clean_restart $executable -+ -+if ![runto callback] then { -+ fail "verify unwinding: Can't run to callback" -+ return 0 -+} -+set test "verify unwinding breaks without CFI" -+gdb_test_multiple "bt" $test { -+ -re " in \[?\]\[?\] .*\r\n$gdb_prompt $" { -+ # It may backtrace through some random frames even to main(). -+ pass $test -+ } -+ -re " in main .*\r\n$gdb_prompt $" { -+ fail $test -+ } -+ -re "\r\n$gdb_prompt $" { -+ pass $test -+ } -+} -+ -+if { [gdb_compile "${srcdir}/${subdir}/${srccallerfile}" ${objcallerfile} \ -+ object [list {additional_flags=-fomit-frame-pointer -funwind-tables -fasynchronous-unwind-tables}]] != "" -+ || [gdb_compile "${srcdir}/${subdir}/${srcmainfile}" ${objmainfile} object {debug}] != "" -+ || [gdb_compile "${objmainfile} ${objcallerfile}" ${binfile} executable {}] != "" } { -+ untested ${testfile}.exp -+ return -1 -+} -+ -+clean_restart $executable -+ -+if ![runto callback] then { -+ fail "test CFI without DIEs: Can't run to callback" -+ return 0 -+} -+# #0 callback () at ... -+# #1 0x00000000004004e9 in caller () -+# #2 0x00000000004004cd in main () at ... -+gdb_test "bt" "#0 +callback \[^\r\n\]+\r\n#1 \[^\r\n\]+ in caller \[^\r\n\]+\r\n#2 \[^\r\n\]+ in main \[^\r\n\]+" "verify unwindin works for CFI without DIEs" diff --git a/gdb-test-dw2-aranges.patch b/gdb-test-dw2-aranges.patch deleted file mode 100644 index d88d3f4..0000000 --- a/gdb-test-dw2-aranges.patch +++ /dev/null @@ -1,220 +0,0 @@ -From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 -From: Fedora GDB patches -Date: Fri, 27 Oct 2017 21:07:50 +0200 -Subject: gdb-test-dw2-aranges.patch - -;; [archer-tromey-delayed-symfile] New test gdb.dwarf2/dw2-aranges.exp. -;;=fedoratest - -[archer-tromey-delayed-symfile] - -commit 77fa7778a37b0d28a7e4e5235f074a10ecf1815d -Author: Jan Kratochvil -Date: Sat Aug 15 15:05:54 2009 +0200 - - Test for "handle incorrect aranges". - - readelf: - Contents of the .debug_aranges section: - - Length: 8 - Version: 2 - Offset into .debug_info: 0x0 - Pointer Size: 0 - Segment Size: 0 - - Address Length - Floating point exception - - * gdb.dwarf2/dw2-aranges.exp, gdb.dwarf2/dw2-aranges.S: New files. - -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-aranges.S b/gdb/testsuite/gdb.dwarf2/dw2-aranges.S -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.dwarf2/dw2-aranges.S -@@ -0,0 +1,140 @@ -+/* This testcase is part of GDB, the GNU debugger. -+ -+ Copyright 2004, 2007, 2008, 2009 Free Software Foundation, Inc. -+ -+ 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 . */ -+ -+/* Test .debug_aranges containing zero address_size. */ -+ -+/* Dummy function to provide debug information for. */ -+ -+ .text -+.Lbegin_text1: -+ .globl main -+ .type main, %function -+main: -+.Lbegin_main: -+ .int 0 -+.Lend_main: -+ .size main, .-main -+.Lend_text1: -+ -+/* Debug information */ -+ -+ .section .debug_info -+.Lcu1_begin: -+ /* CU header */ -+ .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */ -+.Lcu1_start: -+ .2byte 2 /* DWARF Version */ -+ .4byte .Labbrev1_begin /* Offset into abbrev section */ -+ .byte 4 /* Pointer size */ -+ -+ /* CU die */ -+ .uleb128 1 /* Abbrev: DW_TAG_compile_unit */ -+ .4byte .Lend_text1 /* DW_AT_high_pc */ -+ .4byte .Lbegin_text1 /* DW_AT_low_pc */ -+ .ascii "file1.txt\0" /* DW_AT_name */ -+ .ascii "GNU C 3.3.3\0" /* DW_AT_producer */ -+ .byte 1 /* DW_AT_language (C) */ -+ -+ /* main */ -+ .uleb128 2 /* Abbrev: DW_TAG_subprogram */ -+ .byte 1 /* DW_AT_external */ -+ .byte 1 /* DW_AT_decl_file */ -+ .byte 2 /* DW_AT_decl_line */ -+ .ascii "main\0" /* DW_AT_name */ -+ .4byte .Ltype_int-.Lcu1_begin /* DW_AT_type */ -+ .4byte .Lbegin_main /* DW_AT_low_pc */ -+ .4byte .Lend_main /* DW_AT_high_pc */ -+ .byte 1 /* DW_AT_frame_base: length */ -+ .byte 0x55 /* DW_AT_frame_base: DW_OP_reg5 */ -+ -+.Ltype_int: -+ .uleb128 3 /* Abbrev: DW_TAG_base_type */ -+ .ascii "int\0" /* DW_AT_name */ -+ .byte 4 /* DW_AT_byte_size */ -+ .byte 5 /* DW_AT_encoding */ -+ -+ .byte 0 /* End of children of CU */ -+ -+.Lcu1_end: -+ -+/* Abbrev table */ -+ .section .debug_abbrev -+.Labbrev1_begin: -+ .uleb128 1 /* Abbrev code */ -+ .uleb128 0x11 /* DW_TAG_compile_unit */ -+ .byte 1 /* has_children */ -+ .uleb128 0x12 /* DW_AT_high_pc */ -+ .uleb128 0x1 /* DW_FORM_addr */ -+ .uleb128 0x11 /* DW_AT_low_pc */ -+ .uleb128 0x1 /* DW_FORM_addr */ -+ .uleb128 0x3 /* DW_AT_name */ -+ .uleb128 0x8 /* DW_FORM_string */ -+ .uleb128 0x25 /* DW_AT_producer */ -+ .uleb128 0x8 /* DW_FORM_string */ -+ .uleb128 0x13 /* DW_AT_language */ -+ .uleb128 0xb /* DW_FORM_data1 */ -+ .byte 0x0 /* Terminator */ -+ .byte 0x0 /* Terminator */ -+ -+ .uleb128 2 /* Abbrev code */ -+ .uleb128 0x2e /* DW_TAG_subprogram */ -+ .byte 0 /* has_children */ -+ .uleb128 0x3f /* DW_AT_external */ -+ .uleb128 0xc /* DW_FORM_flag */ -+ .uleb128 0x3a /* DW_AT_decl_file */ -+ .uleb128 0xb /* DW_FORM_data1 */ -+ .uleb128 0x3b /* DW_AT_decl_line */ -+ .uleb128 0xb /* DW_FORM_data1 */ -+ .uleb128 0x3 /* DW_AT_name */ -+ .uleb128 0x8 /* DW_FORM_string */ -+ .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 0x1 /* DW_FORM_addr */ -+ .uleb128 0x40 /* DW_AT_frame_base */ -+ .uleb128 0xa /* DW_FORM_block1 */ -+ .byte 0x0 /* Terminator */ -+ .byte 0x0 /* Terminator */ -+ -+ .uleb128 3 /* Abbrev code */ -+ .uleb128 0x24 /* DW_TAG_base_type */ -+ .byte 0 /* has_children */ -+ .uleb128 0x3 /* DW_AT_name */ -+ .uleb128 0x8 /* DW_FORM_string */ -+ .uleb128 0xb /* DW_AT_byte_size */ -+ .uleb128 0xb /* DW_FORM_data1 */ -+ .uleb128 0x3e /* DW_AT_encoding */ -+ .uleb128 0xb /* DW_FORM_data1 */ -+ .byte 0x0 /* Terminator */ -+ .byte 0x0 /* Terminator */ -+ -+ .byte 0x0 /* Terminator */ -+ .byte 0x0 /* Terminator */ -+ -+/* aranges table */ -+ .section .debug_aranges -+ .long .Laranges_end - 1f -+1: -+ .2byte 2 /* aranges Version */ -+ .4byte .Lcu1_begin - .debug_info /* Offset into .debug_info section */ -+ /* The GDB crasher is this zero value. */ -+ .byte 0 /* aranges address_size */ -+ .byte 0 /* aranges segment_size */ -+ -+.Laranges_end: -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-aranges.exp b/gdb/testsuite/gdb.dwarf2/dw2-aranges.exp -new file mode 100644 ---- /dev/null -+++ b/gdb/testsuite/gdb.dwarf2/dw2-aranges.exp -@@ -0,0 +1,40 @@ -+# Copyright 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. -+ -+# 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 . -+ -+# Test .debug_aranges containing zero address_size. -+ -+# This test can only be run on targets which support DWARF-2 and use gas. -+# For now pick a sampling of likely targets. -+if {![istarget *-*-linux*] -+ && ![istarget *-*-gnu*] -+ && ![istarget *-*-elf*] -+ && ![istarget *-*-openbsd*] -+ && ![istarget arm-*-eabi*] -+ && ![istarget powerpc-*-eabi*]} { -+ return 0 -+} -+ -+set testfile "dw2-aranges" -+set srcfile ${testfile}.S -+set binfile [standard_output_file ${testfile}] -+ -+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {nodebug}] != "" } { -+ return -1 -+} -+ -+clean_restart $testfile -+ -+# Failed gdb_load would abort the testcase execution earlier. -+pass "file loaded" diff --git a/gdb-testsuite-add-gdb.arch-s390-disassemble.exp.patch b/gdb-testsuite-add-gdb.arch-s390-disassemble.exp.patch index 329c8e1..17b12ae 100644 --- a/gdb-testsuite-add-gdb.arch-s390-disassemble.exp.patch +++ b/gdb-testsuite-add-gdb.arch-s390-disassemble.exp.patch @@ -1,7 +1,7 @@ -From 5fec5396aebcd41c2a2e92f44fbf0ea26507fca3 Mon Sep 17 00:00:00 2001 +From 29bcee2db6233ff0ea4fc9231910bb2da530308e Mon Sep 17 00:00:00 2001 From: Tom de Vries Date: Thu, 6 Mar 2025 21:19:39 +0100 -Subject: [PATCH 28/28] [gdb/testsuite] Add gdb.arch/s390-disassemble.exp +Subject: [PATCH 10/10] [gdb/testsuite] Add gdb.arch/s390-disassemble.exp In commit a98a6fa2d8e ("s390: Add arch15 instructions"), support for new instructions was added to libopcodes, but the added tests only exercise diff --git a/gdb-testsuite-add-gdb.dwarf2-backward-spec-inter-cu..patch b/gdb-testsuite-add-gdb.dwarf2-backward-spec-inter-cu..patch deleted file mode 100644 index 85f633f..0000000 --- a/gdb-testsuite-add-gdb.dwarf2-backward-spec-inter-cu..patch +++ /dev/null @@ -1,128 +0,0 @@ -From 088088cf78b937cff973c95ec6da2d86ea173b48 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Sun, 24 Sep 2023 12:30:10 +0200 -Subject: [PATCH 07/13] [gdb/testsuite] Add - gdb.dwarf2/backward-spec-inter-cu.exp - -Add another regression test for PR symtab/30846. - -Tested on x86_64-linux. - -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30846 ---- - .../gdb.dwarf2/backward-spec-inter-cu.exp | 103 ++++++++++++++++++ - 1 file changed, 103 insertions(+) - create mode 100644 gdb/testsuite/gdb.dwarf2/backward-spec-inter-cu.exp - -diff --git a/gdb/testsuite/gdb.dwarf2/backward-spec-inter-cu.exp b/gdb/testsuite/gdb.dwarf2/backward-spec-inter-cu.exp -new file mode 100644 -index 00000000000..59b3db50dbb ---- /dev/null -+++ b/gdb/testsuite/gdb.dwarf2/backward-spec-inter-cu.exp -@@ -0,0 +1,103 @@ -+# Copyright 2023 Free Software Foundation, Inc. -+ -+# 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 . -+ -+# Check that the DWARF reader works with a a DW_AT_specification that -+# refers to an earlier DIE. Inter-cu variant of forward-spec.exp. -+ -+load_lib dwarf.exp -+ -+# This test can only be run on targets which support DWARF-2 and use gas. -+require dwarf2_support -+ -+standard_testfile main.c -debug.S -+ -+# Set up the DWARF for the test. -+set asm_file [standard_output_file $srcfile2] -+Dwarf::assemble $asm_file { -+ global srcfile -+ -+ declare_labels spec -+ -+ cu {} { -+ DW_TAG_compile_unit { -+ {DW_AT_language @DW_LANG_C_plus_plus} -+ } { -+ declare_labels myint -+ -+ myint: DW_TAG_base_type { -+ {DW_AT_byte_size 4 DW_FORM_sdata} -+ {DW_AT_encoding @DW_ATE_signed} -+ {DW_AT_name myint} -+ } -+ -+ DW_TAG_namespace { -+ {DW_AT_name ns} -+ } { -+ spec: DW_TAG_variable { -+ {DW_AT_name v} -+ {DW_AT_type :$myint} -+ {DW_AT_declaration 1 DW_FORM_flag_present} -+ } -+ } -+ } -+ } -+ -+ cu {} { -+ DW_TAG_compile_unit { -+ {DW_AT_language @DW_LANG_C_plus_plus} -+ } { -+ # The new indexer has special code to compute the full -+ # name of an object that uses a specification that appears -+ # later in the DWARF. -+ DW_TAG_variable { -+ {DW_AT_specification %$spec} -+ {DW_AT_location { -+ DW_OP_const1u 23 -+ DW_OP_stack_value -+ } SPECIAL_expr} -+ } -+ } -+ } -+} -+ -+if {[build_executable "failed to build executable" ${testfile} \ -+ [list $srcfile $asm_file] {nodebug}]} { -+ return -1 -+} -+ -+set eol "\r\n" -+set ws "\[ \t\]" -+ -+set worker_threads_list {} -+ -+# Exercises the intra-shard case. -+lappend worker_threads_list 0 -+ -+# Might exercise the inter-shard case. -+lappend worker_threads_list default -+ -+foreach_with_prefix worker_threads $worker_threads_list { -+ -+ clean_restart -+ -+ if { $worker_threads != "default" } { -+ gdb_test_no_output "maint set worker-threads $worker_threads" -+ } -+ -+ gdb_load $binfile -+ -+ gdb_test "maint print objfiles" "$eol$ws+qualified:$ws+ns::v$eol.*" \ -+ "v has parent ns" -+} --- -2.35.3 - diff --git a/gdb-testsuite-add-gdb.dwarf2-forward-spec-inter-cu.e.patch b/gdb-testsuite-add-gdb.dwarf2-forward-spec-inter-cu.e.patch deleted file mode 100644 index cd0ea71..0000000 --- a/gdb-testsuite-add-gdb.dwarf2-forward-spec-inter-cu.e.patch +++ /dev/null @@ -1,128 +0,0 @@ -From a022afb07305b50fd6372015bef6c51ae461c6a9 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Sun, 24 Sep 2023 12:33:59 +0200 -Subject: [PATCH 06/13] [gdb/testsuite] Add - gdb.dwarf2/forward-spec-inter-cu.exp - -Add a regression test for PR symtab/30846. - -Tested on x86_64-linux. - -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30846 ---- - .../gdb.dwarf2/forward-spec-inter-cu.exp | 103 ++++++++++++++++++ - 1 file changed, 103 insertions(+) - create mode 100644 gdb/testsuite/gdb.dwarf2/forward-spec-inter-cu.exp - -diff --git a/gdb/testsuite/gdb.dwarf2/forward-spec-inter-cu.exp b/gdb/testsuite/gdb.dwarf2/forward-spec-inter-cu.exp -new file mode 100644 -index 00000000000..d8367b0a162 ---- /dev/null -+++ b/gdb/testsuite/gdb.dwarf2/forward-spec-inter-cu.exp -@@ -0,0 +1,103 @@ -+# Copyright 2023 Free Software Foundation, Inc. -+ -+# 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 . -+ -+# Check that the DWARF reader works with a a DW_AT_specification that -+# refers to a later DIE. Inter-cu variant of forward-spec.exp. -+ -+load_lib dwarf.exp -+ -+# This test can only be run on targets which support DWARF-2 and use gas. -+require dwarf2_support -+ -+standard_testfile main.c -debug.S -+ -+# Set up the DWARF for the test. -+set asm_file [standard_output_file $srcfile2] -+Dwarf::assemble $asm_file { -+ global srcfile -+ -+ declare_labels spec -+ -+ cu {} { -+ DW_TAG_compile_unit { -+ {DW_AT_language @DW_LANG_C_plus_plus} -+ } { -+ # The new indexer has special code to compute the full -+ # name of an object that uses a specification that appears -+ # later in the DWARF. -+ DW_TAG_variable { -+ {DW_AT_specification %$spec} -+ {DW_AT_location { -+ DW_OP_const1u 23 -+ DW_OP_stack_value -+ } SPECIAL_expr} -+ } -+ } -+ } -+ -+ cu {} { -+ DW_TAG_compile_unit { -+ {DW_AT_language @DW_LANG_C_plus_plus} -+ } { -+ declare_labels myint -+ -+ myint: DW_TAG_base_type { -+ {DW_AT_byte_size 4 DW_FORM_sdata} -+ {DW_AT_encoding @DW_ATE_signed} -+ {DW_AT_name myint} -+ } -+ -+ DW_TAG_namespace { -+ {DW_AT_name ns} -+ } { -+ spec: DW_TAG_variable { -+ {DW_AT_name v} -+ {DW_AT_type :$myint} -+ {DW_AT_declaration 1 DW_FORM_flag_present} -+ } -+ } -+ } -+ } -+} -+ -+if {[build_executable "failed to build executable" ${testfile} \ -+ [list $srcfile $asm_file] {nodebug}]} { -+ return -1 -+} -+ -+set eol "\r\n" -+set ws "\[ \t\]" -+ -+set worker_threads_list {} -+ -+# Exercises the intra-shard case. -+lappend worker_threads_list 0 -+ -+# Might exercise the inter-shard case. -+lappend worker_threads_list default -+ -+foreach_with_prefix worker_threads $worker_threads_list { -+ -+ clean_restart -+ -+ if { $worker_threads != "default" } { -+ gdb_test_no_output "maint set worker-threads $worker_threads" -+ } -+ -+ gdb_load $binfile -+ -+ gdb_test "maint print objfiles" "$eol$ws+qualified:$ws+ns::v$eol.*" \ -+ "v has parent ns" -+} --- -2.35.3 - diff --git a/gdb-testsuite-add-missing-include-in-gdb.base-ctf-pt.patch b/gdb-testsuite-add-missing-include-in-gdb.base-ctf-pt.patch deleted file mode 100644 index 61dfe6b..0000000 --- a/gdb-testsuite-add-missing-include-in-gdb.base-ctf-pt.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 4e9077b7e451bd87e48e9868519079a5a7070106 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Tue, 2 Apr 2024 16:22:46 +0200 -Subject: [PATCH 29/48] [gdb/testsuite] Add missing include in - gdb.base/ctf-ptype.c - -On fedora rawhide, when running test-case gdb.base/ctf-ptype.exp, I get: -... -gdb compile failed, ctf-ptype.c: In function 'main': -ctf-ptype.c:242:29: error: implicit declaration of function 'malloc' \ - [-Wimplicit-function-declaration] - 242 | v_char_pointer = (char *) malloc (1); - | ^~~~~~ -ctf-ptype.c:1:1: note: include '' or provide a declaration of 'malloc' - +++ |+#include - 1 | /* This test program is part of GDB, the GNU debugger. -... - -Fix this by adding the missing include. - -Tested on aarch64-linux. ---- - gdb/testsuite/gdb.base/ctf-ptype.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/gdb/testsuite/gdb.base/ctf-ptype.c b/gdb/testsuite/gdb.base/ctf-ptype.c -index cc4e98a234f..0cea44701b9 100644 ---- a/gdb/testsuite/gdb.base/ctf-ptype.c -+++ b/gdb/testsuite/gdb.base/ctf-ptype.c -@@ -24,6 +24,8 @@ - * First the basic C types. - */ - -+#include -+ - #if !defined (__STDC__) && !defined (_AIX) - #define signed /**/ - #endif -@@ -234,9 +236,6 @@ func_type v_func_type; - - int main () - { -- /* Ensure that malloc is a pointer type; avoid use of "void" and any include files. */ --/* extern char *malloc();*/ -- - /* Some of the tests in ptype.exp require invoking malloc, so make - sure it is linked in to this program. */ - v_char_pointer = (char *) malloc (1); --- -2.35.3 - diff --git a/gdb-testsuite-add-missing-include-in-gdb.base-rtld-s.patch b/gdb-testsuite-add-missing-include-in-gdb.base-rtld-s.patch deleted file mode 100644 index 79b4b4b..0000000 --- a/gdb-testsuite-add-missing-include-in-gdb.base-rtld-s.patch +++ /dev/null @@ -1,47 +0,0 @@ -From a2889f1e3f71589fee9454c0aa772ce1bc540db3 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Thu, 28 Mar 2024 06:51:59 +0100 -Subject: [PATCH 35/48] [gdb/testsuite] Add missing include in - gdb.base/rtld-step.exp - -On fedora rawhide, with test-case gdb.base/rtld-step.exp I get: -... -static-pie-static-libc.c: In function '_start':^M -static-pie-static-libc.c:1:22: error: \ - implicit declaration of function '_exit' [-Wimplicit-function-declaration]^M - 1 | void _start (void) { _exit (0); }^M - | ^~~~~^M -compiler exited with status 1 - ... -UNTESTED: gdb.base/rtld-step.exp: failed to compile \ - (-static-pie not supported or static libc missing) -... - -Fix this by adding the missing include. - -Tested on aarch64-linux. - -Approved-by: Kevin Buettner ---- - gdb/testsuite/gdb.base/rtld-step.exp | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/gdb/testsuite/gdb.base/rtld-step.exp b/gdb/testsuite/gdb.base/rtld-step.exp -index 9a6c76d191a..bd3f89769b8 100644 ---- a/gdb/testsuite/gdb.base/rtld-step.exp -+++ b/gdb/testsuite/gdb.base/rtld-step.exp -@@ -86,7 +86,10 @@ set rtld_flags [list debug additional_flags=[list -static-pie -fPIE \ - -nostdlib -static -lc]] - - if { ![gdb_can_simple_compile static-pie-static-libc \ -- "void _start (void) { _exit (0); }" \ -+ { -+ #include -+ void _start (void) { _exit (0); } -+ } \ - executable $rtld_flags] } { - set reason "-static-pie not supported or static libc missing" - untested "failed to compile ($reason)" --- -2.35.3 - diff --git a/gdb-testsuite-add-missing-includes-in-gdb.trace-coll.patch b/gdb-testsuite-add-missing-includes-in-gdb.trace-coll.patch deleted file mode 100644 index 6793bce..0000000 --- a/gdb-testsuite-add-missing-includes-in-gdb.trace-coll.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 4a08080ba59f4f66bf062a9015f9e51c765b05b5 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Fri, 29 Mar 2024 07:47:30 +0100 -Subject: [PATCH 31/48] [gdb/testsuite] Add missing includes in - gdb.trace/collection.c - -On fedora rawhide, with test-case gdb.trace/collection.exp, I get: -... -gdb compile failed, collection.c: In function 'strings_test_func': -collection.c:227:13: error: implicit declaration of function 'malloc' \ - [-Wimplicit-function-declaration] - 227 | longloc = malloc(500); - | ^~~~~~ -collection.c:1:1: note: \ - include '' or provide a declaration of 'malloc' - +++ |+#include - 1 | /* This testcase is part of GDB, the GNU debugger. - -collection.c:228:3: error: implicit declaration of function 'strcpy' \ - [-Wimplicit-function-declaration] - 228 | strcpy(longloc, ... ); - | ^~~~~~ -collection.c:1:1: note: include '' or provide a declaration of \ - 'strcpy' - +++ |+#include - 1 | /* This testcase is part of GDB, the GNU debugger. -collection.c:230:8: error: implicit declaration of function 'strlen' \ - [-Wimplicit-function-declaration] - 230 | i += strlen (locstr); - | ^~~~~~ -collection.c:230:8: note: include '' or provide a declaration of \ - 'strlen' -... - -Fix this by adding the missing includes. - -Tested on aarch64-linux. - -Approved-By: John Baldwin ---- - gdb/testsuite/gdb.trace/collection.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/gdb/testsuite/gdb.trace/collection.c b/gdb/testsuite/gdb.trace/collection.c -index 3b5484748af..4ef93a3fa33 100644 ---- a/gdb/testsuite/gdb.trace/collection.c -+++ b/gdb/testsuite/gdb.trace/collection.c -@@ -19,6 +19,9 @@ - * Test program for trace collection - */ - -+#include -+#include -+ - /* - * Typedefs - */ --- -2.35.3 - diff --git a/gdb-testsuite-add-missing-no-prompt-anchor-in-gdb.ba.patch b/gdb-testsuite-add-missing-no-prompt-anchor-in-gdb.ba.patch deleted file mode 100644 index b2826a4..0000000 --- a/gdb-testsuite-add-missing-no-prompt-anchor-in-gdb.ba.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 08ce0d63c343f7db9a504d37de25391a997b46e2 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Mon, 8 Jan 2024 13:01:50 +0100 -Subject: [PATCH] [gdb/testsuite] Add missing -no-prompt-anchor in - gdb.base/vfork-follow-parent.exp - -When running test-case gdb.base/vfork-follow-parent.exp it passes fine, but -when running it with "taskset -c 0" I run into: -... -(gdb) inferior 1^M -[Switching to inferior 1 [process 26606] (vfork-follow-parent-exit)]^M -[Switching to thread 1.1 (process 26606)]^M -(gdb) Reading symbols from vfork-follow-parent-exit...^M -FAIL: $exp: exec_file=vfork-follow-parent-exit: target-non-stop=on: \ - non-stop=off: resolution_method=schedule-multiple: inferior 1 (timeout) -... - -Fix this by using -no-prompt-anchor. - -Tested on x86_64-linux. - -PR testsuite/31166 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31166 ---- - gdb/testsuite/gdb.base/vfork-follow-parent.exp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gdb/testsuite/gdb.base/vfork-follow-parent.exp b/gdb/testsuite/gdb.base/vfork-follow-parent.exp -index 89c38001dac..ee6f2835d8e 100644 ---- a/gdb/testsuite/gdb.base/vfork-follow-parent.exp -+++ b/gdb/testsuite/gdb.base/vfork-follow-parent.exp -@@ -64,7 +64,7 @@ proc do_test { resolution_method } { - gdb_test "set schedule-multiple on" - gdb_test "continue" "$::inferior_exited_re normally.*" \ - "continue to end of inferior 2" -- gdb_test "inferior 1" ".*Switching to inferior 1.*" -+ gdb_test -no-prompt-anchor "inferior 1" ".*Switching to inferior 1.*" - gdb_test "print unblock_parent = 1" " = 1" - } else { - error "invalid resolution method: $resolution_method" - -base-commit: 19185006cfe0901da907da4f09fbc197aba976a2 --- -2.35.3 - diff --git a/gdb-testsuite-add-pr-gdb-26967-kfail-in-two-more-tes.patch b/gdb-testsuite-add-pr-gdb-26967-kfail-in-two-more-tes.patch deleted file mode 100644 index 1ee0ff4..0000000 --- a/gdb-testsuite-add-pr-gdb-26967-kfail-in-two-more-tes.patch +++ /dev/null @@ -1,167 +0,0 @@ -From fb2b155e33f5a21259c52685ee9b24f75ac66e75 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Wed, 20 Mar 2024 19:23:48 +0100 -Subject: [PATCH 10/48] [gdb/testsuite] Add PR gdb/26967 KFAIL in two more - test-cases - -On aarch64-linux (debian 12), when running test-case -gdb.base/longjmp-until-in-main.exp, I run into: -... -(gdb) until 33^M -warning: Breakpoint address adjusted from 0x70f727c678928489 to 0xfff727c678928489.^M -Warning:^M -Cannot insert breakpoint 0.^M -Cannot access memory at address 0xfff727c678928489^M -^M -0x0000fffff7e3a580 in siglongjmp () from /lib/aarch64-linux-gnu/libc.so.6^M -(gdb) FAIL: gdb.base/longjmp-until-in-main.exp: until $line, in main -... - -This is PR gdb/26967: no longjmp probe is available: -... -(gdb) info probes stap libc ^longjmp$^M -No probes matched.^M -... -and glibc applies pointer mangling which makes it fairly difficult for gdb to -get the longjmp target. - -There's a KFAIL for this in test-case gdb.base/longjmp.exp, added in commit -b5e7cd5cd3d ("[gdb/testsuite] Add KFAILs in gdb.base/longjmp.exp"). - -Factor out new proc have_longjmp_probe, and use it to add similar KFAIL in -this and one more test-case. - -Tested on aarch64-linux. - -Approved-By: Tom Tromey ---- - .../gdb.base/longjmp-until-in-main.exp | 24 ++++++++++++++++--- - gdb/testsuite/gdb.base/longjmp.exp | 11 +-------- - .../premature-dummy-frame-removal.exp | 22 ++++++++++++++++- - gdb/testsuite/lib/gdb.exp | 19 +++++++++++++++ - 4 files changed, 62 insertions(+), 14 deletions(-) - -diff --git a/gdb/testsuite/gdb.base/longjmp-until-in-main.exp b/gdb/testsuite/gdb.base/longjmp-until-in-main.exp -index c0635f23345..6167989319a 100644 ---- a/gdb/testsuite/gdb.base/longjmp-until-in-main.exp -+++ b/gdb/testsuite/gdb.base/longjmp-until-in-main.exp -@@ -35,10 +35,28 @@ if {![runto_main]} { - return - } - -+set have_longjmp_probe [have_longjmp_probe] -+ - delete_breakpoints - - set until_to_line [gdb_get_line_number "until to here"] - --gdb_test "until $until_to_line" \ -- " until to here .*" \ -- "until \$line, in main" -+set re_cannot_insert_bp \ -+ [multi_line \ -+ "Warning:" \ -+ "Cannot insert breakpoint $::decimal\\." \ -+ "Cannot access memory at address $::hex"] -+ -+set test "until \$line, in main" -+gdb_test_multiple "until $until_to_line" $test { -+ -re -wrap "\r\n$re_cannot_insert_bp\r\n.*" { -+ if { $have_longjmp_probe } { -+ fail $gdb_test_name -+ } else { -+ kfail gdb/26967 $gdb_test_name -+ } -+ } -+ -re -wrap " until to here .*" { -+ pass $gdb_test_name -+ } -+} -diff --git a/gdb/testsuite/gdb.base/longjmp.exp b/gdb/testsuite/gdb.base/longjmp.exp -index f74891aa7ca..0420f4df675 100644 ---- a/gdb/testsuite/gdb.base/longjmp.exp -+++ b/gdb/testsuite/gdb.base/longjmp.exp -@@ -62,16 +62,7 @@ proc do_test { with_probes } { - # - # We detect the different failure modes and kfail these. - -- set have_longjmp_probe 0 -- gdb_test_multiple "info probes stap libc ^longjmp$" "" { -- -re -wrap "No probes matched\\." { -- pass $gdb_test_name -- } -- -re -wrap "\r\nstap\[ \t\]+libc\[ \t\]+longjmp\[ \t\]+.*" { -- pass $gdb_test_name -- set have_longjmp_probe 1 -- } -- } -+ set have_longjmp_probe [have_longjmp_probe] - - if { $with_probes } { - if { !$have_longjmp_probe } { -diff --git a/gdb/testsuite/gdb.base/premature-dummy-frame-removal.exp b/gdb/testsuite/gdb.base/premature-dummy-frame-removal.exp -index fe906cefb14..6979345ee45 100644 ---- a/gdb/testsuite/gdb.base/premature-dummy-frame-removal.exp -+++ b/gdb/testsuite/gdb.base/premature-dummy-frame-removal.exp -@@ -49,7 +49,27 @@ if {![runto_main]} { - set pyfile [gdb_remote_download host ${srcdir}/${subdir}/${testfile}.py] - gdb_test_no_output "source ${pyfile}" "load python file" - --gdb_test "p some_func ()" " = 0" -+set have_longjmp_probe [have_longjmp_probe] -+ -+set re_cannot_insert_bp \ -+ [multi_line \ -+ "Warning:" \ -+ "Cannot insert breakpoint $::decimal\\." \ -+ "Cannot access memory at address $::hex"] -+ -+gdb_test_multiple "p some_func ()" "" { -+ -re -wrap "\r\n$re_cannot_insert_bp\r\n.*" { -+ if { $have_longjmp_probe } { -+ fail $gdb_test_name -+ } else { -+ kfail gdb/26967 $gdb_test_name -+ return 0 -+ } -+ } -+ -re -wrap " = 0" { -+ pass $gdb_test_name -+ } -+} - - # When frame debugging is turned on, this test has (previously) - # revealed some crashes due to the Python frame unwinder trying to -diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp -index 21967550cf6..70c2db4ac84 100644 ---- a/gdb/testsuite/lib/gdb.exp -+++ b/gdb/testsuite/lib/gdb.exp -@@ -4615,6 +4615,25 @@ proc skip_libstdcxx_probe_tests {} { - return [skip_libstdcxx_probe_tests_prompt "$gdb_prompt $"] - } - -+# Return 1 if libc supports the longjmp probe. Note that we're not using -+# gdb_caching_proc because the probe may have been disabled. -+ -+proc have_longjmp_probe {} { -+ set have_probe -1 -+ gdb_test_multiple "info probes stap libc ^longjmp$" "" { -+ -re -wrap "No probes matched\\." { -+ set have_probe 0 -+ } -+ -re -wrap "\r\nstap\[ \t\]+libc\[ \t\]+longjmp\[ \t\]+.*" { -+ set have_probe 1 -+ } -+ } -+ if { $have_probe == -1 } { -+ error "failed to get libc longjmp probe status" -+ } -+ return $have_probe -+} -+ - # Helper for gdb_is_target_* procs. TARGET_NAME is the name of the target - # we're looking for (used to build the test name). TARGET_STACK_REGEXP - # is a regexp that will match the output of "maint print target-stack" if --- -2.35.3 - diff --git a/gdb-testsuite-call-ldd-version-in-gdb.testsuite-dump.patch b/gdb-testsuite-call-ldd-version-in-gdb.testsuite-dump.patch deleted file mode 100644 index a20c617..0000000 --- a/gdb-testsuite-call-ldd-version-in-gdb.testsuite-dump.patch +++ /dev/null @@ -1,39 +0,0 @@ -From dedb6d4ce0478d053b7e786d73f298c8e72f1f99 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Thu, 18 Jan 2024 11:14:19 +0100 -Subject: [PATCH 44/48] [gdb/testsuite] Call ldd --version in - gdb.testsuite/dump-system-info.exp - -Once in a while I'm looking at the gdb.log of an entire testsuite run, and I'm -trying to establish what glibc version is used. Sometimes this is possible, -sometimes not. - -Make this easy by calling ldd --version in test-case -gdb.testsuite/dump-system-info.exp, which for instance on openSUSE Leap 15.4 -gives: -... -$ ldd --version -ldd (GNU libc) 2.31 - ... -$ -... - -Tested on x86_64-linux. - -Approved-By: Tom Tromey ---- - gdb/testsuite/gdb.testsuite/dump-system-info.exp | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/gdb/testsuite/gdb.testsuite/dump-system-info.exp b/gdb/testsuite/gdb.testsuite/dump-system-info.exp -index 1a28b29b1c7..e3eb9eee73a 100644 ---- a/gdb/testsuite/gdb.testsuite/dump-system-info.exp -+++ b/gdb/testsuite/gdb.testsuite/dump-system-info.exp -@@ -36,3 +36,4 @@ proc dump_info {cmd {what ""}} { - dump_info "cat /proc/cpuinfo" "Cpuinfo" - dump_info "uname -a" - dump_info "lsb_release -a" -+dump_info "ldd --version" --- -2.35.3 - diff --git a/gdb-testsuite-check-gnatmake-version-in-gdb.ada-scal.patch b/gdb-testsuite-check-gnatmake-version-in-gdb.ada-scal.patch new file mode 100644 index 0000000..d8e8bfc --- /dev/null +++ b/gdb-testsuite-check-gnatmake-version-in-gdb.ada-scal.patch @@ -0,0 +1,48 @@ +From 889debbb7270408fa96401d5482dc2b9caec494d Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Wed, 8 Jan 2025 16:24:11 +0100 +Subject: [PATCH 05/46] [gdb/testsuite] Check gnatmake version in + gdb.ada/scalar_storage.exp + +On a system with gcc 14.2.0 and gnatmake 13.3.0 I run into: +... +(gdb) PASS: gdb.ada/scalar_storage.exp: print V_LE +get_compiler_info: gcc-14-2-0 +print V_BE^M +$2 = (value => 126, another_value => 12, color => red)^M +(gdb) FAIL: gdb.ada/scalar_storage.exp: print V_BE +... + +The test-case contains a corresponding kfail: +... + # This requires a compiler fix that is in GCC 14. + if {[gcc_major_version] < 14} { + setup_kfail "DW_AT_endianity on enum types" *-*-* + } +... +which doesn't trigger because it checks the gcc version rather than the +gnatmake version. + +Fix this by checking the gnatmake version instead. + +Tested on aarch64-linux and x86_64-linux. +--- + gdb/testsuite/gdb.ada/scalar_storage.exp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gdb/testsuite/gdb.ada/scalar_storage.exp b/gdb/testsuite/gdb.ada/scalar_storage.exp +index e01e75fe5d2..5dccaef8f14 100644 +--- a/gdb/testsuite/gdb.ada/scalar_storage.exp ++++ b/gdb/testsuite/gdb.ada/scalar_storage.exp +@@ -36,7 +36,7 @@ if {![runto "storage.adb:$bp_location"]} { + gdb_test "print V_LE" "= \\(value => 126, another_value => 12, color => green\\)" + + # This requires a compiler fix that is in GCC 14. +-if {[gcc_major_version] < 14} { ++if { ![gnatmake_version_at_least 14] } { + setup_kfail "DW_AT_endianity on enum types" *-*-* + } + gdb_test "print V_BE" "= \\(value => 126, another_value => 12, color => green\\)" +-- +2.43.0 + diff --git a/gdb-testsuite-don-t-use-set-auto-solib-add-off.patch b/gdb-testsuite-don-t-use-set-auto-solib-add-off.patch new file mode 100644 index 0000000..0c410f4 --- /dev/null +++ b/gdb-testsuite-don-t-use-set-auto-solib-add-off.patch @@ -0,0 +1,274 @@ +From 42f3a32877ab455607662c7a12c7a793f3744e4e Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Mon, 10 Jun 2024 10:43:10 +0200 +Subject: [PATCH 08/46] [gdb/testsuite] Don't use set auto-solib-add off + +In test-case gdb.mi/mi-var-child-f.exp, we have: +... +mi_gdb_test "-gdb-set auto-solib-add off" "\\^done" +mi_runto prog_array +mi_gdb_test "nosharedlibrary" ".*\\^done" +... + +This was added to avoid a name clash between the array variable as defined in +gdb.mi/array.f90 and debug info in shared libraries, and used in other places +in the testsuite. + +The same workaround is also used to ignore symbols from shared libraries when +excercising for instance a command that prints all symbols. + +However, this approach can cause problems for targets like arm that require +symbol info for some libraries like ld.so and libc to fully function. + +While absense of debug info for shared libraries should be handled gracefully +(which does need fixing, see PR31817), failure to do so should not result +in failures in unrelated test-cases. + +Fix this by removing "set auto-solib-add off". + +This ensures that we don't run into PR31817, while the presence of +nosharedlibrary still ensures that in the rest of the test-case we're not +bothered by shared library symbols. + +Likewise in other test-cases. + +Approved-by: Kevin Buettner + +Tested on arm-linux. +--- + gdb/testsuite/gdb.base/gold-gdb-index.exp | 4 ++-- + gdb/testsuite/gdb.base/info-types.exp.tcl | 3 ++- + gdb/testsuite/gdb.base/print-symbol-loading.exp | 4 +++- + gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp | 6 ++---- + gdb/testsuite/gdb.fortran/allocated.exp | 3 --- + gdb/testsuite/gdb.fortran/array-slices-bad.exp | 3 --- + gdb/testsuite/gdb.fortran/array-slices-sub-slices.exp | 3 --- + gdb/testsuite/gdb.fortran/array-slices.exp | 3 --- + gdb/testsuite/gdb.fortran/info-modules.exp | 3 --- + gdb/testsuite/gdb.fortran/lbound-ubound.exp | 3 --- + gdb/testsuite/gdb.fortran/module.exp | 3 --- + gdb/testsuite/gdb.fortran/subarray.exp | 3 --- + gdb/testsuite/gdb.mi/mi-fortran-modules.exp | 3 --- + gdb/testsuite/gdb.mi/mi-var-child-f.exp | 3 --- + 14 files changed, 9 insertions(+), 38 deletions(-) + +diff --git a/gdb/testsuite/gdb.base/gold-gdb-index.exp b/gdb/testsuite/gdb.base/gold-gdb-index.exp +index c9c6598c3fa..0309dd353ad 100644 +--- a/gdb/testsuite/gdb.base/gold-gdb-index.exp ++++ b/gdb/testsuite/gdb.base/gold-gdb-index.exp +@@ -32,12 +32,12 @@ if { [have_index $binfile] != "gdb_index" } { + return -1 + } + +-gdb_test_no_output "set auto-solib-add off" +- + if {![runto_main]} { + return 0 + } + ++gdb_test_no_output "nosharedlibrary" ++ + gdb_test_no_output "set breakpoint pending off" + gdb_test "break N1::misspelled" "Function \"N1::misspelled\" not defined\." + +diff --git a/gdb/testsuite/gdb.base/info-types.exp.tcl b/gdb/testsuite/gdb.base/info-types.exp.tcl +index 69d53b9f8de..0a33afedf86 100644 +--- a/gdb/testsuite/gdb.base/info-types.exp.tcl ++++ b/gdb/testsuite/gdb.base/info-types.exp.tcl +@@ -32,12 +32,13 @@ proc run_test { lang } { + "${testfile}" $srcfile "debug $lang"]} { + return -1 + } +- gdb_test_no_output "set auto-solib-add off" + + if ![runto_main] then { + return 0 + } + ++ gdb_test_no_output "nosharedlibrary" ++ + set file_re "File .*[string_to_regexp $srcfile]:" + + if { $lang == "c++" } { +diff --git a/gdb/testsuite/gdb.base/print-symbol-loading.exp b/gdb/testsuite/gdb.base/print-symbol-loading.exp +index b61dba33377..b3520f1e032 100644 +--- a/gdb/testsuite/gdb.base/print-symbol-loading.exp ++++ b/gdb/testsuite/gdb.base/print-symbol-loading.exp +@@ -95,10 +95,12 @@ proc test_load_shlib { print_symbol_loading } { + global gdb_prompt + with_test_prefix "shlib ${print_symbol_loading}" { + clean_restart ${binfile} +- gdb_test_no_output "set auto-solib-add off" + if ![runto_main] { + return -1 + } ++ ++ gdb_test_no_output "nosharedlibrary" ++ + gdb_test_no_output "set print symbol-loading $print_symbol_loading" + set test_name "load shared-lib" + set libc_re \ +diff --git a/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp +index 59840b8d0e2..e2e4f240c88 100644 +--- a/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp ++++ b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp +@@ -29,14 +29,12 @@ proc_with_prefix test_relocated { exec_path lib_path complaint_re readnow_p } { + clean_restart $exec_path + gdb_load_shlib $lib_path + +- # Don't load the symbols for $lib_path during runto_main. +- # Instead, we do this afterwards using "sharedlibrary $lib_path". +- gdb_test_no_output "set auto-solib-add off" +- + if { ![runto_main] } { + return + } + ++ gdb_test_no_output "nosharedlibrary" ++ + # Test for presence of complaint. + with_complaints 1 { + set have_complaint 0 +diff --git a/gdb/testsuite/gdb.fortran/allocated.exp b/gdb/testsuite/gdb.fortran/allocated.exp +index d8aee441d7f..1d87bf76244 100644 +--- a/gdb/testsuite/gdb.fortran/allocated.exp ++++ b/gdb/testsuite/gdb.fortran/allocated.exp +@@ -25,9 +25,6 @@ if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ + return -1 + } + +-# Avoid shared lib symbols. +-gdb_test_no_output "set auto-solib-add off" +- + if ![fortran_runto_main] { + return -1 + } +diff --git a/gdb/testsuite/gdb.fortran/array-slices-bad.exp b/gdb/testsuite/gdb.fortran/array-slices-bad.exp +index 8f23b38599f..ac4a77d2e39 100644 +--- a/gdb/testsuite/gdb.fortran/array-slices-bad.exp ++++ b/gdb/testsuite/gdb.fortran/array-slices-bad.exp +@@ -30,9 +30,6 @@ if {![runto [gdb_get_line_number "First Breakpoint"]]} { + return -1 + } + +-# Avoid shared lib symbols. +-gdb_test_no_output "set auto-solib-add off" +- + # Avoid libc symbols, in particular the 'array' type. + gdb_test_no_output "nosharedlibrary" + +diff --git a/gdb/testsuite/gdb.fortran/array-slices-sub-slices.exp b/gdb/testsuite/gdb.fortran/array-slices-sub-slices.exp +index 5bdc7d59f16..5a0f0406afe 100644 +--- a/gdb/testsuite/gdb.fortran/array-slices-sub-slices.exp ++++ b/gdb/testsuite/gdb.fortran/array-slices-sub-slices.exp +@@ -25,9 +25,6 @@ if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ + return -1 + } + +-# Avoid shared lib symbols. +-gdb_test_no_output "set auto-solib-add off" +- + if ![fortran_runto_main] { + return -1 + } +diff --git a/gdb/testsuite/gdb.fortran/array-slices.exp b/gdb/testsuite/gdb.fortran/array-slices.exp +index f2928676bf3..919a2c6e7eb 100644 +--- a/gdb/testsuite/gdb.fortran/array-slices.exp ++++ b/gdb/testsuite/gdb.fortran/array-slices.exp +@@ -58,9 +58,6 @@ proc run_test { repack } { + + clean_restart ${binfile} + +- # Avoid shared lib symbols. +- gdb_test_no_output "set auto-solib-add off" +- + if ![fortran_runto_main] { + return -1 + } +diff --git a/gdb/testsuite/gdb.fortran/info-modules.exp b/gdb/testsuite/gdb.fortran/info-modules.exp +index e6c515ff70f..c8ae7362223 100644 +--- a/gdb/testsuite/gdb.fortran/info-modules.exp ++++ b/gdb/testsuite/gdb.fortran/info-modules.exp +@@ -28,9 +28,6 @@ if { [prepare_for_testing "failed to prepare" $testfile \ + return -1 + } + +-# Avoid shared lib symbols. +-gdb_test_no_output "set auto-solib-add off" +- + if { ![fortran_runto_main] } { + perror "Could not run to main." + return +diff --git a/gdb/testsuite/gdb.fortran/lbound-ubound.exp b/gdb/testsuite/gdb.fortran/lbound-ubound.exp +index 01597ca23ff..781d3614f4c 100644 +--- a/gdb/testsuite/gdb.fortran/lbound-ubound.exp ++++ b/gdb/testsuite/gdb.fortran/lbound-ubound.exp +@@ -25,9 +25,6 @@ if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ + return -1 + } + +-# Avoid shared lib symbols. +-gdb_test_no_output "set auto-solib-add off" +- + if ![fortran_runto_main] { + return -1 + } +diff --git a/gdb/testsuite/gdb.fortran/module.exp b/gdb/testsuite/gdb.fortran/module.exp +index eea83ad71f1..df7ee3b9605 100644 +--- a/gdb/testsuite/gdb.fortran/module.exp ++++ b/gdb/testsuite/gdb.fortran/module.exp +@@ -31,9 +31,6 @@ gdb_test "p modmany::var_i" " = 14" "stopped language detection" + + gdb_test "print mod1::var_const" " = 20" "fully qualified name of DW_TAG_constant" + +-# Avoid shared lib symbols. +-gdb_test_no_output "set auto-solib-add off" +- + if {![fortran_runto_main]} { + return + } +diff --git a/gdb/testsuite/gdb.fortran/subarray.exp b/gdb/testsuite/gdb.fortran/subarray.exp +index 1ec80e78fe4..70a7a2345ba 100644 +--- a/gdb/testsuite/gdb.fortran/subarray.exp ++++ b/gdb/testsuite/gdb.fortran/subarray.exp +@@ -27,9 +27,6 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} { + return -1 + } + +-# Avoid shared lib symbols. +-gdb_test_no_output "set auto-solib-add off" +- + if {![fortran_runto_main]} { + return + } +diff --git a/gdb/testsuite/gdb.mi/mi-fortran-modules.exp b/gdb/testsuite/gdb.mi/mi-fortran-modules.exp +index 13996b9547f..5441d8f15e5 100644 +--- a/gdb/testsuite/gdb.mi/mi-fortran-modules.exp ++++ b/gdb/testsuite/gdb.mi/mi-fortran-modules.exp +@@ -30,9 +30,6 @@ if {[build_executable "failed to prepare" ${testfile} \ + + mi_clean_restart $binfile + +-# Avoid shared lib symbols. +-mi_gdb_test "-gdb-set auto-solib-add off" "\\^done" +- + mi_runto_main + + # Avoid libc symbols. +diff --git a/gdb/testsuite/gdb.mi/mi-var-child-f.exp b/gdb/testsuite/gdb.mi/mi-var-child-f.exp +index 258cbe7cb40..441c3a09366 100644 +--- a/gdb/testsuite/gdb.mi/mi-var-child-f.exp ++++ b/gdb/testsuite/gdb.mi/mi-var-child-f.exp +@@ -32,9 +32,6 @@ if {[mi_clean_restart $binfile]} { + return + } + +-# Avoid shared lib symbols. +-mi_gdb_test "-gdb-set auto-solib-add off" "\\^done" +- + mi_runto prog_array + + # Avoid libc symbols, in particular the 'array' type. +-- +2.43.0 + diff --git a/gdb-testsuite-factor-out-proc-get_portnum.patch b/gdb-testsuite-factor-out-proc-get_portnum.patch deleted file mode 100644 index bf62489..0000000 --- a/gdb-testsuite-factor-out-proc-get_portnum.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 2e5c943519de45144a880b8ce0d693dfd13f4650 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Sat, 4 May 2024 10:41:09 +0200 -Subject: [PATCH 16/48] [gdb/testsuite] Factor out proc get_portnum - -In gdbserver_start, we have some code that determines what port number to use: -... - # Port id -- either specified in baseboard file, or managed here. - if [target_info exists gdb,socketport] { - set portnum [target_info gdb,socketport] - } else { - # Bump the port number to avoid conflicts with hung ports. - incr portnum - } -... - -Factor this out into a new proc get_portnum. - -Tested on aarch64-linux. - -Approved-By: Tom Tromey ---- - gdb/testsuite/lib/gdbserver-support.exp | 40 ++++++++++++++++++------- - 1 file changed, 29 insertions(+), 11 deletions(-) - -diff --git a/gdb/testsuite/lib/gdbserver-support.exp b/gdb/testsuite/lib/gdbserver-support.exp -index 30d94fd7eb6..8aaca946b7d 100644 ---- a/gdb/testsuite/lib/gdbserver-support.exp -+++ b/gdb/testsuite/lib/gdbserver-support.exp -@@ -129,8 +129,31 @@ proc gdb_target_cmd { args } { - return [expr $res == 0 ? 0 : 1] - } - --global portnum --set portnum "2345" -+# Return a usable port number. -+ -+proc get_portnum {} { -+ if { [target_info exists gdb,socketport] } { -+ # Hard-coded in target board. -+ return [target_info gdb,socketport] -+ } -+ -+ # Not hard-coded in target board. Return increasing port numbers, -+ # starting at $initial_portnum, to avoid conflicts with hung ports. -+ set initial_portnum 2345 -+ -+ # Currently available port number. -+ global portnum -+ -+ # Initialize, if necessary. -+ if { ![info exists portnum] } { -+ set portnum $initial_portnum -+ } -+ -+ # Return currently available port number, and update it. -+ set res $portnum -+ incr portnum -+ return $res -+} - - # Locate the gdbserver binary. Returns "" if gdbserver could not be found. - -@@ -247,16 +270,10 @@ proc gdbserver_default_get_comm_port { port } { - # Returns the target protocol and socket to connect to. - - proc gdbserver_start { options arguments } { -- global portnum - global GDB_TEST_SOCKETHOST - - # Port id -- either specified in baseboard file, or managed here. -- if [target_info exists gdb,socketport] { -- set portnum [target_info gdb,socketport] -- } else { -- # Bump the port number to avoid conflicts with hung ports. -- incr portnum -- } -+ set portnum [get_portnum] - - # Extract the local and remote host ids from the target board struct. - if { [info exists GDB_TEST_SOCKETHOST] } { -@@ -372,10 +389,11 @@ proc gdbserver_start { options arguments } { - -re "Listening on" { } - -re "Can't (bind address|listen on socket): Address already in use\\.\r\n" { - verbose -log "Port $portnum is already in use." -- if ![target_info exists gdb,socketport] { -+ set other_portnum [get_portnum] -+ if { $other_portnum != $portnum } { - # Bump the port number to avoid the conflict. - wait -i $expect_out(spawn_id) -- incr portnum -+ set portnum $other_portnum - continue - } - } --- -2.35.3 - diff --git a/gdb-testsuite-factor-out-proc-lock_dir.patch b/gdb-testsuite-factor-out-proc-lock_dir.patch deleted file mode 100644 index a3aab5c..0000000 --- a/gdb-testsuite-factor-out-proc-lock_dir.patch +++ /dev/null @@ -1,63 +0,0 @@ -From a9cc672af5f81034f4189446aa656c08ea10e2ac Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Sat, 4 May 2024 10:41:09 +0200 -Subject: [PATCH 19/48] [gdb/testsuite] Factor out proc lock_dir - -In lib/rocm.exp we have: -... -set gpu_lock_filename $objdir/gpu-parallel.lock -... - -This decides both the lock file name and directory. - -Factor out a new proc lock_dir that decides on the directory, leaving just: -... -set gpu_lock_filename gpu-parallel.lock -... - -Tested on aarch64-linux. - -Approved-By: Tom Tromey ---- - gdb/testsuite/lib/gdb-utils.exp | 7 +++++++ - gdb/testsuite/lib/rocm.exp | 2 +- - 2 files changed, 8 insertions(+), 1 deletion(-) - -diff --git a/gdb/testsuite/lib/gdb-utils.exp b/gdb/testsuite/lib/gdb-utils.exp -index 3dc4b3a3ebc..63f6b8c3698 100644 ---- a/gdb/testsuite/lib/gdb-utils.exp -+++ b/gdb/testsuite/lib/gdb-utils.exp -@@ -177,10 +177,17 @@ proc lock_file_release {info} { - } - } - -+# Return directory where we keep lock files. -+ -+proc lock_dir {} { -+ return $objdir -+} -+ - # Run body under lock LOCK_FILE. - - proc with_lock { lock_file body } { - if {[info exists ::GDB_PARALLEL]} { -+ set lock_file [file join [lock_dir] $lock_file] - set lock_rc [lock_file_acquire $lock_file] - } - -diff --git a/gdb/testsuite/lib/rocm.exp b/gdb/testsuite/lib/rocm.exp -index 86ec29567da..a6608664f24 100644 ---- a/gdb/testsuite/lib/rocm.exp -+++ b/gdb/testsuite/lib/rocm.exp -@@ -105,7 +105,7 @@ gdb_caching_proc allow_hipcc_tests {} { - - # The lock file used to ensure that only one GDB has access to the GPU - # at a time. --set gpu_lock_filename $objdir/gpu-parallel.lock -+set gpu_lock_filename gpu-parallel.lock - - # Run body under the GPU lock. Also calls gdb_exit before releasing - # the GPU lock. --- -2.35.3 - diff --git a/gdb-testsuite-factor-out-proc-with_lock.patch b/gdb-testsuite-factor-out-proc-with_lock.patch deleted file mode 100644 index 19f606b..0000000 --- a/gdb-testsuite-factor-out-proc-with_lock.patch +++ /dev/null @@ -1,160 +0,0 @@ -From d96f9a0ef44eb3a3f41e2a478b817c1d00e6e0a1 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Sat, 4 May 2024 10:41:09 +0200 -Subject: [PATCH 18/48] [gdb/testsuite] Factor out proc with_lock - -Factor out proc with_lock from with_rocm_gpu_lock, and move required procs -lock_file_acquire and lock_file_release to lib/gdb-utils.exp. - -Tested on aarch64-linux. - -Approved-By: Tom Tromey ---- - gdb/testsuite/lib/gdb-utils.exp | 59 +++++++++++++++++++++++++++++++++ - gdb/testsuite/lib/rocm.exp | 55 +----------------------------- - 2 files changed, 60 insertions(+), 54 deletions(-) - -diff --git a/gdb/testsuite/lib/gdb-utils.exp b/gdb/testsuite/lib/gdb-utils.exp -index a010e14fc04..3dc4b3a3ebc 100644 ---- a/gdb/testsuite/lib/gdb-utils.exp -+++ b/gdb/testsuite/lib/gdb-utils.exp -@@ -138,3 +138,62 @@ proc version_compare { l1 op l2 } { - } - return 1 - } -+ -+# Acquire lock file LOCKFILE. Tries forever until the lock file is -+# successfully created. -+ -+proc lock_file_acquire {lockfile} { -+ verbose -log "acquiring lock file: $::subdir/${::gdb_test_file_name}.exp" -+ while {true} { -+ if {![catch {open $lockfile {WRONLY CREAT EXCL}} rc]} { -+ set msg "locked by $::subdir/${::gdb_test_file_name}.exp" -+ verbose -log "lock file: $msg" -+ # For debugging, put info in the lockfile about who owns -+ # it. -+ puts $rc $msg -+ flush $rc -+ return [list $rc $lockfile] -+ } -+ after 10 -+ } -+} -+ -+# Release a lock file. -+ -+proc lock_file_release {info} { -+ verbose -log "releasing lock file: $::subdir/${::gdb_test_file_name}.exp" -+ -+ if {![catch {fconfigure [lindex $info 0]}]} { -+ if {![catch { -+ close [lindex $info 0] -+ file delete -force [lindex $info 1] -+ } rc]} { -+ return "" -+ } else { -+ return -code error "Error releasing lockfile: '$rc'" -+ } -+ } else { -+ error "invalid lock" -+ } -+} -+ -+# Run body under lock LOCK_FILE. -+ -+proc with_lock { lock_file body } { -+ if {[info exists ::GDB_PARALLEL]} { -+ set lock_rc [lock_file_acquire $lock_file] -+ } -+ -+ set code [catch {uplevel 1 $body} result] -+ -+ if {[info exists ::GDB_PARALLEL]} { -+ lock_file_release $lock_rc -+ } -+ -+ if {$code == 1} { -+ global errorInfo errorCode -+ return -code $code -errorinfo $errorInfo -errorcode $errorCode $result -+ } else { -+ return -code $code $result -+ } -+} -diff --git a/gdb/testsuite/lib/rocm.exp b/gdb/testsuite/lib/rocm.exp -index fcdf665aef9..86ec29567da 100644 ---- a/gdb/testsuite/lib/rocm.exp -+++ b/gdb/testsuite/lib/rocm.exp -@@ -107,68 +107,15 @@ gdb_caching_proc allow_hipcc_tests {} { - # at a time. - set gpu_lock_filename $objdir/gpu-parallel.lock - --# Acquire lock file LOCKFILE. Tries forever until the lock file is --# successfully created. -- --proc lock_file_acquire {lockfile} { -- verbose -log "acquiring lock file: $::subdir/${::gdb_test_file_name}.exp" -- while {true} { -- if {![catch {open $lockfile {WRONLY CREAT EXCL}} rc]} { -- set msg "locked by $::subdir/${::gdb_test_file_name}.exp" -- verbose -log "lock file: $msg" -- # For debugging, put info in the lockfile about who owns -- # it. -- puts $rc $msg -- flush $rc -- return [list $rc $lockfile] -- } -- after 10 -- } --} -- --# Release a lock file. -- --proc lock_file_release {info} { -- verbose -log "releasing lock file: $::subdir/${::gdb_test_file_name}.exp" -- -- if {![catch {fconfigure [lindex $info 0]}]} { -- if {![catch { -- close [lindex $info 0] -- file delete -force [lindex $info 1] -- } rc]} { -- return "" -- } else { -- return -code error "Error releasing lockfile: '$rc'" -- } -- } else { -- error "invalid lock" -- } --} -- - # Run body under the GPU lock. Also calls gdb_exit before releasing - # the GPU lock. - - proc with_rocm_gpu_lock { body } { -- if {[info exists ::GDB_PARALLEL]} { -- set lock_rc [lock_file_acquire $::gpu_lock_filename] -- } -- -- set code [catch {uplevel 1 $body} result] -+ with_lock $::gpu_lock_filename $body - - # In case BODY returned early due to some testcase failing, and - # left GDB running, debugging the GPU. - gdb_exit -- -- if {[info exists ::GDB_PARALLEL]} { -- lock_file_release $lock_rc -- } -- -- if {$code == 1} { -- global errorInfo errorCode -- return -code $code -errorinfo $errorInfo -errorcode $errorCode $result -- } else { -- return -code $code $result -- } - } - - # Return true if all the devices support debugging multiple processes --- -2.35.3 - diff --git a/gdb-testsuite-fix-another-regexp-in-gdb.threads-step.patch b/gdb-testsuite-fix-another-regexp-in-gdb.threads-step.patch new file mode 100644 index 0000000..3c955c9 --- /dev/null +++ b/gdb-testsuite-fix-another-regexp-in-gdb.threads-step.patch @@ -0,0 +1,40 @@ +From 002b882370fb3d69b7c89fc99e85fc1b767567b9 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Thu, 29 Aug 2024 11:39:02 +0200 +Subject: [PATCH 2/2] [gdb/testsuite] Fix another regexp in + gdb.threads/stepi-over-clone.exp + +On openSUSE Tumbleweed, I run into: +... +(gdb) PASS: gdb.threads/stepi-over-clone.exp: catch process syscalls +continue^M +Continuing.^M +^M +Catchpoint 2 (call to syscall clone3), __clone3 () at clone3.S:62^M +(gdb) FAIL: gdb.threads/stepi-over-clone.exp: continue +... + +Fix this by updating another (see commit 8fbf220321d) regexp to also recognize +__clone3. + +Tested on x86_64-linux. +--- + gdb/testsuite/gdb.threads/stepi-over-clone.exp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gdb/testsuite/gdb.threads/stepi-over-clone.exp b/gdb/testsuite/gdb.threads/stepi-over-clone.exp +index da8bbf6a215..b93cfe69c7f 100644 +--- a/gdb/testsuite/gdb.threads/stepi-over-clone.exp ++++ b/gdb/testsuite/gdb.threads/stepi-over-clone.exp +@@ -50,7 +50,7 @@ gdb_test_multiple "catch syscall group:process" "catch process syscalls" { + + set re_loc1 "$hex in (__)?clone\[23\]? \\(\\)" + set re_loc2 "$decimal\[ \t\]+in \[^\r\n\]+" +-set re_loc3 "clone\[23\]? \\(\\) at \[^:\]+:$decimal" ++set re_loc3 "(__)?clone\[23\]? \\(\\) at \[^:\]+:$decimal" + + gdb_test "continue" \ + "Catchpoint $decimal \\(call to syscall clone\[23\]?\\), ($re_loc1|$re_loc3).*" +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.ada-big_packed_array.exp-on-s3.patch b/gdb-testsuite-fix-gdb.ada-big_packed_array.exp-on-s3.patch new file mode 100644 index 0000000..6d38957 --- /dev/null +++ b/gdb-testsuite-fix-gdb.ada-big_packed_array.exp-on-s3.patch @@ -0,0 +1,62 @@ +From f74652042d7330cd5db2fe1c2f6f4e9cd23f2d55 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Tue, 4 Feb 2025 14:06:20 +0100 +Subject: [PATCH 44/46] [gdb/testsuite] Fix gdb.ada/big_packed_array.exp on + s390x-linux + +When running test-case gdb.ada/big_packed_array.exp on s390x-linux, I run +into: +... +(gdb) print bad^M +$2 = (0 => 0 , 1)^M +(gdb) FAIL: gdb.ada/big_packed_array.exp: scenario=minimal: print bad +... + +This is with gcc 7.5.0, and this xfail should trigger: +... + if { $have_xfail && [string is integer $last] \ + && [expr ($last & 0xf) == 0] } { + # gcc/101643 + setup_xfail *-*-* + } +... +but it doesn't because $last is '1'. + +Fix this by using 0xf0 as mask for big endian. + +Tested on s390x-linux. +--- + gdb/testsuite/gdb.ada/big_packed_array.exp | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/gdb/testsuite/gdb.ada/big_packed_array.exp b/gdb/testsuite/gdb.ada/big_packed_array.exp +index 1ba2c4853c8..1a10ea1d2a5 100644 +--- a/gdb/testsuite/gdb.ada/big_packed_array.exp ++++ b/gdb/testsuite/gdb.ada/big_packed_array.exp +@@ -21,6 +21,8 @@ standard_ada_testfile foo_ra24_010 + + set old_gcc [expr [test_compiler_info {gcc-[0-8]-*}]] + ++set endian [target_endianness] ++ + foreach_with_prefix scenario {all minimal} { + set flags [list debug additional_flags=-fgnat-encodings=$scenario] + +@@ -54,8 +56,13 @@ foreach_with_prefix scenario {all minimal} { + } + -re -wrap $re_xfail2 { + set last $expect_out(1,string) ++ if { $endian == "little" } { ++ set mask 0x0f ++ } else { ++ set mask 0xf0 ++ } + if { $have_xfail && [string is integer $last] \ +- && [expr ($last & 0xf) == 0] } { ++ && [expr ($last & $mask) == 0] } { + # gcc/101643 + setup_xfail *-*-* + } +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.ada-convvar_comp.exp-on-s390x-.patch b/gdb-testsuite-fix-gdb.ada-convvar_comp.exp-on-s390x-.patch new file mode 100644 index 0000000..974e847 --- /dev/null +++ b/gdb-testsuite-fix-gdb.ada-convvar_comp.exp-on-s390x-.patch @@ -0,0 +1,113 @@ +From ac9c99f7f6b86d536c60fcb4b5ecdd4a2e767603 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Tue, 4 Feb 2025 14:06:20 +0100 +Subject: [PATCH 45/46] [gdb/testsuite] Fix gdb.ada/convvar_comp.exp on + s390x-linux + +When running test-case gdb.ada/convvar_comp.exp on s390x-linux, I get: +... +(gdb) run ^M +Starting program: pb16_063 ^M +^M +Breakpoint 1, pck.break_me (item=...) at pck.adb:17^M +17 function Break_Me (Item : T) return Boolean is^M +(gdb) print item.started^M +Cannot access memory at address 0x0^M +(gdb) FAIL: gdb.ada/convvar_comp.exp: print item.started +... + +This happens as follows. + +The parameter item is available in (DW_OP_fbreg: -168): +... + <2><912>: Abbrev Number: 18 (DW_TAG_formal_parameter) + <913> DW_AT_name : (indirect string, offset: 0x14ca): item + <919> DW_AT_type : <0x929> + <91d> DW_AT_location : 3 byte block: 91 d8 7e (DW_OP_fbreg: -168) +... +and according to the rules of -O0, it's considered to be available after the +prologue, which looks like this: +... +0000000001002998 : + 1002998: b3 c1 00 2b ldgr %f2,%r11 + 100299c: b3 c1 00 0f ldgr %f0,%r15 + 10029a0: e3 f0 ff 58 ff 71 lay %r15,-168(%r15) + 10029a6: b9 04 00 bf lgr %r11,%r15 + 10029aa: e3 20 b0 a0 00 24 stg %r2,160(%r11) +... + +To detect the prologue, gdb checks the line info, which looks like this: +... +pck.adb: +File name Line number Starting address View Stmt +pck.adb 17 0x1002998 x +pck.adb 17 0x1002998 1 x +pck.adb 19 0x10029b0 x +pck.adb 20 0x10029b8 x +pck.adb - 0x10029c6 +... +and gdb concludes that it's an empty prologue, so we stop at 0x1002998 and +try to print parameter item, which is not available yet. + +For more details, see this comment in skip_prologue_using_sal: +... + /* For languages other than assembly, treat two consecutive line + entries at the same address as a zero-instruction prologue. +... + +The same thing happens on x86_64-linux, but it causes no problem there, +because amd64_skip_prologue decides not to trust the result: +... + struct compunit_symtab *cust = find_pc_compunit_symtab (func_addr); + + /* LLVM backend (Clang/Flang) always emits a line note before the + prologue and another one after. We trust clang and newer Intel + compilers to emit usable line notes. */ + if (post_prologue_pc + && (cust != NULL + && cust->producer () != nullptr + && (producer_is_llvm (cust->producer ()) + || producer_is_icc_ge_19 (cust->producer ())))) + return std::max (start_pc, post_prologue_pc); +... +because the producer is GCC. + +Work around this by setting a breakpoint on the first statement of +pck.break_me instead. + +Tested on s390x-linux. +--- + gdb/testsuite/gdb.ada/convvar_comp.exp | 4 +++- + gdb/testsuite/gdb.ada/convvar_comp/pck.adb | 2 +- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/gdb/testsuite/gdb.ada/convvar_comp.exp b/gdb/testsuite/gdb.ada/convvar_comp.exp +index d59a19a40c3..e7ff3baa624 100644 +--- a/gdb/testsuite/gdb.ada/convvar_comp.exp ++++ b/gdb/testsuite/gdb.ada/convvar_comp.exp +@@ -25,7 +25,9 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug ]] != "" } + + clean_restart ${testfile} + +-if {![runto "break_me"]} { ++set bp_location [gdb_get_line_number "BREAK" "$testdir/pck.adb"] ++ ++if {![runto pck.adb:$bp_location]} { + return + } + +diff --git a/gdb/testsuite/gdb.ada/convvar_comp/pck.adb b/gdb/testsuite/gdb.ada/convvar_comp/pck.adb +index be5d8d719d8..b7bf3efe8f9 100644 +--- a/gdb/testsuite/gdb.ada/convvar_comp/pck.adb ++++ b/gdb/testsuite/gdb.ada/convvar_comp/pck.adb +@@ -16,6 +16,6 @@ + package body Pck is + function Break_Me (Item : T) return Boolean is + begin +- return False; ++ return False; -- BREAK + end Break_Me; + end Pck; +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.ada-mi_task_arg.exp-on-arm-lin.patch b/gdb-testsuite-fix-gdb.ada-mi_task_arg.exp-on-arm-lin.patch new file mode 100644 index 0000000..ec794db --- /dev/null +++ b/gdb-testsuite-fix-gdb.ada-mi_task_arg.exp-on-arm-lin.patch @@ -0,0 +1,70 @@ +From 58e1c193329c4e919272f01e5626b912d36ff65d Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Tue, 23 Jul 2024 14:27:36 +0200 +Subject: [PATCH 03/46] [gdb/testsuite] Fix gdb.ada/mi_task_arg.exp on + arm-linux + +On arm-linux, I run into: +... +PASS: gdb.ada/mi_task_arg.exp: mi runto task_switch.break_me +Expecting: ^(-stack-list-arguments 1[^M +]+)?(\^done,stack-args=\[frame={level="0",args=\[\]},frame={level="1",args=\[{name="<_task>",value="0x[0-9A-Fa-f]+"}(,{name="<_taskL>",value="[0-9]+"})?\]},frame={level="2",args=\[({name="self_id",value="(0x[0-9A-Fa-f]+|)"})?\]},.*[^M +]+[(]gdb[)] ^M +[ ]*) +-stack-list-arguments 1^M +^done,stack-args=[frame={level="0",args=[]},frame={level="1",args=[{name="<_task>",value="0x40bc48"}]},frame={level="2",args=[]}]^M +(gdb) ^M +FAIL: gdb.ada/mi_task_arg.exp: -stack-list-arguments 1 (unexpected output) +... + +The problem is that the test-case expects a level 3 frame, but there is none. + +This can be reproduced using cli bt: +... + $ gdb -q -batch outputs/gdb.ada/mi_task_arg/task_switch \ + -ex "b task_switch.break_me" \ + -ex run \ + -ex bt + Breakpoint 1 at 0x34b4: file task_switch.adb, line 57. + + Thread 3 "my_caller" hit Breakpoint 1, task_switch.break_me () \ + at task_switch.adb:57 + 57 null; + #0 task_switch.break_me () at task_switch.adb:57 + #1 0x00403424 in task_switch.caller (<_task>=0x40bc48) at task_switch.adb:51 + #2 0xf7f95a08 in ?? () from /lib/arm-linux-gnueabihf/libgnarl-12.so + Backtrace stopped: previous frame identical to this frame (corrupt stack?) +... + +The purpose of the test-case is printing the frame at level 1, so I don't +think we should bother about the presence of the frame at level 3. + +Fix this by allowing the backtrace to stop at level 2. + +Tested on arm-linux. + +Approved-By: Luis Machado +Approved-By: Andrew Burgess +--- + gdb/testsuite/gdb.ada/mi_task_arg.exp | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/gdb/testsuite/gdb.ada/mi_task_arg.exp b/gdb/testsuite/gdb.ada/mi_task_arg.exp +index 098396d5c09..b4b7b4997f3 100644 +--- a/gdb/testsuite/gdb.ada/mi_task_arg.exp ++++ b/gdb/testsuite/gdb.ada/mi_task_arg.exp +@@ -49,7 +49,8 @@ set frame1 "frame=\{level=\"1\",args=\\\[${frame1_args}(,$frame1_opt_args)?\\\]\ + # Frame for system.tasking.stages.task_wrapper + set frame2_args "(\{name=\"self_id\",value=\"($hex|)\"\})?" + set frame2 "frame=\{level=\"2\",args=\\\[$frame2_args\\\]\}" +-mi_gdb_test "-stack-list-arguments 1" \ +- "\\^done,stack-args=\\\[$frame0,$frame1,$frame2,.*" \ +- "-stack-list-arguments 1" + ++set frames "$frame0,$frame1,${frame2}(,.*)?" ++mi_gdb_test "-stack-list-arguments 1" \ ++ "\\^done,stack-args=\\\[$frames\\\]" \ ++ "-stack-list-arguments 1" +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.ada-verylong.exp-on-32-bit-tar.patch b/gdb-testsuite-fix-gdb.ada-verylong.exp-on-32-bit-tar.patch deleted file mode 100644 index 807b5f1..0000000 --- a/gdb-testsuite-fix-gdb.ada-verylong.exp-on-32-bit-tar.patch +++ /dev/null @@ -1,84 +0,0 @@ -From d9a17115fbeb8d4c1780677bb57edf0fe8448038 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Tue, 2 Apr 2024 16:14:39 +0200 -Subject: [PATCH 30/48] [gdb/testsuite] Fix gdb.ada/verylong.exp on 32-bit - target - -In an aarch32-linux chroot on an aarch64-linux system, I run into: -... -(gdb) print x^M -$1 = 9223372036854775807^M -(gdb) FAIL: gdb.ada/verylong.exp: print x -... - -A passing version on aarch64-linux looks like: -... -(gdb) print x^M -$1 = 170141183460469231731687303715884105727^M -(gdb) PASS: gdb.ada/verylong.exp: print x -... - -The difference is caused by the size of the type Long_Long_Long_Integer, which -is: -- a 128-bit signed on 64-bit targets, and -- a 64-bit signed on 32-bit target. - -Fix this by detecting the size of the Long_Long_Long_Integer type, and -handling it. - -Tested on aarch64-linux and aarch32-linux. - -Approved-By: Tom Tromey - -PR testsuite/31574 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31574 - -[1] https://gcc.gnu.org/onlinedocs/gnat_rm/Implementation-Defined-Characteristics.html ---- - gdb/testsuite/gdb.ada/verylong.exp | 28 +++++++++++++++++++++------- - 1 file changed, 21 insertions(+), 7 deletions(-) - -diff --git a/gdb/testsuite/gdb.ada/verylong.exp b/gdb/testsuite/gdb.ada/verylong.exp -index d1fa968015b..4b83e0bd467 100644 ---- a/gdb/testsuite/gdb.ada/verylong.exp -+++ b/gdb/testsuite/gdb.ada/verylong.exp -@@ -29,15 +29,29 @@ clean_restart ${testfile} - set bp_location [gdb_get_line_number "START" ${testdir}/prog.adb] - runto "prog.adb:$bp_location" - --gdb_test "print x" " = 170141183460469231731687303715884105727" --gdb_test "print x / 2" " = 85070591730234615865843651857942052863" --gdb_test "print (x / 4) * 2" " = 85070591730234615865843651857942052862" -+set lll_int_size 0 -+gdb_test_multiple "ptype Long_Long_Long_Integer" "" { -+ -re -wrap "type = <8-byte integer>" { -+ set lll_int_size 8 -+ set max 9223372036854775807 -+ } -+ -re -wrap "type = <16-byte integer>" { -+ set lll_int_size 16 -+ set max 170141183460469231731687303715884105727 -+ } -+} -+ -+require {expr $lll_int_size == 8 || $lll_int_size == 16} -+ -+gdb_test "print x" " = $max" -+gdb_test "print x / 2" " = [expr $max / 2]" -+gdb_test "print (x / 4) * 2" " = [expr ($max / 4) * 2]" - gdb_test "print x - x" " = 0" --gdb_test "print x - 99 + 1" " = 170141183460469231731687303715884105629" --gdb_test "print -x" " = -170141183460469231731687303715884105727" --gdb_test "print +x" " = 170141183460469231731687303715884105727" -+gdb_test "print x - 99 + 1" " = [expr $max - 99 + 1]" -+gdb_test "print -x" " = -$max" -+gdb_test "print +x" " = $max" - - gdb_test "print 170141183460469231731687303715884105727" \ - " = 170141183460469231731687303715884105727" --gdb_test "print x = 170141183460469231731687303715884105727" \ -+gdb_test "print x = $max" \ - " = true" --- -2.35.3 - diff --git a/gdb-testsuite-fix-gdb.arch-arm-pseudo-unwind.exp-wit.patch b/gdb-testsuite-fix-gdb.arch-arm-pseudo-unwind.exp-wit.patch new file mode 100644 index 0000000..d681bbc --- /dev/null +++ b/gdb-testsuite-fix-gdb.arch-arm-pseudo-unwind.exp-wit.patch @@ -0,0 +1,88 @@ +From 23c9940a62f31071c03e54142e57aea3b8ab1eff Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Wed, 17 Jul 2024 17:04:02 +0200 +Subject: [PATCH 06/46] [gdb/testsuite] Fix gdb.arch/arm-pseudo-unwind.exp with + unix/mthumb + +When running test-case gdb.arch/arm-pseudo-unwind.exp with target board +unix/mthumb, we run into: +... +(gdb) continue^M +Continuing.^M +^M +Program received signal SIGILL, Illegal instruction.^M +0x00400f38 in ?? ()^M +(gdb) FAIL: $exp: continue to breakpoint: continue to callee +... + +The test-case attempts to force arm-pseudo-unwind.c to be compiled in arm mode +using additional_flags=-marm, but that's overridden by using target board +unix/mthumb. + +This causes function main to be in thumb mode, and consequently function +caller (which is called from main) is is executed as if it's in thumb mode, +while it's actually in arm mode. + +Fix this by adding an intermediate function caller_trampoline in +arm-pseudo-unwind.c, and hardcoding it to arm mode using +__attribute__((target("arm"))). + +Likewise for test-case gdb.arch/arm-pseudo-unwind-legacy.exp. + +Tested on arm-linux. + +Approved-By: Luis Machado +--- + gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c | 9 ++++++++- + gdb/testsuite/gdb.arch/arm-pseudo-unwind.c | 9 ++++++++- + 2 files changed, 16 insertions(+), 2 deletions(-) + +diff --git a/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c +index 49b0553ade4..adda4b8b298 100644 +--- a/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c ++++ b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c +@@ -24,10 +24,17 @@ break_here_c (uint64_t value) + { + } + ++__attribute__((target("arm"))) ++uint64_t ++caller_trampoline (void) ++{ ++ return caller (); ++} ++ + int + main (void) + { +- uint64_t value = caller (); ++ uint64_t value = caller_trampoline (); + break_here_c (value); + return 0; + } +diff --git a/gdb/testsuite/gdb.arch/arm-pseudo-unwind.c b/gdb/testsuite/gdb.arch/arm-pseudo-unwind.c +index 49b0553ade4..adda4b8b298 100644 +--- a/gdb/testsuite/gdb.arch/arm-pseudo-unwind.c ++++ b/gdb/testsuite/gdb.arch/arm-pseudo-unwind.c +@@ -24,10 +24,17 @@ break_here_c (uint64_t value) + { + } + ++__attribute__((target("arm"))) ++uint64_t ++caller_trampoline (void) ++{ ++ return caller (); ++} ++ + int + main (void) + { +- uint64_t value = caller (); ++ uint64_t value = caller_trampoline (); + break_here_c (value); + return 0; + } +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.arch-arm-single-step-kernel-he.patch b/gdb-testsuite-fix-gdb.arch-arm-single-step-kernel-he.patch new file mode 100644 index 0000000..2a0f777 --- /dev/null +++ b/gdb-testsuite-fix-gdb.arch-arm-single-step-kernel-he.patch @@ -0,0 +1,79 @@ +From eb20b0f725b114eb117093971cf0146113517e6b Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Fri, 16 Aug 2024 14:22:46 +0200 +Subject: [PATCH 33/46] [gdb/testsuite] Fix + gdb.arch/arm-single-step-kernel-helper.exp + +On arm-linux I run into: +... +(gdb) p *kernel_user_helper_version^M +Cannot access memory at address 0xffff0ffc^M +(gdb) FAIL: gdb.arch/arm-single-step-kernel-helper.exp: check kernel helper version +... + +What the test-case is trying to do, is to access a special address in the arm +linux kernel [1] using ptrace, which doesn't seem to work. + +This is with kernel version 6.1.55. Perhaps this used to work, but the kernel +was modified to be more strict with respect to access to this special address. + +Fix this by making the inferior access that special address instead. + +Tested on arm-linux. + +Approved-By: Luis Machado + +PR testsuite/32070 +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32070 + +[1] https://www.kernel.org/doc/Documentation/arm/kernel_user_helpers.txt +--- + gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.c | 5 ++++- + gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.exp | 5 ++++- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.c b/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.c +index 393004e623a..9b5e137992d 100644 +--- a/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.c ++++ b/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.c +@@ -15,7 +15,8 @@ + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +-static int *kernel_user_helper_version = (int *) 0xffff0ffc; ++static int *kernel_user_helper_version_ptr = (int *) 0xffff0ffc; ++static int kernel_user_helper_version; + + typedef void * (kernel_user_func_t)(void); + #define kernel_user_get_tls (*(kernel_user_func_t *) 0xffff0fe0) +@@ -25,6 +26,8 @@ main (void) + { + int i; + ++ kernel_user_helper_version = *kernel_user_helper_version_ptr; ++ + for (i = 0; i < 8; i++) + kernel_user_get_tls (); + } +diff --git a/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.exp b/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.exp +index 27be5d56883..788bc863799 100644 +--- a/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.exp ++++ b/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.exp +@@ -26,10 +26,13 @@ if { ![runto_main] } { + return -1 + } + ++# Initialize kernel_user_helper_version. ++gdb_test "next" "for .*" ++ + # Check kernel helpers are supported or not. + + set kernel_helper_supported 0 +-gdb_test_multiple "p *kernel_user_helper_version" \ ++gdb_test_multiple "p kernel_user_helper_version" \ + "check kernel helper version" { + -re " = ($decimal)\r\n$gdb_prompt $" { + if { $expect_out(1,string) >= 1 } { +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.arch-riscv-tdesc-regs.exp.patch b/gdb-testsuite-fix-gdb.arch-riscv-tdesc-regs.exp.patch new file mode 100644 index 0000000..d1a5104 --- /dev/null +++ b/gdb-testsuite-fix-gdb.arch-riscv-tdesc-regs.exp.patch @@ -0,0 +1,84 @@ +From cb85331b671b668aaea1e10b2a37d49e9260bac3 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Wed, 4 Sep 2024 15:37:28 +0200 +Subject: [PATCH 35/46] [gdb/testsuite] Fix gdb.arch/riscv-tdesc-regs.exp + +On riscv64-linux, with test-case gdb.arch/riscv-tdesc-regs.exp I get: +... +(gdb) info registers fflags^M +fflags 0x0 NV:0 DZ:0 OF:0 UF:0 NX:0^M +(gdb) FAIL: gdb.arch/riscv-tdesc-regs.exp: info registers fflags +info registers frm^M +frm 0x0 FRM:0 [RNE (round to nearest; ties to even)]^M +(gdb) FAIL: gdb.arch/riscv-tdesc-regs.exp: info registers frm +... + +The FAILs are produced by: +... +foreach reg {fflags frm} { + gdb_test_multiple "info registers $reg" "" { + -re "^info registers $reg\r\n" { + exp_continue + } + + -wrap -re "^Invalid register `$reg`" { + fail $gdb_test_name + } + + -wrap -re "^$reg\\s+\[^\r\n\]+" { + pass $gdb_test_name + } + } +} +... + +The first clause is meant to consume the command. + +The '^' char was updated to mean "consume command", so that clause no longer +works since it now attempts to consume the command twice. + +Also, it's unnecessary because the following clauses start with ^. + +Then, the second clause is unnecessary because there's a default clause +producing the FAIL. + +Fix this by simplifying to: +... +foreach reg {fflags frm} { + gdb_test "info registers $reg" "^$reg\\s+\[^\r\n\]+" +} +... + +Tested on riscv64-linux. + +Approved-By: Andrew Burgess +--- + gdb/testsuite/gdb.arch/riscv-tdesc-regs.exp | 14 +------------- + 1 file changed, 1 insertion(+), 13 deletions(-) + +diff --git a/gdb/testsuite/gdb.arch/riscv-tdesc-regs.exp b/gdb/testsuite/gdb.arch/riscv-tdesc-regs.exp +index bd4ba38390a..58859d161b6 100644 +--- a/gdb/testsuite/gdb.arch/riscv-tdesc-regs.exp ++++ b/gdb/testsuite/gdb.arch/riscv-tdesc-regs.exp +@@ -156,17 +156,5 @@ gdb_test_no_output "set tdesc filename $remote_file" \ + "load the target description that lacks fflags and frm" + + foreach reg {fflags frm} { +- gdb_test_multiple "info registers $reg" "" { +- -re "^info registers $reg\r\n" { +- exp_continue +- } +- +- -wrap -re "^Invalid register `$reg`" { +- fail $gdb_test_name +- } +- +- -wrap -re "^$reg\\s+\[^\r\n\]+" { +- pass $gdb_test_name +- } +- } ++ gdb_test "info registers $reg" "^$reg\\s+\[^\r\n\]+" + } +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.base-branch-to-self.exp-on-arm.patch b/gdb-testsuite-fix-gdb.base-branch-to-self.exp-on-arm.patch new file mode 100644 index 0000000..5932a51 --- /dev/null +++ b/gdb-testsuite-fix-gdb.base-branch-to-self.exp-on-arm.patch @@ -0,0 +1,96 @@ +From 9625fc9c035b75f7e55350ad72c37ce1b7e8fe55 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Wed, 22 Jan 2025 10:46:08 +0100 +Subject: [PATCH 27/46] [gdb/testsuite] Fix gdb.base/branch-to-self.exp on + arm-linux + +On arm-linux (ubuntu 24.04 with gcc 13.3.0) with target board unix/-marm and +test-case gdb.base/branch-to-self.exp I run into: +... +(gdb) continue^M +Continuing.^M +^M +Breakpoint 2, main () at branch-to-self.c:38^M +38 for (;;); /* loop-line */^M +(gdb) PASS: $exp: single-step: continue to breakpoint: hit breakpoint +si^M +0x0040058c 38 for (;;); /* loop-line */^M +(gdb) FAIL: $exp: single-step: si +... + +In contrast, on the same machine but with debian testing and gcc 14.2.0 we have: +... +(gdb) continue^M +Continuing.^M +^M +Breakpoint 2, main () at branch-to-self.c:38^M +38 for (;;); /* loop-line */^M +(gdb) PASS: $exp: single-step: continue to breakpoint: hit breakpoint +si^M +^M +Breakpoint 2, main () at branch-to-self.c:38^M +38 for (;;); /* loop-line */^M +(gdb) PASS: $exp: single-step: stepi +... + +The difference is in the instruction(s) generated for the loop. + +In the passing case, we have: +... + 588: eafffffe b 588 +... +and in the failing case: +... + 588: e320f000 nop {0} + 58c: eafffffd b 588 +... + +The purpose of this part of the test-case is to: +- generate a branch instruction that jumps to itself, and +- set a breakpoint on it, and check that stepi-ing from that breakpoint + triggers the breakpoint again. + +As we can see, in the failing case we failed to generate a branch instruction +that jumps to itself, and consequently we cannot expect to hit the breakpoint +again after issuing a single si. + +Fix this by issuing stepi until we hit the breakpoint. + +Tested on arm-linux. + +Reviewed-by: Thiago Jung Bauermann +--- + gdb/testsuite/gdb.base/branch-to-self.exp | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/gdb/testsuite/gdb.base/branch-to-self.exp b/gdb/testsuite/gdb.base/branch-to-self.exp +index 9b4f7467498..71859d71e0d 100644 +--- a/gdb/testsuite/gdb.base/branch-to-self.exp ++++ b/gdb/testsuite/gdb.base/branch-to-self.exp +@@ -35,7 +35,22 @@ with_test_prefix "single-step" { + gdb_test "break ${testfile}.c:${line_num}" "Breakpoint .*" \ + "set breakpoint" + gdb_continue_to_breakpoint "hit breakpoint" +- gdb_test "si" ".*${testfile}.c:${line_num}.*" ++ ++ set stepi_count 1 ++ gdb_test_multiple "stepi" "" { ++ -re -wrap ".*${testfile}.c:${line_num}.*" { ++ pass $gdb_test_name ++ } ++ -re -wrap "" { ++ if { $stepi_count == 10 } { ++ fail $gdb_test_name ++ } else { ++ incr stepi_count ++ send_gdb "stepi\n" ++ exp_continue ++ } ++ } ++ } + } + + with_test_prefix "break-cond" { +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.base-eh_return.exp.patch b/gdb-testsuite-fix-gdb.base-eh_return.exp.patch deleted file mode 100644 index fc0c4df..0000000 --- a/gdb-testsuite-fix-gdb.base-eh_return.exp.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 7ee7b011e0c846a77cb4d1dde3a3c625412f1733 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Thu, 25 Jan 2024 16:25:07 +0100 -Subject: [PATCH 11/48] [gdb/testsuite] Fix gdb.base/eh_return.exp - -On Fedora rawhide aarch64, I run into: -... -(gdb) PASS: gdb.base/eh_return.exp: set breakpoint on address -run ^M -Starting program: eh_return ^M -[Thread debugging using libthread_db enabled]^M -Using host libthread_db library "/lib64/libthread_db.so.1".^M -[Inferior 1 (process 1113051) exited normally]^M -(gdb) FAIL: gdb.base/eh_return.exp: hit breakpoint (the program exited) -... - -This happens as follows: the test-case sets a breakpoint on the last -instruction of function eh2: -... -(gdb) break *0x00000000004103ec^M -... -and expects to hit the breakpoint, but instead the "br x6" is taken: -... - 0x00000000004103e0 <+176>: cbz x4, 0x4103ec ^M - 0x00000000004103e4 <+180>: add sp, sp, x5^M - 0x00000000004103e8 <+184>: br x6^M - 0x00000000004103ec <+188>: ret^M -... - -In contrast, with fedora f39 we have: -... - 0x00000000004103bc <+156>: ldp x2, x3, [sp, #48]^M - 0x00000000004103c0 <+160>: ldp x29, x30, [sp, #16]^M - 0x00000000004103c4 <+164>: add sp, sp, #0x50^M - 0x00000000004103c8 <+168>: add sp, sp, x4^M - 0x00000000004103cc <+172>: ret^M - -... -and the breakpoint is reached. - -Fix this by detecting that the breakpoint is not hit, and declaring the test -unsupported. - -Tested on aarch64-linux. - -Approved-By: Tom Tromey - -PR testsuite/31291 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31291 ---- - gdb/testsuite/gdb.base/eh_return.exp | 16 +++++++++++++++- - 1 file changed, 15 insertions(+), 1 deletion(-) - -diff --git a/gdb/testsuite/gdb.base/eh_return.exp b/gdb/testsuite/gdb.base/eh_return.exp -index bced409547b..7d566b1ddc2 100644 ---- a/gdb/testsuite/gdb.base/eh_return.exp -+++ b/gdb/testsuite/gdb.base/eh_return.exp -@@ -79,4 +79,18 @@ gdb_assert [gdb_breakpoint "*$address" no-message] "set breakpoint on address" - # breakpoint, so instead, run to the breakpoint. - gdb_run_cmd - --gdb_test "" "Breakpoint .*" "hit breakpoint" -+set test "hit breakpoint" -+gdb_expect { -+ -re "Breakpoint .*\r\n$gdb_prompt $" { -+ pass $test -+ } -+ -re "$inferior_exited_re normally.*\r\n$gdb_prompt $" { -+ unsupported $test -+ } -+ -re "\r\n$gdb_prompt $" { -+ fail $test -+ } -+ default { -+ fail $test -+ } -+} --- -2.35.3 - diff --git a/gdb-testsuite-fix-gdb.base-empty-host-env-vars.exp.patch b/gdb-testsuite-fix-gdb.base-empty-host-env-vars.exp.patch new file mode 100644 index 0000000..b601900 --- /dev/null +++ b/gdb-testsuite-fix-gdb.base-empty-host-env-vars.exp.patch @@ -0,0 +1,132 @@ +From bb7497a27dc37f9775c2c00ecb464b7b44a9e8bb Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Mon, 23 Sep 2024 07:57:49 +0200 +Subject: [PATCH 38/46] [gdb/testsuite] Fix gdb.base/empty-host-env-vars.exp + +On aarch64-linux (debian testing) with test-case +gdb.base/empty-host-env-vars.exp I ran into: +... +(gdb) show index-cache directory^M +The directory of the index cache is "/home/linux/.cache/gdb".^M +(gdb) FAIL: $exp: env_var_name=HOME: show index-cache directory +... + +Without changing any environment variables, the value of the index-cache dir +is: +... +$ gdb -q -batch -ex "show index-cache directory" +The directory of the index cache is "/home/linux/.cache/gdb". +... +and the expectation of the test-case is that setting HOME to empty will +produce an empty dir, but what it actually produces is: +... +$ HOME= gdb -q -batch -ex "show index-cache directory" +The directory of the index cache is "/home/linux/.cache/gdb". +... + +There's nothing wrong with that behaviour, the dir is simply constructed using +XDG_CACHE_HOME which happens to be explictly set to its default value +$HOME/.cache [1]: +... +$ echo $XDG_CACHE_HOME +/home/linux/.cache +... +and indeed also setting that variable to empty gets us the expected empty dir: +... +$ XDG_CACHE_HOME= HOME= gdb -q -batch -ex "show index-cache directory" +gdb: warning: Couldn't determine a path for the index cache directory. +The directory of the index cache is "". +... + +Furthermore, the test-case assumption that setting variables to empty either +produces the original dir or an empty dir is incorrect. + +Say that XDG_CACHE_HOME has a non-default value: +... +$ echo $XDG_CACHE_HOME +/home/linux/my-xdg-cache-home +$ gdb -q -batch -ex "show index-cache directory" +The directory of the index cache is "/home/linux/my-xdg-cache-home/gdb". +... +then setting that variable to empty: +... +$ XDG_CACHE_HOME= gdb -q -batch -ex "show index-cache directory" +The directory of the index cache is "/home/linux/.cache/gdb". +... +does change the value of the dir. + +Fix this by making the test-case less specific. + +While we're at it, factor out regexps re_pre and re_post to make regexps more +readable, and use string_to_regexp to reduce quoting. + +Tested on aarch64-linux. + +PR testsuite/32132 +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32132 + +[1] https://specifications.freedesktop.org/basedir-spec/latest/index.html#variables +--- + .../gdb.base/empty-host-env-vars.exp | 32 ++++++------------- + 1 file changed, 9 insertions(+), 23 deletions(-) + +diff --git a/gdb/testsuite/gdb.base/empty-host-env-vars.exp b/gdb/testsuite/gdb.base/empty-host-env-vars.exp +index e6e9d6e3156..5fab65a3607 100644 +--- a/gdb/testsuite/gdb.base/empty-host-env-vars.exp ++++ b/gdb/testsuite/gdb.base/empty-host-env-vars.exp +@@ -21,16 +21,14 @@ require {!is_remote host} + + set all_env_vars { HOME XDG_CACHE_HOME LOCALAPPDATA XDG_CONFIG_HOME } + +-# Record the initial value of the index-cache directory. ++set re_pre \ ++ [string_to_regexp {The directory of the index cache is "}] ++set re_post \ ++ [string_to_regexp {".}] ++ ++# Show the initial value of the index-cache directory. + clean_restart +-set index_cache_directory "" +-gdb_test_multiple "show index-cache directory" "" { +- -re -wrap "The directory of the index cache is \"(.*)\"\\." { +- set index_cache_directory $expect_out(1,string) +- set index_cache_directory [string_to_regexp $index_cache_directory] +- pass $gdb_test_name +- } +-} ++gdb_test "show index-cache directory" $re_pre\[^\r\n\]*$re_post + + foreach_with_prefix env_var_name $all_env_vars { + # Restore the original state of the environment variable. +@@ -38,18 +36,7 @@ foreach_with_prefix env_var_name $all_env_vars { + set env($env_var_name) {} + clean_restart + +- # Verify that the empty environment variable didn't affect the +- # index-cache directory setting, that we still see the initial value. +- # "HOME" is different, because if that one is unset, GDB isn't even +- # able to compute the default location. In that case, we expect it to +- # be empty. +- if { $env_var_name == "HOME" } { +- gdb_test "show index-cache directory" \ +- "The directory of the index cache is \"\"\\." +- } else { +- gdb_test "show index-cache directory" \ +- "The directory of the index cache is \"$index_cache_directory\"\\." +- } ++ gdb_test "show index-cache directory" $re_pre\[^\r\n\]*$re_post + } + } + +@@ -69,7 +56,6 @@ with_test_prefix "all env vars" { + + clean_restart + +- gdb_test "show index-cache directory" \ +- "The directory of the index cache is \"\"\\." ++ gdb_test "show index-cache directory" $re_pre$re_post + } + } +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.base-ending-run.exp-on-manjaro.patch b/gdb-testsuite-fix-gdb.base-ending-run.exp-on-manjaro.patch deleted file mode 100644 index 26f3954..0000000 --- a/gdb-testsuite-fix-gdb.base-ending-run.exp-on-manjaro.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 5f7c4f7a435571d535c2372b999e1017eefb15c4 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Thu, 28 Mar 2024 08:26:31 +0100 -Subject: [PATCH 33/48] [gdb/testsuite] Fix gdb.base/ending-run.exp on manjaro - linux - -On aarch64-linux, using the manjaro linux distro, I run into: -... -(gdb) next^M -32 }^M -(gdb) next^M -0x0000fffff7d67b80 in ?? () from /usr/lib/libc.so.6^M -(gdb) FAIL: gdb.base/ending-run.exp: step out of main -... - -What happens here is described in detail in this clause: -... - -re "0x.*\\?\\? \\(\\) from /lib/powerpc.*$gdb_prompt $" { - # This case occurs on Powerpc when gdb steps out of main and the - # needed debug info files are not loaded on the system, preventing - # GDB to determine which function it reached (__libc_start_call_main). - # Ideally, the target system would have the necessary debugging - # information, but in its absence, GDB's behavior is as expected. - ... - } -... -but the clause only matches for powerpc. - -Fix this by: -- making the regexp generic enough to also match /usr/lib/libc.so.6, and -- updating the comment to not mention powerpc. - -Tested on aarch64-linux. - -PR testsuite/31450 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31450 ---- - gdb/testsuite/gdb.base/ending-run.exp | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/gdb/testsuite/gdb.base/ending-run.exp b/gdb/testsuite/gdb.base/ending-run.exp -index 070dcc6f190..76701d33e19 100644 ---- a/gdb/testsuite/gdb.base/ending-run.exp -+++ b/gdb/testsuite/gdb.base/ending-run.exp -@@ -206,8 +206,8 @@ gdb_test_multiple "next" "step out of main" { - # This is what happens on system using uClibc. - pass "step out of main" - } -- -re "0x.*\\?\\? \\(\\) from /lib/powerpc.*$gdb_prompt $" { -- # This case occurs on Powerpc when gdb steps out of main and the -+ -re -wrap "$hex in \\?\\? \\(\\) from \[^\r\n\]+" { -+ # This case occurs when gdb steps out of main and the - # needed debug info files are not loaded on the system, preventing - # GDB to determine which function it reached (__libc_start_call_main). - # Ideally, the target system would have the necessary debugging --- -2.35.3 - diff --git a/gdb-testsuite-fix-gdb.base-list-dot-nodebug-and-make.patch b/gdb-testsuite-fix-gdb.base-list-dot-nodebug-and-make.patch new file mode 100644 index 0000000..8e78363 --- /dev/null +++ b/gdb-testsuite-fix-gdb.base-list-dot-nodebug-and-make.patch @@ -0,0 +1,83 @@ +From 755699757fc57172c5c9a173fae9bfaf75bc1b6a Mon Sep 17 00:00:00 2001 +From: Guinevere Larsen +Date: Fri, 31 May 2024 10:48:54 -0300 +Subject: [PATCH 36/46] gdb,testsuite: fix gdb.base/list-dot-nodebug and make + it more robust + +Thiago Jung Bauermann noticed that gdb.base/list-dot-nodebug was not +actually compiling the test with some debuginfo in the relevant part, +and while fixing I noticed that the base assumption of the "some" case +was wrong, GDB would select some symtab as a default location and the +test would always fail. This fix makes printing the default location +only be tested when there is no debuginfo. + +When testing with no debuginfo, if a system had static libc debuginfo, +the test would also fail. To add an extra layer of robustness to the +test, this rewrite also strips any stray debuginfo from the executable. +The test would only fail now if it runs in a system that can't handle +stripped debuginfo and has static debuginfo pre-installed. + +Reported-By: Tom de Vries +Reported-By: Thiago Jung Bauermann +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31721 +Reviewed-by: Thiago Jung Bauermann +Approved-By: Andrew Burgess +--- + gdb/testsuite/gdb.base/list-dot-nodebug.exp | 37 +++++++++++++++------ + 1 file changed, 26 insertions(+), 11 deletions(-) + +diff --git a/gdb/testsuite/gdb.base/list-dot-nodebug.exp b/gdb/testsuite/gdb.base/list-dot-nodebug.exp +index c9d732e801b..b7359be1a45 100644 +--- a/gdb/testsuite/gdb.base/list-dot-nodebug.exp ++++ b/gdb/testsuite/gdb.base/list-dot-nodebug.exp +@@ -34,21 +34,36 @@ standard_testfile .c -extra.c + + foreach_with_prefix debug {"none" "some"} { + +- set flags "nodebug" + if {$debug == "some"} { +- set flags "debug" +- } ++ if {[prepare_for_testing_full "failed to prepare" \ ++ [list ${testfile}-${debug} $linkflags \ ++ $srcfile [list nodebug] \ ++ $srcfile2 [list debug]]]} { ++ return -1 ++ } + +- if {[prepare_for_testing_full "failed to prepare" \ +- [list ${testfile}-${debug} $linkflags \ +- $srcfile [list nodebug] \ +- $srcfile2 [list $debug]]]} { +- return -1 ++ # We don't test "list ." before starting with some debug info ++ # because GDB will choose the symtab that has debuginfo, and ++ # print the copyright blurb. This test isn't interested (yet?) ++ # in checking if this default location choice is consistent. ++ } else { ++ set executable ${testfile}-none ++ if {[build_executable "failed to prepare" ${executable} \ ++ [list $srcfile $srcfile2] $linkflags]} { ++ return -1 ++ } ++ ++ # Stripping is a backup in case the system has static libc debuginfo. ++ # We can continue the test even if it fails. ++ gdb_gnu_strip_debug $executable no-debuglink ++ ++ clean_restart ${executable} ++ ++ gdb_test "list ." \ ++ "^Insufficient debug info for showing source lines at default location" \ ++ "print before start" + } + +- gdb_test "list ." \ +- "^Insufficient debug info for showing source lines at default location" \ +- "print before start" + + if { ![runto bar] } { + return -1 +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.base-list-dot-nodebug.exp-on-o.patch b/gdb-testsuite-fix-gdb.base-list-dot-nodebug.exp-on-o.patch new file mode 100644 index 0000000..2db9117 --- /dev/null +++ b/gdb-testsuite-fix-gdb.base-list-dot-nodebug.exp-on-o.patch @@ -0,0 +1,60 @@ +From 3048a9807737063118adfd0addbcf7218a5d8681 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Tue, 4 Feb 2025 10:34:39 +0100 +Subject: [PATCH 37/46] [gdb/testsuite] Fix gdb.base/list-dot-nodebug.exp on + openSUSE + +On openSUSE Leap 15.6 with test-case gdb.base/list-dot-nodebug.exp I run into: +... +(gdb) list .^M +warning: 1 ../sysdeps/x86_64/crtn.S: No such file or directory^M +(gdb) FAIL: $exp: debug=none: print before start +... + +The intent of the debug=none case is to generate an executable with no debug +info. However, we have quite a few CUs with debug info: +... +$ readelf -wi outputs/gdb.base/list-dot-nodebug/list-dot-nodebug-none \ + | egrep -c " @ " +431 +... + +This is because this code: +... + gdb_gnu_strip_debug $executable no-debuglink +... +uses $executable, and the variable is set here: +... + set executable ${testfile}-none +... +which sets it to "list-dot-nodebug-none" and consequently +gdb_gnu_strip_debug cannot find it. + +Fix this by using "[standard_output_file $executable]" instead. + +Tested on x86_64-linux. + +Approved-By: Tom Tromey + +PR testsuite/31721 +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31721 +--- + gdb/testsuite/gdb.base/list-dot-nodebug.exp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gdb/testsuite/gdb.base/list-dot-nodebug.exp b/gdb/testsuite/gdb.base/list-dot-nodebug.exp +index b7359be1a45..107669de04d 100644 +--- a/gdb/testsuite/gdb.base/list-dot-nodebug.exp ++++ b/gdb/testsuite/gdb.base/list-dot-nodebug.exp +@@ -55,7 +55,7 @@ foreach_with_prefix debug {"none" "some"} { + + # Stripping is a backup in case the system has static libc debuginfo. + # We can continue the test even if it fails. +- gdb_gnu_strip_debug $executable no-debuglink ++ gdb_gnu_strip_debug [standard_output_file $executable] no-debuglink + + clean_restart ${executable} + +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.base-list-no-debug.exp-on-debi.patch b/gdb-testsuite-fix-gdb.base-list-no-debug.exp-on-debi.patch deleted file mode 100644 index 443bf3e..0000000 --- a/gdb-testsuite-fix-gdb.base-list-no-debug.exp-on-debi.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 2235f362eba0387f0404620676dd29637ff17738 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Sun, 17 Mar 2024 16:48:43 +0100 -Subject: [PATCH 39/48] [gdb/testsuite] Fix gdb.base/list-no-debug.exp on - debian - -On debian 12, aarch64-linux I run into: -... -(gdb) list .^M -No symbol table is loaded. Use the "file" command.^M -(gdb) FAIL: gdb.base/list-nodebug.exp: first 'list .' -... - -The test-case expects some debug info, but none for main. Instead, there's no -debug info at all. - -Fix this by adding another source file to the test-case, and compiling it with -debug info. - -Tested on aarch64-linux. - -Approved-By: Andrew Burgess - -PR testsuite/31290 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31290 ---- - gdb/testsuite/gdb.base/list-nodebug-2.c | 24 ++++++++++++++++++++++++ - gdb/testsuite/gdb.base/list-nodebug.c | 7 +++++-- - gdb/testsuite/gdb.base/list-nodebug.exp | 9 ++++++--- - 3 files changed, 35 insertions(+), 5 deletions(-) - create mode 100644 gdb/testsuite/gdb.base/list-nodebug-2.c - -diff --git a/gdb/testsuite/gdb.base/list-nodebug-2.c b/gdb/testsuite/gdb.base/list-nodebug-2.c -new file mode 100644 -index 00000000000..861e6149071 ---- /dev/null -+++ b/gdb/testsuite/gdb.base/list-nodebug-2.c -@@ -0,0 +1,24 @@ -+/* This testcase is part of GDB, the GNU debugger. -+ -+ Copyright 2024 Free Software Foundation, Inc. -+ -+ 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 . */ -+ -+extern int foo (void); -+ -+int -+foo (void) -+{ -+ return 0; -+} -diff --git a/gdb/testsuite/gdb.base/list-nodebug.c b/gdb/testsuite/gdb.base/list-nodebug.c -index 078517c011e..d4ae6787310 100644 ---- a/gdb/testsuite/gdb.base/list-nodebug.c -+++ b/gdb/testsuite/gdb.base/list-nodebug.c -@@ -15,7 +15,10 @@ - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - --int main () -+extern int foo (void); -+ -+int -+main (void) - { -- return 0; -+ return foo (); - } -diff --git a/gdb/testsuite/gdb.base/list-nodebug.exp b/gdb/testsuite/gdb.base/list-nodebug.exp -index 08de05423af..942a282083a 100644 ---- a/gdb/testsuite/gdb.base/list-nodebug.exp -+++ b/gdb/testsuite/gdb.base/list-nodebug.exp -@@ -16,10 +16,13 @@ - # Test that using the command "list" in a file with no debug information - # will not crash GDB and will give reasonable output. - --standard_testfile .c -+standard_testfile .c -2.c - --if {[prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ -- {nodebug}]} { -+if { [prepare_for_testing_full "failed to prepare" \ -+ [list \ -+ $testfile {} \ -+ $srcfile {nodebug} \ -+ $srcfile2 {debug}]] } { - return -1 - } - --- -2.35.3 - diff --git a/gdb-testsuite-fix-gdb.base-step-over-syscall.exp-with-glibc-2-41.patch b/gdb-testsuite-fix-gdb.base-step-over-syscall.exp-with-glibc-2-41.patch new file mode 100644 index 0000000..2c5e17e --- /dev/null +++ b/gdb-testsuite-fix-gdb.base-step-over-syscall.exp-with-glibc-2-41.patch @@ -0,0 +1,119 @@ +From c663bffcf74ccf94f7ff3c78b98d20fa60a09d31 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Tue, 11 Mar 2025 09:38:50 +0100 +Subject: [PATCH 2/2] [gdb/testsuite] Fix gdb.base/step-over-syscall.exp with + glibc 2.41 + +On openSUSE Tumbleweed, with glibc 2.41, when running test-case +gdb.base/step-over-syscall.exp I run into: +... +(gdb) stepi^M +0x00007ffff7cfd09b in __abort_lock_rdlock () from /lib64/libc.so.6^M +1: x/i $pc^M +=> 0x7ffff7cfd09b <__abort_lock_rdlock+29>: syscall^M +(gdb) p $eax^M +$1 = 14^M +(gdb) FAIL: $exp: fork: displaced=off: syscall number matches +FAIL: $exp: fork: displaced=off: find syscall insn in fork (timeout) +... + +We're stepi-ing through fork trying to find the fork syscall, but encounter +another syscall. + +The test-case attempts to handle this: +... + gdb_test_multiple "stepi" "find syscall insn in $syscall" { + -re ".*$syscall_insn.*$gdb_prompt $" { + # Is the syscall number the correct one? + if {[syscall_number_matches $syscall]} { + pass $gdb_test_name + } else { + exp_continue + } + } + -re "x/i .*=>.*\r\n$gdb_prompt $" { + incr steps + if {$steps == $max_steps} { + fail $gdb_test_name + } else { + send_gdb "stepi\n" + exp_continue + } + } + } +... +but fails to do so because it issues an exp_continue without issuing a new +stepi command, and consequently the "find syscall insn in fork" test times +out. + +Also, the call to syscall_number_matches produces a PASS or FAIL, so skipping +one syscall would produce: +... +FAIL: $exp: fork: displaced=off: syscall number matches +PASS: $exp: fork: displaced=off: syscall number matches +DUPLICATE: $exp: fork: displaced=off: syscall number matches +... + +Fix this by: +- not producing PASS or FAIL in syscall_number_matches, and +- issuing stepi when encountering another syscall. + +While we're at it, fix indentation in syscall_number_matches. + +Tested on x86_64-linux, specifically: +- openSUSE Tumbleweed (glibc 2.41), and +- openSUSE Leap 15.6 (glibc 2.38). + +PR testsuite/32780 +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32780 +--- + gdb/testsuite/gdb.base/step-over-syscall.exp | 24 ++++++++++++++------ + 1 file changed, 17 insertions(+), 7 deletions(-) + +diff --git a/gdb/testsuite/gdb.base/step-over-syscall.exp b/gdb/testsuite/gdb.base/step-over-syscall.exp +index b3b02acc553..cd1683d3dde 100644 +--- a/gdb/testsuite/gdb.base/step-over-syscall.exp ++++ b/gdb/testsuite/gdb.base/step-over-syscall.exp +@@ -62,14 +62,18 @@ proc_with_prefix check_pc_after_cross_syscall { displaced syscall syscall_insn_n + # Verify the syscall number is the correct one. + + proc syscall_number_matches { syscall } { +- global syscall_register syscall_number ++ global syscall_register syscall_number + +- if {[gdb_test "p \$$syscall_register" ".*= $syscall_number($syscall)" \ +- "syscall number matches"] != 0} { +- return 0 +- } ++ set res 0 ++ gdb_test_multiple "p \$$syscall_register" "syscall number matches" { ++ -re -wrap ".*= $syscall_number($syscall)" { ++ set res 1 ++ } ++ -re -wrap "" { ++ } ++ } + +- return 1 ++ return $res + } + + # Restart GDB and set up the test. Return a list in which the first one +@@ -139,7 +143,13 @@ proc setup { syscall } { + if {[syscall_number_matches $syscall]} { + pass $gdb_test_name + } else { +- exp_continue ++ incr steps ++ if {$steps == $max_steps} { ++ fail $gdb_test_name ++ } else { ++ send_gdb "stepi\n" ++ exp_continue ++ } + } + } + -re "x/i .*=>.*\r\n$gdb_prompt $" { +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.base-step-over-syscall.exp-with-m32-amd-case.patch b/gdb-testsuite-fix-gdb.base-step-over-syscall.exp-with-m32-amd-case.patch deleted file mode 100644 index 5b3cbb9..0000000 --- a/gdb-testsuite-fix-gdb.base-step-over-syscall.exp-with-m32-amd-case.patch +++ /dev/null @@ -1,71 +0,0 @@ -[gdb/testsuite] Fix gdb.base/step-over-syscall.exp with -m32, AMD case - -On an OBS machine with openSUSE Leap 15.2 and target board unix/-m32 I run -into: -... -(gdb) x/2i $pc^M -=> 0xf7fd5155 <__kernel_vsyscall+5>: syscall ^M - 0xf7fd5157 <__kernel_vsyscall+7>: int $0x80^M -(gdb) PASS: gdb.base/step-over-syscall.exp: fork: displaced=off: \ - pc before/after syscall instruction -stepi^M -[Detaching after fork from child process 19924]^M -0xf7fd5159 in __kernel_vsyscall ()^M -1: x/i $pc^M -=> 0xf7fd5159 <__kernel_vsyscall+9>: pop %ebp^M -(gdb) PASS: gdb.base/step-over-syscall.exp: fork: displaced=off: stepi fork insn -print /x $pc^M -$2 = 0xf7fd5159^M -(gdb) PASS: gdb.base/step-over-syscall.exp: fork: displaced=off: pc after stepi -FAIL: gdb.base/step-over-syscall.exp: fork: displaced=off: \ - pc after stepi matches insn addr a -fter syscall -... - -This is essentially a duplicate of the problem solved by commit 14852123287 -"[gdb/testsuite] Fix gdb.base/step-over-syscall.exp with -m32", only here the -insn before "int $0x80" is syscall instead of sysenter. - -The background here is that we're executing this code in the linux kernel -(from ./arch/x86/entry/vdso/vdso32/system_call.S): -... - #define SYSENTER_SEQUENCE "movl %esp, %ebp; sysenter" - #define SYSCALL_SEQUENCE "movl %ecx, %ebp; syscall" - - /* If SYSENTER (Intel) or SYSCALL32 (AMD) is available, use it. */ - ALTERNATIVE_2 "", SYSENTER_SEQUENCE, X86_FEATURE_SYSENTER32, \ - SYSCALL_SEQUENCE, X86_FEATURE_SYSCALL32 - ALTERNATIVE "", SYSENTER_SEQUENCE, X86_FEATURE_SEP -... -and depending on the active feature, we either have sysenter or syscall. - -Fix this by recognizing the "syscall", "int $0x80" sequence. - -Tested on x86_64-linux. - ---- - gdb/testsuite/gdb.base/step-over-syscall.exp | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/gdb/testsuite/gdb.base/step-over-syscall.exp b/gdb/testsuite/gdb.base/step-over-syscall.exp -index ecfb7be481d..a4821d7cd5a 100644 ---- a/gdb/testsuite/gdb.base/step-over-syscall.exp -+++ b/gdb/testsuite/gdb.base/step-over-syscall.exp -@@ -162,12 +162,13 @@ proc setup { syscall } { - } - - # If we encounter a sequence: -- # 0xf7fd5155 <__kernel_vsyscall+5>: sysenter -+ # 0xf7fd5155 <__kernel_vsyscall+5>: sysenter / syscall - # 0xf7fd5157 <__kernel_vsyscall+7>: int $0x80 - # 0xf7fd5159 <__kernel_vsyscall+9>: pop %ebp -- # then a stepi at sysenter will step over the int insn, so make sure -- # next_insn_addr points after the int insn. -- if { $actual_syscall_insn == "sysenter" } { -+ # then a stepi at sysenter/syscall will step over the int insn, -+ # so make sure next_insn_addr points after the int insn. -+ if { $actual_syscall_insn == "sysenter" -+ || $actual_syscall_insn == "syscall" } { - set test "pc after sysenter instruction" - set re_int_insn "\[ \t\]*int\[ \t\]\[^\r\n\]*" - set re [multi_line \ diff --git a/gdb-testsuite-fix-gdb.base-step-over-syscall.exp-with-m32-for-amd.patch b/gdb-testsuite-fix-gdb.base-step-over-syscall.exp-with-m32-for-amd.patch new file mode 100644 index 0000000..793afed --- /dev/null +++ b/gdb-testsuite-fix-gdb.base-step-over-syscall.exp-with-m32-for-amd.patch @@ -0,0 +1,61 @@ +From 7be3afccde80f7c580226f08715c181fd3f48e43 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Sat, 8 Mar 2025 09:52:08 +0100 +Subject: [PATCH 1/2] [gdb/testsuite] Fix gdb.base/step-over-syscall.exp with + -m32 for AMD + +When running test-case gdb.base/step-over-syscall.exp with target board +unix/-m32 on an AMD processor, I run into: +... +(gdb) x/2i $pc^M +=> 0xf7fc9575 <__kernel_vsyscall+5>: syscall^M + 0xf7fc9577 <__kernel_vsyscall+7>: int $0x80^M +(gdb) PASS: $exp: fork: displaced=off: pc before/after syscall instruction +stepi^M +[Detaching after fork from child process 65650]^M +0xf7fc9579 in __kernel_vsyscall ()^M +1: x/i $pc^M +=> 0xf7fc9579 <__kernel_vsyscall+9>: pop %ebp^M +(gdb) $exp: fork: displaced=off: stepi fork insn +print /x $pc^M +$2 = 0xf7fc9579^M +(gdb) PASS: gdb.base/step-over-syscall.exp: fork: displaced=off: pc after stepi +FAIL: $exp: fork: displaced=off: pc after stepi matches insn addr after syscall +... + +The problem is that the syscall returns at the "pop %ebp" insn, while the +test-case expects it to return at the "int $0x80" insn. + +This is similar to the problem I fixed in commit 14852123287 ("[gdb/testsuite] +Fix gdb.base/step-over-syscall.exp with -m32"), just that the syscall sequence +used there used the "sysenter" insn instead of the "syscall" insn. + +Fix this by extending the fix for commit 14852123287 to also handle the +"syscall" insn. + +Tested on x86_64-linux, both using an AMD and Intel processor. + +PR testsuite/32439 +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32439 +--- + gdb/testsuite/gdb.base/step-over-syscall.exp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gdb/testsuite/gdb.base/step-over-syscall.exp b/gdb/testsuite/gdb.base/step-over-syscall.exp +index 8cacc0962c3..b3b02acc553 100644 +--- a/gdb/testsuite/gdb.base/step-over-syscall.exp ++++ b/gdb/testsuite/gdb.base/step-over-syscall.exp +@@ -176,7 +176,7 @@ proc setup { syscall } { + # 0xf7fd5159 <__kernel_vsyscall+9>: pop %ebp + # then a stepi at sysenter will step over the int insn, so make sure + # next_insn_addr points after the int insn. +- if { $actual_syscall_insn == "sysenter" } { ++ if { $actual_syscall_insn == "sysenter" || $actual_syscall_insn == "syscall" } { + set test "pc after sysenter instruction" + set re_int_insn "\[ \t\]*int\[ \t\]\[^\r\n\]*" + set re [multi_line \ + +base-commit: 5754dc6554eb0ffef484ce898537846a6247f4a9 +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.cp-m-static.exp-on-arm.patch b/gdb-testsuite-fix-gdb.cp-m-static.exp-on-arm.patch new file mode 100644 index 0000000..8917824 --- /dev/null +++ b/gdb-testsuite-fix-gdb.cp-m-static.exp-on-arm.patch @@ -0,0 +1,88 @@ +From c77016a72a59a2f32be370d2c8d6729baa97191c Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Wed, 24 Jul 2024 14:44:33 +0200 +Subject: [PATCH 10/46] [gdb/testsuite] Fix gdb.cp/m-static.exp on arm + +With test-case gdb.cp/m-static.exp on arm-linux, I get: +... +(gdb) ptype test5.single_constructor^M +type = class single_constructor {^M +^M + public:^M + single_constructor(void);^M + ~single_constructor(void);^M +} *(single_constructor * const)^M +(gdb) FAIL: gdb.cp/m-static.exp: simple object instance, ptype constructor +... + +The test-case expects: +- no empty line before "public:", and +- no "~single_constructor(void)", but "~single_constructor()" + +The latter is due to commit 137c886e9a6 ("[gdb/c++] Print destructor the same +for gcc and clang"). + +The failing test is in a part only enabled for is_aarch32_target == 1, so it +looks like it was left behind. + +I'm assuming the same happened for the other difference. + +Fix this by updating the regexps to match the observed output. + +Tested on arm-linux. + +Approved-By: Andrew Burgess +--- + gdb/testsuite/gdb.cp/m-static.exp | 15 +++++++++++---- + gdb/testsuite/lib/gdb-utils.exp | 8 ++++++++ + 2 files changed, 19 insertions(+), 4 deletions(-) + +diff --git a/gdb/testsuite/gdb.cp/m-static.exp b/gdb/testsuite/gdb.cp/m-static.exp +index 45bc090d01f..5b41898ec9d 100644 +--- a/gdb/testsuite/gdb.cp/m-static.exp ++++ b/gdb/testsuite/gdb.cp/m-static.exp +@@ -71,11 +71,18 @@ if { [is_aarch32_target] } { + gdb_test "print test5.single_constructor" \ + { = {single_constructor \*\(single_constructor \* const\)} 0x[0-9a-f]+ } \ + "simple object instance, print constructor" +- gdb_test "ptype test5.single_constructor" \ +- {type = class single_constructor {\r\n public:\r\n single_constructor\(void\);\r\n ~single_constructor\(\);\r\n} \*\(single_constructor \* const\)} \ ++ ++ set re \ ++ [multi_line_string_to_regexp \ ++ "type = class single_constructor {" \ ++ "" \ ++ " public:" \ ++ " single_constructor(void);" \ ++ " ~single_constructor(void);" \ ++ "} *(single_constructor * const)"] ++ gdb_test "ptype test5.single_constructor" $re \ + "simple object instance, ptype constructor" +- gdb_test "ptype single_constructor::single_constructor" \ +- {type = class single_constructor {\r\n public:\r\n single_constructor\(void\);\r\n ~single_constructor\(\);\r\n} \*\(single_constructor \* const\)} \ ++ gdb_test "ptype single_constructor::single_constructor" $re \ + "simple object class, ptype constructor" + + gdb_test "print test1.~gnu_obj_1" \ +diff --git a/gdb/testsuite/lib/gdb-utils.exp b/gdb/testsuite/lib/gdb-utils.exp +index 95c53d030d8..41989da3ed2 100644 +--- a/gdb/testsuite/lib/gdb-utils.exp ++++ b/gdb/testsuite/lib/gdb-utils.exp +@@ -38,6 +38,14 @@ proc string_to_regexp {str} { + return $result + } + ++# Convenience function that calls string_to_regexp for each arg, and ++# joins the results using "\r\n". ++ ++proc multi_line_string_to_regexp { args } { ++ set res [lmap arg $args {string_to_regexp $arg}] ++ return [multi_line {*}$res] ++} ++ + # Given a list of strings, adds backslashes as needed to each string to + # create a regexp that will match the string, and join the result. + +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.cp-namespace.exp-with-read1.patch b/gdb-testsuite-fix-gdb.cp-namespace.exp-with-read1.patch deleted file mode 100644 index 64e0052..0000000 --- a/gdb-testsuite-fix-gdb.cp-namespace.exp-with-read1.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 818f70aa9a6c17ddc79ac33f80c1a3e4df30ea14 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Sun, 14 Jan 2024 09:36:12 +0100 -Subject: [PATCH 46/48] [gdb/testsuite] Fix gdb.cp/namespace.exp with read1 - -With check-read1 we run into: -... -(gdb) break DNE>::DNE^M -Function "DNE>::DNE" not defined.^M -Make breakpoint pending on future shared library load? (y or [n]) y^M -Breakpoint 9 (DNE>::DNE) pending.^M -n^M -(gdb) FAIL: gdb.cp/namespace.exp: br malformed '>' (got interactive prompt) -n^M -... - -The question is supposed to be handled by the question and response arguments -to this gdb_test call: -... -gdb_test "break DNE>::DNE" "" "br malformed \'>\'" \ - "Make breakpoint pending on future shared library load?.*" "y" -... -but both this and the builtin handling in gdb_test_multiple triggers. - -The cause of this is that the question argument regexp is incomplete. - -Fix this by making sure that the entire question is matched in the regexp: -... -set yn_re [string_to_regexp {(y or [n])}] - ... - "Make breakpoint pending on future shared library load\\? $yn_re " "Y" -... - -Tested on x86_64-linux. ---- - gdb/testsuite/gdb.cp/namespace.exp | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/gdb/testsuite/gdb.cp/namespace.exp b/gdb/testsuite/gdb.cp/namespace.exp -index a9de09f087d..b1c7403f2c6 100644 ---- a/gdb/testsuite/gdb.cp/namespace.exp -+++ b/gdb/testsuite/gdb.cp/namespace.exp -@@ -251,8 +251,9 @@ gdb_test "print AAA::ALPHA" "\\$\[0-9\].* = AAA::ALPHA" - gdb_test "whatis ::C::CClass::NestedClass" "type = C::CClass::NestedClass" - gdb_test "whatis ::C::CClass::NestedClass *" "type = C::CClass::NestedClass \\*" - -+set yn_re [string_to_regexp {(y or [n])}] - # Break on functions with a malformed name. - gdb_test "break DNE>::DNE" "" "br malformed \'>\'" \ -- "Make breakpoint pending on future shared library load?.*" "y" -+ "Make breakpoint pending on future shared library load\\? $yn_re " "Y" - gdb_test "break DNE)::DNE" "" "br malformed \')\'" \ -- "Make breakpoint pending on future shared library load?.*" "y" -+ "Make breakpoint pending on future shared library load\\? $yn_re " "Y" --- -2.35.3 - diff --git a/gdb-testsuite-fix-gdb.cp-non-trivial-retval.exp-on-a.patch b/gdb-testsuite-fix-gdb.cp-non-trivial-retval.exp-on-a.patch new file mode 100644 index 0000000..af8d7de --- /dev/null +++ b/gdb-testsuite-fix-gdb.cp-non-trivial-retval.exp-on-a.patch @@ -0,0 +1,99 @@ +From 23574ea1b3502dd13efa9b3ebf32fee3118e6ff0 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Mon, 20 Jan 2025 05:41:01 +0100 +Subject: [PATCH 29/46] [gdb/testsuite] Fix gdb.cp/non-trivial-retval.exp on + arm-linux with gcc 13 + +On arm-linux, with target board unix/-mthumb, we get: +... +(gdb) PASS: gdb.cp/non-trivial-retval.exp: continue to breakpoint: Break here +p f1 (i1, i2)^M +$1 = {a = -136274256}^M +(gdb) FAIL: gdb.cp/non-trivial-retval.exp: gdb-command

+... + +This is not a problem with the inferior call, which works fine: +... +(gdb) p f1 (23, 100) +$3 = {a = 123} +... +but instead it's a problem with the location information: +... +(gdb) p i1 +$1 = -136274356 +(gdb) p i2 +$2 = 100 +... +which tells us to find the value of i1 in (DW_OP_fbreg: -12). + +The test-case passes if we drop -fvar-tracking, in which case the debug info +tells us to find the value of i1 in (DW_OP_fbreg: -20). + +This is with gcc 13.3.0 on Ubuntu 24.04. With gcc 14.2.0 on Debian testing, +the code is the same, but -fvar-tracking does use the correct +'(DW_OP_fbreg: -20)'. + +There seems to be some bugfix in -fvar-tracking for gcc 14. + +Workaround the bug by using constants 23 and 100 instead of i1 and i2 when +using -fvar-tracking and gcc < 14. + +Tested on arm-linux. + +PR testsuite/32549 +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32549 +--- + gdb/testsuite/gdb.cp/non-trivial-retval.exp | 28 ++++++++++++++++----- + 1 file changed, 22 insertions(+), 6 deletions(-) + +diff --git a/gdb/testsuite/gdb.cp/non-trivial-retval.exp b/gdb/testsuite/gdb.cp/non-trivial-retval.exp +index 6c9f7e13d2a..64c0867368d 100644 +--- a/gdb/testsuite/gdb.cp/non-trivial-retval.exp ++++ b/gdb/testsuite/gdb.cp/non-trivial-retval.exp +@@ -21,8 +21,18 @@ require allow_cplus_tests + + standard_testfile .cc + ++set i1 i1 ++set i2 i2 ++ + if {[have_fvar_tracking]} { + set additional_flags "additional_flags= -fvar-tracking" ++ ++ if { [gcc_major_version] < 14 } { ++ # For armv7, target board unix/-mthumb, -fvar-tracking and gcc 13 we ++ # get incorrect location info. Work around this by using constants instead. ++ set i1 23 ++ set i2 100 ++ } + } + + if {[prepare_for_testing "failed to prepare" $testfile $srcfile [list debug c++ $additional_flags]]} { +@@ -37,12 +47,18 @@ if {![runto_main]} { + gdb_breakpoint [gdb_get_line_number "Break here"] + gdb_continue_to_breakpoint "Break here" + +-gdb_test "p f1 (i1, i2)" ".* = {a = 123}" +-gdb_test "p f2 (i1, i2)" ".* = {b = 123}" +-gdb_test "p f22 (i1, i2)" ".* = {b1 = 123}" +-gdb_test "p f3 (i1, i2)" ".* = {.* c = 123}" +-gdb_test "p f4 (i1, i2)" ".* = {.* e = 123}" +-gdb_test "p f5 (i1, i2)" ".* = {f = 123}" ++gdb_test "p f1 ($i1, $i2)" ".* = {a = 123}" \ ++ "p f1 (i1, i2)" ++gdb_test "p f2 ($i1, $i2)" ".* = {b = 123}" \ ++ "p f2 (i1, i2)" ++gdb_test "p f22 ($i1, $i2)" ".* = {b1 = 123}" \ ++ "p f22 (i1, i2)" ++gdb_test "p f3 ($i1, $i2)" ".* = {.* c = 123}" \ ++ "p f3 (i1, i2)" ++gdb_test "p f4 ($i1, $i2)" ".* = {.* e = 123}" \ ++ "p f4 (i1, i2)" ++gdb_test "p f5 ($i1, $i2)" ".* = {f = 123}" \ ++ "p f5 (i1, i2)" + + gdb_breakpoint "f1" + gdb_breakpoint "f2" +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.dwarf2-dw2-fixed-point.exp-on-.patch b/gdb-testsuite-fix-gdb.dwarf2-dw2-fixed-point.exp-on-.patch new file mode 100644 index 0000000..2d44067 --- /dev/null +++ b/gdb-testsuite-fix-gdb.dwarf2-dw2-fixed-point.exp-on-.patch @@ -0,0 +1,54 @@ +From 80150dc7ac41e767d857905702bf4b57eb1c0029 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Fri, 16 Aug 2024 14:22:46 +0200 +Subject: [PATCH 11/46] [gdb/testsuite] Fix gdb.dwarf2/dw2-fixed-point.exp on + arm-linux + +With test-case gdb.dwarf2/dw2-fixed-point.exp on arm-linux I run into: +... +(gdb) PASS: gdb.dwarf2/dw2-fixed-point.exp: set lang ada +print pck.fp1_var^M +$1 = 0.3125^M +(gdb) FAIL: gdb.dwarf2/dw2-fixed-point.exp: print pck.fp1_var +... + +The problem is that the thumb prologue analyzer overshoot, setting the +breakpoint for main after line 49: +... + 46 int + 47 main (void) + 48 { + 49 pck__fp1_var++; +... +and consequently we see the value of pck.fp1_var after line 49 instead of +before line 49. This is PR tdep/31981. + +Work around this by removing line 49 and all similar subsequent lines, which +turn out to be dead code. + +Approved-By: Luis Machado + +Tested on arm-linux. +--- + gdb/testsuite/gdb.dwarf2/dw2-fixed-point.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/gdb/testsuite/gdb.dwarf2/dw2-fixed-point.c b/gdb/testsuite/gdb.dwarf2/dw2-fixed-point.c +index 58b97caf055..2789e6ac0fb 100644 +--- a/gdb/testsuite/gdb.dwarf2/dw2-fixed-point.c ++++ b/gdb/testsuite/gdb.dwarf2/dw2-fixed-point.c +@@ -46,11 +46,5 @@ int8_t pck__fp1_range_var = 16; + int + main (void) + { +- pck__fp1_var++; +- pck__fp1_var2++; +- pck__fp2_var++; +- pck__fp3_var++; +- pck__fp1_range_var++; +- + return 0; + } +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.dwarf2-dw2-gas-workaround.exp.patch b/gdb-testsuite-fix-gdb.dwarf2-dw2-gas-workaround.exp.patch deleted file mode 100644 index 99a0948..0000000 --- a/gdb-testsuite-fix-gdb.dwarf2-dw2-gas-workaround.exp.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 254988c36fe592e89af5d92e1d35a6eb4b09cbb0 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Mon, 6 Nov 2023 08:32:54 +0100 -Subject: [PATCH 2/2] [gdb/testsuite] Fix gdb.dwarf2/dw2-gas-workaround.exp - -Recently added test-case gdb.dwarf2/dw2-gas-workaround.exp: -- passes when gdb is configured using $(cd ../src; pwd)/configure, but -- fails when using ../src/configure. - -Fix this by making the matching more precise: -... -- -re -wrap "$objdir.*" { -+ -re -wrap "name_for_id = $objdir/$srcfile\r\n.*" { -... -such that we only fail on the line: -... -[symtab-create] start_subfile: name = dw2-lines.c, name_for_id = \ - /data/vries/gdb/leap-15-4/build/gdb/testsuite/dw2-lines.c^M -... - -Reported-By: Carl Love ---- - gdb/testsuite/gdb.dwarf2/dw2-gas-workaround.exp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-gas-workaround.exp b/gdb/testsuite/gdb.dwarf2/dw2-gas-workaround.exp -index ca2b10f23b3..7d5375a920a 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-gas-workaround.exp -+++ b/gdb/testsuite/gdb.dwarf2/dw2-gas-workaround.exp -@@ -83,7 +83,7 @@ if { [prepare_for_testing "failed to prepare" ${testfile} \ - - gdb_test_no_output "set debug symtab-create 1" - gdb_test_multiple "ptype bar" "" { -- -re -wrap "$objdir.*" { -+ -re -wrap "name_for_id = $objdir/$srcfile\r\n.*" { - fail $gdb_test_name - } - -re -wrap "" { --- -2.35.3 - diff --git a/gdb-testsuite-fix-gdb.dwarf2-dw2-lines.exp-on-arm-li.patch b/gdb-testsuite-fix-gdb.dwarf2-dw2-lines.exp-on-arm-li.patch new file mode 100644 index 0000000..9d6fc1a --- /dev/null +++ b/gdb-testsuite-fix-gdb.dwarf2-dw2-lines.exp-on-arm-li.patch @@ -0,0 +1,279 @@ +From e13b5af2c0bc0cdf1b2d66f184fff4ba019b28ec Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Wed, 4 Sep 2024 10:07:19 +0200 +Subject: [PATCH 12/46] [gdb/testsuite] Fix gdb.dwarf2/dw2-lines.exp on + arm-linux + +With test-case gdb.dwarf2/dw2-lines.exp on arm-linux, I run into: +... +(gdb) break bar_label^M +Breakpoint 2 at 0x4004f6: file dw2-lines.c, line 29.^M +(gdb) continue^M +Continuing.^M +^M +Breakpoint 2, bar () at dw2-lines.c:29^M +29 foo (2);^M +(gdb) PASS: $exp: cv=2: cdw=32: lv=2: ldw=32: continue to breakpoint: foo \(1\) +... + +The pass is incorrect because the continue lands at line 29 with "foo (2)" +instead of line line 27 with "foo (1)". + +A minimal version is: +... +$ gdb -q -batch dw2-lines.cv-2-cdw-32-lv-2-ldw-32 -ex "b bar_label" +Breakpoint 1 at 0x4f6: file dw2-lines.c, line 29. +... +where: +... +000004ec : + 4ec: b580 push {r7, lr} + 4ee: af00 add r7, sp, #0 + +000004f0 : + 4f0: 2001 movs r0, #1 + 4f2: f7ff fff1 bl 4d8 + +000004f6 : + 4f6: 2002 movs r0, #2 + 4f8: f7ff ffee bl 4d8 +... + +So, how does this happen? In short: +- skip_prologue_sal calls arm_skip_prologue with pc == 0x4ec, +- thumb_analyze_prologue returns 0x4f2 + (overshooting by 1 insn, PR tdep/31981), and +- skip_prologue_sal decides that we're mid-line, and updates to 0x4f6. + +However, this is a test-case about .debug_line info, so why didn't arm_skip_prologue +use the line info to skip the prologue? + +The answer is that the line info starts at bar_label, not at bar. + +Fixing that allows us to work around PR tdep/31981. + +Likewise in gdb.dwarf2/dw2-line-number-zero.exp. + +Instead, add a new test-case gdb.arch/skip-prologue.exp that is dedicated to +checking quality of architecture-specific prologue analysis, without being +written in an architecture-specific way. + +If fails on arm-linux for both marm and mthumb: +... +FAIL: gdb.arch/skip-prologue.exp: f2: $bp_addr == $prologue_end_addr (skipped too much) +FAIL: gdb.arch/skip-prologue.exp: f4: $bp_addr == $prologue_end_addr (skipped too much) +... +and passes for: +- x86_64-linux for {m64,m32}x{-fno-PIE/-no-pie,-fPIE/-pie} +- aarch64-linux. + +Tested on arm-linux. +--- + gdb/testsuite/gdb.arch/skip-prologue.c | 54 +++++++++++++ + gdb/testsuite/gdb.arch/skip-prologue.exp | 76 +++++++++++++++++++ + .../gdb.dwarf2/dw2-line-number-zero.exp | 8 ++ + gdb/testsuite/gdb.dwarf2/dw2-lines.c | 2 +- + gdb/testsuite/gdb.dwarf2/dw2-lines.exp | 4 + + 5 files changed, 143 insertions(+), 1 deletion(-) + create mode 100644 gdb/testsuite/gdb.arch/skip-prologue.c + create mode 100644 gdb/testsuite/gdb.arch/skip-prologue.exp + +diff --git a/gdb/testsuite/gdb.arch/skip-prologue.c b/gdb/testsuite/gdb.arch/skip-prologue.c +new file mode 100644 +index 00000000000..08ceacb6aa8 +--- /dev/null ++++ b/gdb/testsuite/gdb.arch/skip-prologue.c +@@ -0,0 +1,54 @@ ++/* Copyright 2024 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 . */ ++ ++void ++f1 (void) ++{ ++ asm ("f1_prologue_end: .globl f1_prologue_end"); ++} ++ ++int ++f2 (int a) ++{ ++ asm ("f2_prologue_end: .globl f2_prologue_end"); ++ return a; ++} ++ ++void ++f3 (void) ++{ ++ asm ("f3_prologue_end: .globl f3_prologue_end"); ++ f1 (); ++} ++ ++int ++f4 (int a) ++{ ++ asm ("f4_prologue_end: .globl f4_prologue_end"); ++ return f2 (a); ++} ++ ++int ++main (void) ++{ ++ f1 (); ++ f2 (0); ++ f3 (); ++ f4 (0); ++ ++ return 0; ++} +diff --git a/gdb/testsuite/gdb.arch/skip-prologue.exp b/gdb/testsuite/gdb.arch/skip-prologue.exp +new file mode 100644 +index 00000000000..89d2225151a +--- /dev/null ++++ b/gdb/testsuite/gdb.arch/skip-prologue.exp +@@ -0,0 +1,76 @@ ++# Copyright 2024 Free Software Foundation, Inc. ++ ++# 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 . ++ ++# Test-case that checks architecture-specific prologue analyzers. ++ ++standard_testfile ++ ++if { [prepare_for_testing "failed to prepare" $testfile $srcfile \ ++ {nodebug}] } { ++ return -1 ++} ++ ++proc do_test { f } { ++ set bp_addr "" ++ gdb_test_multiple "break $f" "" { ++ -re -wrap "Breakpoint $::decimal at ($::hex)" { ++ set bp_addr $expect_out(1,string) ++ pass $gdb_test_name ++ } ++ } ++ ++ if { $bp_addr == "" } { ++ return ++ } ++ ++ set prologue_end_addr "" ++ gdb_test_multiple "p /x &${f}_prologue_end" "" { ++ -re -wrap " = ($::hex)" { ++ set prologue_end_addr $expect_out(1,string) ++ pass $gdb_test_name ++ } ++ } ++ ++ if { $prologue_end_addr == "" } { ++ return ++ } ++ ++ set test {$bp_addr == $prologue_end_addr} ++ if { [expr $test] } { ++ pass $test ++ } elseif { $bp_addr < $prologue_end_addr } { ++ # We'll allow this. For instance, amd64 has a prologue ++ # analyzer that doesn't skip the 3rd instruction here, which saves an ++ # argument register to stack: ++ # ++ # 00000000004004ae : ++ # 4004ae: 55 push %rbp ++ # 4004af: 48 89 e5 mov %rsp,%rbp ++ # 4004b2: 89 7d fc mov %edi,-0x4(%rbp) ++ # 00000000004004b5 : ++ # ++ pass "$test (skipped less than possible)" ++ } elseif { $bp_addr > $prologue_end_addr } { ++ fail "$test (skipped too much)" ++ } else { ++ fail "$test" ++ } ++} ++ ++foreach f { f1 f2 f3 f4 } { ++ with_test_prefix $f { ++ do_test $f ++ } ++} +diff --git a/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp b/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp +index c510de42037..9124aff1dad 100644 +--- a/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp ++++ b/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp +@@ -56,6 +56,10 @@ Dwarf::assemble $asm_file { + file_name "$srcfile" 1 + + program { ++ DW_LNE_set_address $bar1_start ++ line 25 ++ DW_LNS_copy ++ + DW_LNE_set_address bar1_label + line 27 + DW_LNS_copy +@@ -76,6 +80,10 @@ Dwarf::assemble $asm_file { + DW_LNE_end_sequence + + ++ DW_LNE_set_address $bar2_start ++ line 39 ++ DW_LNS_copy ++ + DW_LNE_set_address bar2_label + line 41 + DW_LNS_copy +diff --git a/gdb/testsuite/gdb.dwarf2/dw2-lines.c b/gdb/testsuite/gdb.dwarf2/dw2-lines.c +index 67c98fecf02..221d7b95bc3 100644 +--- a/gdb/testsuite/gdb.dwarf2/dw2-lines.c ++++ b/gdb/testsuite/gdb.dwarf2/dw2-lines.c +@@ -22,7 +22,7 @@ foo (int x) + + void + bar (void) +-{ ++{ /* bar: */ + asm ("bar_label: .globl bar_label"); + foo (1); + asm ("bar_label_2: .globl bar_label_2"); +diff --git a/gdb/testsuite/gdb.dwarf2/dw2-lines.exp b/gdb/testsuite/gdb.dwarf2/dw2-lines.exp +index af5b6b71768..fd5b83edc5b 100644 +--- a/gdb/testsuite/gdb.dwarf2/dw2-lines.exp ++++ b/gdb/testsuite/gdb.dwarf2/dw2-lines.exp +@@ -88,6 +88,10 @@ proc test_1 { _cv _cdw64 _lv _ldw64 {_string_form ""}} { + # to set the current file explicitly. + DW_LNS_set_file $diridx + ++ DW_LNE_set_address $bar_start ++ line [line_for bar] ++ DW_LNS_copy ++ + DW_LNE_set_address bar_label + line [line_for bar_label] + DW_LNS_copy +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.mi-mi-dprintf.exp-with-read1.patch b/gdb-testsuite-fix-gdb.mi-mi-dprintf.exp-with-read1.patch deleted file mode 100644 index 1115c0c..0000000 --- a/gdb-testsuite-fix-gdb.mi-mi-dprintf.exp-with-read1.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 80b0afed39702c7a25d68f6b28427f92c5db6d80 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Sun, 14 Jan 2024 10:21:46 +0100 -Subject: [PATCH 45/48] [gdb/testsuite] Fix gdb.mi/mi-dprintf.exp with read1 - -When running test-case gdb.mi/mi-dprintf.exp with check-read1, I run into: -... -(gdb) ^M -PASS: gdb.mi/mi-dprintf.exp: gdb: mi 2nd dprintf stop --data-evaluate-expression stderr^M -^done,value="0x7ffff7e4a420 <_IO_2_1_stderr_>"^M -(gdb) FAIL: gdb.mi/mi-dprintf.exp: stderr symbol check -... - -The problem is in proc mi_gdb_is_stderr_available: -... -proc mi_gdb_is_stderr_available {} { - set has_stderr_symbol false - gdb_test_multiple "-data-evaluate-expression stderr" "stderr symbol check" { - -re "\\^error,msg=\"'stderr' has unknown type; cast it to its declared type\"\r\n$::mi_gdb_prompt$" { - } - -re "$::mi_gdb_prompt$" { - set has_stderr_symbol true - } - } -... -which uses a gdb_test_multiple that is supposed to use the mi prompt, but -doesn't use -prompt to indicate this. Consequently, the default patterns use -the regular gdb prompt, which trigger earlier than the two custom patterns -which use "$::mi_gdb_prompt$". - -Fix this by adding the missing -prompt "$::mi_gdb_prompt$" arguments. - -While we're at it, make the gdb_test_multiple call a bit more readable by -using variables, and by using -wrap. - -Tested on x86_64-linux, with: -- gcc and clang (to trigger both the has_stderr_symbol true and false cases) -- make check and make check-read1. ---- - gdb/testsuite/lib/mi-support.exp | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - -diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp -index 540eb3371c6..1b702e8a3bb 100644 ---- a/gdb/testsuite/lib/mi-support.exp -+++ b/gdb/testsuite/lib/mi-support.exp -@@ -2956,13 +2956,18 @@ proc foreach_mi_ui_mode { var_name body } { - # Check if GDB has information about the stderr symbol. - proc mi_gdb_is_stderr_available {} { - set has_stderr_symbol false -- gdb_test_multiple "-data-evaluate-expression stderr" "stderr symbol check" { -- -re "\\^error,msg=\"'stderr' has unknown type; cast it to its declared type\"\r\n$::mi_gdb_prompt$" { -+ -+ set cmd "-data-evaluate-expression stderr" -+ set test "stderr symbol check" -+ set msg_re {"'stderr' has unknown type; cast it to its declared type"} -+ gdb_test_multiple $cmd $test -prompt "$::mi_gdb_prompt$" { -+ -re -wrap "\\^error,msg=$msg_re" { - # Default value of false is fine. - } -- -re "$::mi_gdb_prompt$" { -+ -re -wrap "" { - set has_stderr_symbol true - } - } -+ - return $has_stderr_symbol - } --- -2.35.3 - diff --git a/gdb-testsuite-fix-gdb.python-py-format-address.exp-o.patch b/gdb-testsuite-fix-gdb.python-py-format-address.exp-o.patch new file mode 100644 index 0000000..76756db --- /dev/null +++ b/gdb-testsuite-fix-gdb.python-py-format-address.exp-o.patch @@ -0,0 +1,88 @@ +From 37ce118a44994fb178065eaed671c7036f3d93a5 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Thu, 20 Jun 2024 16:54:47 +0200 +Subject: [PATCH 34/46] [gdb/testsuite] Fix gdb.python/py-format-address.exp on + arm + +When running test-case gdb.python/py-format-address.exp on arm-linux, I get: +... +(gdb) python print("Got: " + gdb.format_address(0x103dd))^M +Got: 0x103dd

^M +(gdb) FAIL: $exp: symbol_filename=on: gdb.format_address, \ +result should have an offset +... + +What is expected here is: +... +Got: 0x103dd ^M +... + +Main starts at main_addr: +... +(gdb) print /x &main^M +$1 = 0x103dc^M +... +and we obtained next_addr 0x103dd by adding 1 to it: +... +set next_addr [format 0x%x [expr $main_addr + 1]] +... + +Adding 1 to $main_addr results in an address for a thumb function starting at +address 0x103dc, which is incorrect because main is an arm function (because +I'm running with target board unix/-marm). + +At some point during the call to format_addr, arm_addr_bits_remove removes +the thumb bit, which causes the +1 offset to be dropped, causing the FAIL. + +Fix this by using the address of the breakpoint on main, provided it's not at +the very start of main. + +Tested on arm-linux. + +PR testsuite/31452 +Bug: https://www.sourceware.org/bugzilla/show_bug.cgi?id=31452 +--- + .../gdb.python/py-format-address.exp | 20 +++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +diff --git a/gdb/testsuite/gdb.python/py-format-address.exp b/gdb/testsuite/gdb.python/py-format-address.exp +index 8e7cf47e03a..ab8022c753b 100644 +--- a/gdb/testsuite/gdb.python/py-format-address.exp ++++ b/gdb/testsuite/gdb.python/py-format-address.exp +@@ -40,7 +40,23 @@ if ![runto_main] { + # for the program space and architecture (these will be selected based + # on the current inferior). + set main_addr [get_hexadecimal_valueof "&main" "UNKNOWN"] +-set next_addr [format 0x%x [expr $main_addr + 1]] ++require {!string equal $main_addr {UNKNOWN}} ++ ++set next_addr "UNKNOWN" ++gdb_test_multiple "info break 1" "" { ++ -re -wrap " y +($hex) +in .*" { ++ set next_addr $expect_out(1,string) ++ set next_addr [regsub {^0x0+} $next_addr "0x"] ++ pass $gdb_test_name ++ } ++} ++if { $next_addr == "UNKNOWN" || $next_addr == $main_addr } { ++ set next_addr [format 0x%x [expr $main_addr + 1]] ++} ++ ++verbose -log "main_addr: $main_addr" ++verbose -log "next_addr: $next_addr" ++ + + foreach_with_prefix symbol_filename { on off } { + gdb_test_no_output "set print symbol-filename ${symbol_filename}" +@@ -56,7 +72,7 @@ foreach_with_prefix symbol_filename { on off } { + "gdb.format_address, result should have no offset" + + gdb_test "python print(\"Got: \" + gdb.format_address($next_addr))" \ +- "Got: $next_addr " \ ++ "Got: $next_addr " \ + "gdb.format_address, result should have an offset" + } + +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.python-py-format-string.exp-wi.patch b/gdb-testsuite-fix-gdb.python-py-format-string.exp-wi.patch new file mode 100644 index 0000000..51bea55 --- /dev/null +++ b/gdb-testsuite-fix-gdb.python-py-format-string.exp-wi.patch @@ -0,0 +1,65 @@ +From ae564bb3259a6ae34efa3dd48561709d116dc3bc Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Thu, 1 Aug 2024 09:23:24 +0200 +Subject: [PATCH 01/46] [gdb/testsuite] Fix gdb.python/py-format-string.exp + with python 3.13 + +On fedora rawhide, with python 3.13, I run into: +... +(gdb) python print (gdb.parse_and_eval ('a_point_t').format_string (invalid=True))^M +Python Exception : \ + this function got an unexpected keyword argument 'invalid'^M +Error occurred in Python: \ + this function got an unexpected keyword argument 'invalid'^M +(gdb) FAIL: $exp: format_string: lang_c: test_all_common: test_invalid_args: \ + a_point_t with option invalid=True +... + +A passing version with an older python version looks like: +... +(gdb) python print (gdb.parse_and_eval ('a_point_t').format_string (invalid=True))^M +Python Exception : \ + 'invalid' is an invalid keyword argument for this function^M +Error occurred in Python: \ + 'invalid' is an invalid keyword argument for this function^M +(gdb) PASS: $exp: format_string: lang_c: test_all_common: test_invalid_args: \ + a_point_t with option invalid=True +... + +Fix this by accepting the updated error message. + +Tested on aarch64-linux. + +PR testsuite/31912 +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31912 +--- + gdb/testsuite/gdb.python/py-format-string.exp | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/gdb/testsuite/gdb.python/py-format-string.exp b/gdb/testsuite/gdb.python/py-format-string.exp +index 0c70ad562c7..92092139639 100644 +--- a/gdb/testsuite/gdb.python/py-format-string.exp ++++ b/gdb/testsuite/gdb.python/py-format-string.exp +@@ -1104,10 +1104,16 @@ proc_with_prefix test_invalid_args {} { + "12" \ + "TypeError.*: format_string\\(\\) takes 0 positional arguments but 1 were given.*" + ++ # For python <= 3.12. ++ set re1 \ ++ "TypeError.*: 'invalid' is an invalid keyword argument for this function" ++ # For python >= 3.13. ++ set re2 \ ++ "TypeError.*: this function got an unexpected keyword argument 'invalid'" + check_format_string \ + "a_point_t" \ + "invalid=True" \ +- "TypeError.*: 'invalid' is an invalid keyword argument for this function.*" ++ "($re1|$re2).*" + + check_format_string \ + "a_point_t" \ + +base-commit: 735d4dc480bcdcb0eddde33b687bd5f11d4f86ee +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.python-py-mi-cmd.exp-with-pyth.patch b/gdb-testsuite-fix-gdb.python-py-mi-cmd.exp-with-pyth.patch new file mode 100644 index 0000000..45aa42d --- /dev/null +++ b/gdb-testsuite-fix-gdb.python-py-mi-cmd.exp-with-pyth.patch @@ -0,0 +1,154 @@ +From 6874385b527cf5d5a43a01484ea58f3912a06b67 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Tue, 20 Aug 2024 15:57:36 +0200 +Subject: [PATCH 02/46] [gdb/testsuite] Fix gdb.python/py-mi-cmd.exp with + python 3.13 + +When running test-case gdb.python/py-mi-cmd.exp with python 3.13, I run into: +... +Expecting: ^(-pycmd exp[^M +]+)?(.*&"Traceback \(most recent call last\):.."^M +&"[^^M +]+py-mi-cmd.py[^^M +]+"^M +&"[^^M +]+raise gdb.GdbError\(\).."^M +&"gdb.GdbError.."^M +\^error,msg="Error occurred in Python\."[^M +]+[(]gdb[)] ^M +[ ]*) +-pycmd exp^M +&"Traceback (most recent call last):\n"^M +&" File \"py-mi-cmd.py\", line 76, in invoke\n raise gdb.GdbError()\n"^M +&"gdb.GdbError\n"^M +^error,msg="Error occurred in Python."^M +(gdb) ^M +FAIL: gdb.python/py-mi-cmd.exp: -pycmd exp (unexpected output) +... + +In contrast, with python 3.12 I have: +... +Expecting: ^(-pycmd exp[^M +]+)?(.*&"Traceback \(most recent call last\):.."^M +&"[^^M +]+py-mi-cmd.py[^^M +]+"^M +&"[^^M +]+raise gdb.GdbError\(\).."^M +&"gdb.GdbError.."^M +\^error,msg="Error occurred in Python\."[^M +]+[(]gdb[)] ^M +[ ]*) +-pycmd exp^M +&"Traceback (most recent call last):\n"^M +&" File \"py-mi-cmd.py\", line 76, in invoke\n"^M +&" raise gdb.GdbError()\n"^M +&"gdb.GdbError\n"^M +^error,msg="Error occurred in Python."^M +(gdb) ^M +PASS: gdb.python/py-mi-cmd.exp: -pycmd exp +... + +To make it easier to understand what we're looking at, let's take this out of +the mi interpreter context and use the cli interpreter: +... +$ gdb -q -batch -ex "set trace-commands on" -x gdb.in ++set python print-stack full ++source py-mi-cmd.py ++python pycmd1('-pycmd') ++python pycmd1.invoke (pycmd1, ["exp"]) +Traceback (most recent call last): + File "", line 1, in + File "py-mi-cmd.py", line 76, in invoke + raise gdb.GdbError() +gdb.GdbError +gdb.in:4: Error in sourced command file: +Error occurred in Python. +... + +Interestingly, this is what we're seeing with both python 3.12 and 3.13. + +The difference between the python versions is that: +- with python 3.12 each line is printed by itself, and +- with python 3.13 two particular lines are printed toghether. + +With the cli interpreter, that makes no difference, because the '\n' is +interpreted. + +But with the mi interpreter, that causes a difference in output because the +'\n' is not interpreted, but rather printed literally. + +Fix this by accepting the new output in addition to the old one. + +Tested on aarch64-linux. + +Reviewed-by: Thiago Jung Bauermann + +PR testsuite/31913 +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31913 +--- + gdb/testsuite/gdb.python/py-mi-cmd.exp | 48 ++++++++++++++++++++++---- + 1 file changed, 41 insertions(+), 7 deletions(-) + +diff --git a/gdb/testsuite/gdb.python/py-mi-cmd.exp b/gdb/testsuite/gdb.python/py-mi-cmd.exp +index 28c71cd75f3..52914099e6d 100644 +--- a/gdb/testsuite/gdb.python/py-mi-cmd.exp ++++ b/gdb/testsuite/gdb.python/py-mi-cmd.exp +@@ -119,13 +119,47 @@ mi_gdb_test "-pycmd dash-key" \ + # With this argument the command raises a gdb.GdbError with no message + # string. GDB considers this a bug in the user program, so prints a + # backtrace, and a generic error message. +-mi_gdb_test "-pycmd exp" \ +- [multi_line ".*&\"Traceback \\(most recent call last\\):..\"" \ +- "&\"\[^\r\n\]+${testfile}.py\[^\r\n\]+\"" \ +- "&\"\[^\r\n\]+raise gdb.GdbError\\(\\)..\"" \ +- "&\"gdb.GdbError..\"" \ +- "\\^error,msg=\"Error occurred in Python\\.\""] \ +- "-pycmd exp" ++ ++set line1 \ ++ [string_to_regexp {Traceback (most recent call last):\n}] ++set line2 \ ++ [string cat \ ++ [string_to_regexp { File \"}] \ ++ "\[^\r\n\]+" \ ++ [string_to_regexp ${testfile}.py] \ ++ [string_to_regexp {\", line }] \ ++ $decimal \ ++ [string_to_regexp {, in invoke\n}]] ++set line3 \ ++ [string_to_regexp { raise gdb.GdbError()\n}] ++set line4 \ ++ [string_to_regexp {gdb.GdbError\n}] ++set errline \ ++ [string_to_regexp {^error,msg="Error occurred in Python."}] ++ ++set start_line \ ++ [string_to_regexp {&"}] ++set end_line \ ++ [string_to_regexp {"}] ++ ++# With python <= 3.12. ++set re1 \ ++ [multi_line \ ++ $start_line$line1$end_line \ ++ $start_line$line2$end_line \ ++ $start_line$line3$end_line \ ++ $start_line$line4$end_line \ ++ $errline] ++ ++# With python >= 3.13. ++set re2 \ ++ [multi_line \ ++ $start_line$line1$end_line \ ++ $start_line$line2$line3$end_line \ ++ $start_line$line4$end_line \ ++ $errline] ++ ++mi_gdb_test "-pycmd exp" ($re1|$re2) + + mi_gdb_test "python pycmd2('-pycmd')" \ + ".*\\^done" \ +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.rust-completion.exp-timeout-on.patch b/gdb-testsuite-fix-gdb.rust-completion.exp-timeout-on.patch new file mode 100644 index 0000000..d650637 --- /dev/null +++ b/gdb-testsuite-fix-gdb.rust-completion.exp-timeout-on.patch @@ -0,0 +1,70 @@ +From 90e16cc4b30a742387b6d8324a862a5e4a91b24e Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Fri, 10 Jan 2025 08:53:29 +0100 +Subject: [PATCH 30/46] [gdb/testsuite] Fix gdb.rust/completion.exp timeout on + riscv64-linux + +On riscv64-linux, with test-case gdb.rust/completion.exp I run into the +following timeout: +... +(gdb) complete break pars^M +FAIL: gdb.rust/completion.exp: complete break pars (timeout) +... + +Replaying the scenario outside the testsuite show us that the command takes +~13 seconds: +... +$ gdb -q -batch -x gdb.in + ... +2025-01-08 12:23:46.853 - command started ++complete break pars +break parse.rs +break parse_printf_format +break parse_running_mmaps_unix.rs +break parser.rs +2025-01-08 12:23:59.600 - command finished +Command execution time: 12.677752 (cpu), 12.748565 (wall) +... +while the timeout is 10 seconds. + +The riscv64 processor on the server (cfarm91) is not fast (a fair amount of +the skip_huge_test test-cases times out), but something else is going on as +well. + +For x86_64-linux, roughly measuring the size of debug info in the exec get us: +... +$ readelf -wi outputs/gdb.rust/completion/completion | wc -l +2007 +... +while on the riscv64 server I get: +... +$ readelf -wi outputs/gdb.rust/completion/completion | wc -l +1606950 +... + +So it seems reasonable that the test is somewhat slower on riscv64. + +Fix this by using timeout factor 2. + +Tested on riscv64-linux and x86_64-linux. + +Approved-By: Tom Tromey +--- + gdb/testsuite/gdb.rust/completion.exp | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/gdb/testsuite/gdb.rust/completion.exp b/gdb/testsuite/gdb.rust/completion.exp +index 02fbdcdf92c..1b0638ad21a 100644 +--- a/gdb/testsuite/gdb.rust/completion.exp ++++ b/gdb/testsuite/gdb.rust/completion.exp +@@ -31,4 +31,6 @@ if {![runto ${srcfile}:$line]} { + return -1 + } + +-gdb_test "complete break pars" ".*" ++with_timeout_factor 2 { ++ gdb_test "complete break pars" ".*" ++} +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.server-server-connect.exp-for-.patch b/gdb-testsuite-fix-gdb.server-server-connect.exp-for-.patch deleted file mode 100644 index 7606cae..0000000 --- a/gdb-testsuite-fix-gdb.server-server-connect.exp-for-.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 237a0ec8a20cc5e233d630a43d9cacd2774a564d Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Wed, 20 Mar 2024 19:31:24 +0100 -Subject: [PATCH 37/48] [gdb/testsuite] Fix gdb.server/server-connect.exp for - missing ipv6 - -On a system without ipv6 support enabled, when running test-case -gdb.server/server-connect.exp, it takes about 4 minutes, and I get: -... -builtin_spawn gdbserver --once ::1:2347 server-connect^M -Can't open socket: Address family not supported by protocol.^M -Exiting^M -PASS: gdb.server/server-connect.exp: tcp6: start gdbserver -target remote tcp6:::1:2347^M -A program is being debugged already. Kill it? (y or n) y^M -could not connect: Address family not supported by protocol.^M -(gdb) FAIL: gdb.server/server-connect.exp: tcp6: connect to gdbserver using tcp6:::1 -... - -Fix this by: -- recognizing the error message in gdbserver_start, and returning an empty list - to signal unsupported, and -- handling the unsupported response in the test-case. - -This brings testing time down to 2 seconds, and gets me: -... -UNSUPPORTED: gdb.server/server-connect.exp: tcp6: start gdbserver -UNSUPPORTED: gdb.server/server-connect.exp: tcp6-with-brackets: start gdbserver -UNSUPPORTED: gdb.server/server-connect.exp: udp6: start gdbserver -UNSUPPORTED: gdb.server/server-connect.exp: udp6-with-brackets: start gdbserver -... - -Tested on aarch64-linux. - -Approved-By: Tom Tromey - -PR testsuite/31502 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31502 ---- - gdb/testsuite/gdb.server/server-connect.exp | 3 +++ - gdb/testsuite/lib/gdbserver-support.exp | 3 +++ - 2 files changed, 6 insertions(+) - -diff --git a/gdb/testsuite/gdb.server/server-connect.exp b/gdb/testsuite/gdb.server/server-connect.exp -index 1f5b9a27cf4..ffdfaa89154 100644 ---- a/gdb/testsuite/gdb.server/server-connect.exp -+++ b/gdb/testsuite/gdb.server/server-connect.exp -@@ -88,6 +88,9 @@ save_vars { GDB_TEST_SOCKETHOST } { - } else { - if { $gdbserver_should_fail } { - fail "$test: gdbserver should fail but did not" -+ } elseif { [llength $res] == 0 } { -+ unsupported $test -+ continue - } else { - pass "$test" - } -diff --git a/gdb/testsuite/lib/gdbserver-support.exp b/gdb/testsuite/lib/gdbserver-support.exp -index a3cccf54a72..d065fb36764 100644 ---- a/gdb/testsuite/lib/gdbserver-support.exp -+++ b/gdb/testsuite/lib/gdbserver-support.exp -@@ -429,6 +429,9 @@ proc gdbserver_start { options arguments } { - -re ".*: cannot resolve name: .*\r\n" { - error "gdbserver cannot resolve name." - } -+ -re "Can't open socket: Address family not supported by protocol." { -+ return {} -+ } - timeout { - error "Timeout waiting for gdbserver response." - } --- -2.35.3 - diff --git a/gdb-testsuite-fix-gdb.threads-access-mem-running-thr.patch b/gdb-testsuite-fix-gdb.threads-access-mem-running-thr.patch new file mode 100644 index 0000000..2e42c92 --- /dev/null +++ b/gdb-testsuite-fix-gdb.threads-access-mem-running-thr.patch @@ -0,0 +1,119 @@ +From 87a754a5b94b2360f39525f63f2292f23e9e0fe6 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Thu, 27 Mar 2025 13:18:57 +0100 +Subject: [PATCH] [gdb/testsuite] Fix + gdb.threads/access-mem-running-thread-exit.exp + +In OBS (Open Build Service), with a 15.2 based gdb package, occasionally I run +into: +... +(gdb) inferior 2 +[Switching to inferior 2 [process 31372] (access-mem-running-thread-exit)] +[Switching to thread 2.1 (Thread 0xf7db9700 (LWP 31372))](running) +(gdb) print global_var = 555 +$1 = 555 +(gdb) print global_var +$2 = 556 +(gdb) FAIL: $exp: all-stop: access mem \ + (print global_var after writing, inf=2, iter=1) +... + +I managed to reproduce this on current trunk using a reproducer patch (posted +in the PR). + +The problem is due to commit 31c21e2c13d ("[gdb/testsuite] Fix +gdb.threads/access-mem-running-thread-exit.exp with clang"), which introduced +an increment of global_var at the start of main. + +This created a race between: +- gdb modifying global_var, and +- the inferior modifying global_var. + +Fix this by: +- adding a new empty function setup_done, +- adding a call to setup_done after the increment of global_var, and +- rather than running to main, running to setup_done. + +Tested on x86_64-linux. + +PR testsuite/32822 +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32822 +--- + .../gdb.threads/access-mem-running-thread-exit.c | 7 +++++++ + .../gdb.threads/access-mem-running-thread-exit.exp | 10 +++++----- + 2 files changed, 12 insertions(+), 5 deletions(-) + +diff --git a/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.c b/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.c +index af05b13c763..e22bf12df75 100644 +--- a/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.c ++++ b/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.c +@@ -97,6 +97,11 @@ thread_fn (void *arg) + return NULL; + } + ++static void ++setup_done (void) ++{ ++} ++ + int + main (void) + { +@@ -104,6 +109,8 @@ main (void) + + global_var++; + ++ setup_done (); ++ + for (i = 0; i < 4; i++) + { + struct thread_arg *p; +diff --git a/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.exp b/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.exp +index 784f17ff3b2..42222c0fb35 100644 +--- a/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.exp ++++ b/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.exp +@@ -54,7 +54,7 @@ proc test { non_stop } { + clean_restart ${binfile} + } + +- if ![runto_main] { ++ if ![runto setup_done] { + return -1 + } + +@@ -76,7 +76,7 @@ proc test { non_stop } { + # Start the second inferior. + with_test_prefix "second inferior" { + # With stub targets that do reload on run, if we let the new +- # inferior share inferior 1's connection, runto_main would ++ # inferior share inferior 1's connection, runto would + # fail because GDB is already connected to something, like + # e.g. with --target_board=native-gdbserver: + # +@@ -86,10 +86,10 @@ proc test { non_stop } { + # Already connected to a remote target. Disconnect? (y or n) + # + # Instead, start the inferior with no connection, and let +- # gdb_load/runto_main spawn a new remote connection/gdbserver. ++ # gdb_load/runto spawn a new remote connection/gdbserver. + # + # OTOH, with extended-remote, we must let the new inferior +- # reuse the current connection, so that runto_main below can ++ # reuse the current connection, so that runto below can + # issue the "run" command, and have the inferior run on the + # remote target. If we forced no connection, then "run" would + # either fail if "set auto-connect-native-target" is on, like +@@ -108,7 +108,7 @@ proc test { non_stop } { + + gdb_load $binfile + +- if ![runto_main] { ++ if ![runto setup_done] { + return -1 + } + } + +base-commit: af5d18ee9fd221ca8a54de4957ec5c351599f13c +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb.threads-leader-exit-attach.exp.patch b/gdb-testsuite-fix-gdb.threads-leader-exit-attach.exp.patch new file mode 100644 index 0000000..5f9d9e2 --- /dev/null +++ b/gdb-testsuite-fix-gdb.threads-leader-exit-attach.exp.patch @@ -0,0 +1,80 @@ +From e0c1db6156fa8ee35661a9964062eeb69a963576 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Mon, 29 Jul 2024 14:05:52 +0200 +Subject: [PATCH] [gdb/testsuite] Fix gdb.threads/leader-exit-attach.exp with + check-read1 + +With test-case gdb.threads/leader-exit-attach.exp and check-read1, I run into: +... +(gdb) attach 18591^M +Attaching to program: leader-exit-attach, process 18591^M +warning: process 18591 is a zombie - the process has already terminatedKFAIL: $exp: attach (PRMS: gdb/31555) +^M +ptrace: Operation not permitted.^M +(gdb) FAIL: $exp: get valueof "$_inferior_thread_count" +... + +The problem is that the gdb_test_multiple in the test-case doesn't consume the +prompt in all clauses: +... +gdb_test_multiple "attach $testpid" "attach" { + -re "Attaching to process $testpid failed.*" { + # GNU/Linux gdbserver. Linux ptrace does not let you attach + # to zombie threads. + setup_kfail "gdb/31555" *-*-linux* + fail $gdb_test_name + } + -re "warning: process $testpid is a zombie - the process has already terminated.*" { + # Native GNU/Linux. Linux ptrace does not let you attach to + # zombie threads. + setup_kfail "gdb/31555" *-*-linux* + fail $gdb_test_name + } + -re "Attaching to program: $escapedbinfile, process $testpid.*$gdb_prompt $" { + pass $gdb_test_name + set attached 1 + } +} +... + +Fix this by using -wrap in the first two clauses. + +While we're at it, also use -wrap in the third clause. + +Tested on x86_64-linux. +--- + gdb/testsuite/gdb.threads/leader-exit-attach.exp | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/gdb/testsuite/gdb.threads/leader-exit-attach.exp b/gdb/testsuite/gdb.threads/leader-exit-attach.exp +index c1ed1baaa67..a1bc2d470d5 100644 +--- a/gdb/testsuite/gdb.threads/leader-exit-attach.exp ++++ b/gdb/testsuite/gdb.threads/leader-exit-attach.exp +@@ -41,19 +41,19 @@ set is_gdbserver [target_is_gdbserver] + set attached 0 + + gdb_test_multiple "attach $testpid" "attach" { +- -re "Attaching to process $testpid failed.*" { ++ -re -wrap "Attaching to process $testpid failed.*" { + # GNU/Linux gdbserver. Linux ptrace does not let you attach + # to zombie threads. + setup_kfail "gdb/31555" *-*-linux* + fail $gdb_test_name + } +- -re "warning: process $testpid is a zombie - the process has already terminated.*" { ++ -re -wrap "warning: process $testpid is a zombie - the process has already terminated.*" { + # Native GNU/Linux. Linux ptrace does not let you attach to + # zombie threads. + setup_kfail "gdb/31555" *-*-linux* + fail $gdb_test_name + } +- -re "Attaching to program: $escapedbinfile, process $testpid.*$gdb_prompt $" { ++ -re -wrap "Attaching to program: $escapedbinfile, process $testpid.*" { + pass $gdb_test_name + set attached 1 + } + +base-commit: 6d7adb1f1e6ecad5a6b94319e4d272a82be16277 +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdb_py_module_available-for-python.patch b/gdb-testsuite-fix-gdb_py_module_available-for-python.patch new file mode 100644 index 0000000..81b0296 --- /dev/null +++ b/gdb-testsuite-fix-gdb_py_module_available-for-python.patch @@ -0,0 +1,39 @@ +From 7992b582e5a55bf2fd64f2f94b854d335c36c6a5 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Tue, 28 Jan 2025 17:44:42 +0100 +Subject: [PATCH] [gdb/testsuite] Fix gdb_py_module_available for python 3.4 + +On SLE-12, I run into: +... +(gdb) python import pygments +Python Exception : No module named 'pygments' +Error occurred in Python: No module named 'pygments' +(gdb) FAIL: gdb.base/style.exp: python import pygments +... + +Fix this by handling the output string in gdb_py_module_available. + +Tested on x86_64-linux. +--- + gdb/testsuite/lib/gdb-python.exp | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/gdb/testsuite/lib/gdb-python.exp b/gdb/testsuite/lib/gdb-python.exp +index e27d5c17769..f8141193596 100644 +--- a/gdb/testsuite/lib/gdb-python.exp ++++ b/gdb/testsuite/lib/gdb-python.exp +@@ -64,6 +64,9 @@ proc gdb_py_module_available { name } { + -re -wrap "ImportError: No module named '?${name}'?.*" { + set available false + } ++ -re -wrap "Python Exception : No module named '?${name}'?.*" { ++ set available false ++ } + -re -wrap "python import ${name}" { + set available true + } + +base-commit: 94df6741bbabaa9a51960446b2af4c0bed01b54b +-- +2.43.0 + diff --git a/gdb-testsuite-fix-gdbserver-pid-in-gdb.server-server.patch b/gdb-testsuite-fix-gdbserver-pid-in-gdb.server-server.patch deleted file mode 100644 index d96e679..0000000 --- a/gdb-testsuite-fix-gdbserver-pid-in-gdb.server-server.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 7357f73483cfe8f3e8ec2dd9ca2fb3d52206055a Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Wed, 17 Apr 2024 11:45:02 +0200 -Subject: [PATCH 28/48] [gdb/testsuite] Fix gdbserver pid in - gdb.server/server-kill-python.exp - -The commit ed32754a8c7 ("[gdb/testsuite] Fix gdb.server/multi-ui-errors.exp for -remote target") intended to addresss the problem that this command: -... -set gdbserver_pid [exp_pid -i $server_spawn_id] -... -does not return the pid of the gdbserver for remote target, but rather the one -of the ssh client session. - -To fix this, it added another way of getting the gdbserver_pid. - -For the trivial case of non-remote target, the PID found by either method -should be identical, but if we compare those by adding -"puts [exec ps -p $gdbserver_pid]" we get: -... - PID TTY TIME CMD -31711 pts/8 00:00:00 gdbserver - PID TTY TIME CMD -31718 pts/8 00:00:00 server-kill-pyt -... - -The problem is that while the gdbserver PID is supposed to be read from the -result of "gdb.execute ('p server_pid')" in the python script, instead it's -taken from: -... -Process server-kill-python created; pid = 31718^M -... - -Fix this by moving the printing of the gdbserver PID out of the python script. - -Also double-check the two methods against each other, in the cases that they -should match. - -Tested on x86_64-linux. - -PR testsuite/31633 -https://sourceware.org/bugzilla/show_bug.cgi?id=31633 ---- - .../gdb.server/server-kill-python.exp | 37 +++++++++++-------- - 1 file changed, 21 insertions(+), 16 deletions(-) - -diff --git a/gdb/testsuite/gdb.server/server-kill-python.exp b/gdb/testsuite/gdb.server/server-kill-python.exp -index dcb6eddd6eb..778880984ec 100644 ---- a/gdb/testsuite/gdb.server/server-kill-python.exp -+++ b/gdb/testsuite/gdb.server/server-kill-python.exp -@@ -37,7 +37,7 @@ set host_binfile [gdb_remote_download host $binfile] - set res [gdbserver_spawn "${target_binfile}"] - set gdbserver_protocol [lindex $res 0] - set gdbserver_gdbport [lindex $res 1] --set gdbserver_pid [exp_pid -i $server_spawn_id] -+set gdbserver_pid_check [exp_pid -i $server_spawn_id] - - set break_linenr [gdb_get_line_number "@@XX@@ Inferior Starting @@XX@@"] - -@@ -48,9 +48,6 @@ puts $fd \ - "import gdb - - def do_gdb_stuff (): -- gdb.execute ('break $srcfile:$break_linenr') -- gdb.execute ('continue') -- gdb.execute ('p server_pid') - gdb.execute ('continue') - - do_gdb_stuff()" -@@ -68,24 +65,32 @@ if {[gdb_spawn_with_cmdline_opts \ - - gdb_load $binfile - gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport --send_gdb "source $host_file1\n" -+ -+gdb_test "break $srcfile:$break_linenr" - - # Get the gdbserver PID. - set gdbserver_pid 0 -- --# Wait for the inferior to start up. --with_spawn_id $server_spawn_id { -- gdb_test_multiple "" "get gdbserver PID" { -- -re " = ($decimal)\r\n" { -- set gdbserver_pid $expect_out(1,string) -- pass $gdb_test_name -- } -+gdb_test "continue" -+gdb_test_multiple "print server_pid" "get gdbserver PID" { -+ -re -wrap " = ($decimal)" { -+ set gdbserver_pid $expect_out(1,string) -+ pass $gdb_test_name - } -+} - -- if { $gdbserver_pid == 0 } { -- return -- } -+if { $gdbserver_pid == 0 } { -+ return -+} -+ -+if { ![is_remote target] && $gdbserver_pid != $gdbserver_pid_check } { -+ error "Failed to get correct gdbserver pid" -+} - -+send_gdb "source $host_file1\n" -+ -+ -+# Wait for the inferior to start up. -+with_spawn_id $server_spawn_id { - gdb_test_multiple "" "ensure inferior is running" { - -re "@@XX@@ Inferior Starting @@XX@@" { - pass $gdb_test_name --- -2.35.3 - diff --git a/gdb-testsuite-fix-license-text-in-gdb.reverse-map-to.patch b/gdb-testsuite-fix-license-text-in-gdb.reverse-map-to.patch deleted file mode 100644 index 7bbae1c..0000000 --- a/gdb-testsuite-fix-license-text-in-gdb.reverse-map-to.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 5b840a3cb41ada4cee1456d16993809abeb30eda Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Thu, 22 Feb 2024 12:09:14 +0100 -Subject: [PATCH 43/48] [gdb/testsuite] Fix license text in - gdb.reverse/map-to-same-line.{c,exp} - -I noticed in gdb.reverse/map-to-same-line.{c,exp} that the license urls are -using some kind of indirection via urldefense.proofpoint.com. - -Fix this by removing this indirection. - -Tested on x86_64-linux. - -PR testsuite/31358 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31358 ---- - gdb/testsuite/gdb.reverse/map-to-same-line.c | 2 +- - gdb/testsuite/gdb.reverse/map-to-same-line.exp | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/gdb/testsuite/gdb.reverse/map-to-same-line.c b/gdb/testsuite/gdb.reverse/map-to-same-line.c -index 3086e849231..f6b4f10dbf7 100644 ---- a/gdb/testsuite/gdb.reverse/map-to-same-line.c -+++ b/gdb/testsuite/gdb.reverse/map-to-same-line.c -@@ -11,7 +11,7 @@ - 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 . */ -+ along with this program. If not, see . */ - - /* The purpose of this test is to create a DWARF line table that contains two - or more entries for the same line. When stepping (forwards or backwards), -diff --git a/gdb/testsuite/gdb.reverse/map-to-same-line.exp b/gdb/testsuite/gdb.reverse/map-to-same-line.exp -index 63f8c9c76b3..1510cf98d0c 100644 ---- a/gdb/testsuite/gdb.reverse/map-to-same-line.exp -+++ b/gdb/testsuite/gdb.reverse/map-to-same-line.exp -@@ -11,7 +11,7 @@ - # 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 . -+# along with this program. If not, see . - - # When stepping (forwards or backwards), GDB should step over the entire line - # and not just a particular entry in the line table. This test was added to --- -2.35.3 - diff --git a/gdb-testsuite-fix-missing-return-type-in-gdb.linespe.patch b/gdb-testsuite-fix-missing-return-type-in-gdb.linespe.patch deleted file mode 100644 index 25083c5..0000000 --- a/gdb-testsuite-fix-missing-return-type-in-gdb.linespe.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 3e4d764ebb264f0c9153c6fd3727f67d4454ae9b Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Fri, 29 Mar 2024 07:47:30 +0100 -Subject: [PATCH 32/48] [gdb/testsuite] Fix missing return type in - gdb.linespec/break-asm-file.c - -On fedora rawhide, when running test-case gdb.linespec/break-asm-file.exp, I -get: -... -gdb compile failed, break-asm-file.c:21:8: error: \ - return type defaults to 'int' [-Wimplicit-int] - 21 | static func() - | ^~~~ -... - -Fix this by adding the missing return type. - -Tested on aarch64-linux. - -Approved-By: John Baldwin ---- - gdb/testsuite/gdb.linespec/break-asm-file.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gdb/testsuite/gdb.linespec/break-asm-file.c b/gdb/testsuite/gdb.linespec/break-asm-file.c -index 41f0904fc84..e7bdc26b1ec 100644 ---- a/gdb/testsuite/gdb.linespec/break-asm-file.c -+++ b/gdb/testsuite/gdb.linespec/break-asm-file.c -@@ -18,7 +18,7 @@ - void func3(); - void func2(); - --static func() -+static void func() - { - } - --- -2.35.3 - diff --git a/gdb-testsuite-fix-regexp-in-gdb.ada-mi_var_access.ex.patch b/gdb-testsuite-fix-regexp-in-gdb.ada-mi_var_access.ex.patch new file mode 100644 index 0000000..f17ead7 --- /dev/null +++ b/gdb-testsuite-fix-regexp-in-gdb.ada-mi_var_access.ex.patch @@ -0,0 +1,50 @@ +From d9da3935f1be9c0d008764d6fff4b5dc277a5cd7 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Tue, 30 Jul 2024 21:50:17 +0200 +Subject: [PATCH 04/46] [gdb/testsuite] Fix regexp in gdb.ada/mi_var_access.exp + some more + +When running test-case gdb.ada/mi_var_access.exp on arm-linux (debian trixie), +I run into: +... +Expecting: ^(-var-create A_String_Access \* A_String_Access[ +]+)?((\^done,name="A_String_Access",numchild="[0-9]+",.*|\^error,msg="Value out of range.".*)[ +]+[(]gdb[)] +[ ]*) +-var-create A_String_Access * A_String_Access +^error,msg="Cannot access memory at address 0x4" +(gdb) +FAIL: gdb.ada/mi_var_access.exp: Create varobj (unexpected output) +... + +This is similar to the problem fixed by commit c5a72a8d1c3 ("[gdb/testsuite] +Fix regexp in gdb.ada/mi_var_access.exp"). + +The problem in both cases is that we're printing an uninitialized variable, +and consequently we can run into various error messages during printing. + +Fix this as in the other commit, by accepting the error message. + +Tested on arm-linux. +--- + gdb/testsuite/gdb.ada/mi_var_access.exp | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/gdb/testsuite/gdb.ada/mi_var_access.exp b/gdb/testsuite/gdb.ada/mi_var_access.exp +index b71c8f32151..e797a1576cb 100644 +--- a/gdb/testsuite/gdb.ada/mi_var_access.exp ++++ b/gdb/testsuite/gdb.ada/mi_var_access.exp +@@ -42,8 +42,9 @@ mi_continue_to_line \ + # to match possible values. + set re_ok "\\^done,name=\"A_String_Access\",numchild=\"$decimal\",.*" + set re_error "\\^error,msg=\"Value out of range\.\".*" ++set re_error2 "\\^error,msg=\"Cannot access memory at address $hex\"" + mi_gdb_test "-var-create A_String_Access * A_String_Access" \ +- "($re_ok|$re_error)" \ ++ "($re_ok|$re_error|$re_error2)" \ + "Create varobj" + + set bp_location [gdb_get_line_number "STOP2" ${testdir}/mi_access.adb] +-- +2.43.0 + diff --git a/gdb-testsuite-fix-regexp-in-gdb.arch-i386-disp-step-.patch b/gdb-testsuite-fix-regexp-in-gdb.arch-i386-disp-step-.patch new file mode 100644 index 0000000..5311ad0 --- /dev/null +++ b/gdb-testsuite-fix-regexp-in-gdb.arch-i386-disp-step-.patch @@ -0,0 +1,71 @@ +From da8d1a26f1015678245f23abc0b96ee6fba9f16d Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Thu, 29 Aug 2024 07:31:12 +0200 +Subject: [PATCH 32/46] [gdb/testsuite] Fix regexp in + gdb.arch/i386-disp-step-self-call.exp + +Usually, with test-case gdb.arch/i386-disp-step-self-call.exp I get: +... +(gdb) x/1wx 0xffffc4f8^M +0xffffc4f8: 0x08048472^M +(gdb) PASS: $exp: check return address was updated correctly +... +but sometimes I run into: +... +(gdb) x/1wx 0xffffc5c8^M +0xffffc5c8: 0x0804917e^M +(gdb) FAIL: $exp: check return address was updated correctly +... + +The problem is that here: +... +set next_insn_addr 0x[format %08X $next_insn_addr] +gdb_test "x/1wx 0x[format %x $sp]" "$hex:\\s+$next_insn_addr" \ + "check return address was updated correctly" +... +we're trying to match string 0x0804917e against regexp 0x0804917E due to using +"%08X" as format string. + +We only run into this problem if the address contains letters, which apparently +usually isn't the case. + +Fix this by using "%08x" instead as format string. + +Likewise in test-case gdb.arch/amd64-disp-step-self-call.exp. + +Tested on x86_64-linux. + +PR testsuite/32121 +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32121 +--- + gdb/testsuite/gdb.arch/amd64-disp-step-self-call.exp | 2 +- + gdb/testsuite/gdb.arch/i386-disp-step-self-call.exp | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/gdb/testsuite/gdb.arch/amd64-disp-step-self-call.exp b/gdb/testsuite/gdb.arch/amd64-disp-step-self-call.exp +index 762d19a2960..2db3ff228c9 100644 +--- a/gdb/testsuite/gdb.arch/amd64-disp-step-self-call.exp ++++ b/gdb/testsuite/gdb.arch/amd64-disp-step-self-call.exp +@@ -77,6 +77,6 @@ gdb_assert {[expr $sp == $new_sp]} \ + "check stack pointer was updated as expected" + + # Check the contents of the stack were updated to the expected value. +-set next_insn_addr 0x[format %016X $next_insn_addr] ++set next_insn_addr 0x[format %016x $next_insn_addr] + gdb_test "x/1gx 0x[format %x $sp]" "$hex:\\s+$next_insn_addr" \ + "check return address was updated correctly" +diff --git a/gdb/testsuite/gdb.arch/i386-disp-step-self-call.exp b/gdb/testsuite/gdb.arch/i386-disp-step-self-call.exp +index b2cb902f8ed..5de7ebcd69f 100644 +--- a/gdb/testsuite/gdb.arch/i386-disp-step-self-call.exp ++++ b/gdb/testsuite/gdb.arch/i386-disp-step-self-call.exp +@@ -77,6 +77,6 @@ gdb_assert {[expr $sp == $new_sp]} \ + "check stack pointer was updated as expected" + + # Check the contents of the stack were updated to the expected value. +-set next_insn_addr 0x[format %08X $next_insn_addr] ++set next_insn_addr 0x[format %08x $next_insn_addr] + gdb_test "x/1wx 0x[format %x $sp]" "$hex:\\s+$next_insn_addr" \ + "check return address was updated correctly" +-- +2.43.0 + diff --git a/gdb-testsuite-fix-regexp-in-gdb.threads-stepi-over-c.patch b/gdb-testsuite-fix-regexp-in-gdb.threads-stepi-over-c.patch new file mode 100644 index 0000000..ebd390e --- /dev/null +++ b/gdb-testsuite-fix-regexp-in-gdb.threads-stepi-over-c.patch @@ -0,0 +1,42 @@ +From 2140bfdb0f523bcfd4475bc9ef779d693f0852fc Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Fri, 21 Jun 2024 16:53:19 +0200 +Subject: [PATCH 1/2] [gdb/testsuite] Fix regexp in + gdb.threads/stepi-over-clone.exp + +On fedora rawhide, I ran into: +... +(gdb) continue^M +Continuing.^M +^M +Catchpoint 2 (call to syscall clone3), 0x000000000042097d in __clone3 ()^M +(gdb) FAIL: gdb.threads/stepi-over-clone.exp: continue +... + +Fix this by updating a regexp to also recognize __clone3. + +Tested on x86_64-linux. + +Tested-By: Guinevere Larsen +--- + gdb/testsuite/gdb.threads/stepi-over-clone.exp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gdb/testsuite/gdb.threads/stepi-over-clone.exp b/gdb/testsuite/gdb.threads/stepi-over-clone.exp +index f671fd7b8bd..da8bbf6a215 100644 +--- a/gdb/testsuite/gdb.threads/stepi-over-clone.exp ++++ b/gdb/testsuite/gdb.threads/stepi-over-clone.exp +@@ -48,7 +48,7 @@ gdb_test_multiple "catch syscall group:process" "catch process syscalls" { + } + } + +-set re_loc1 "$hex in clone\[23\]? \\(\\)" ++set re_loc1 "$hex in (__)?clone\[23\]? \\(\\)" + set re_loc2 "$decimal\[ \t\]+in \[^\r\n\]+" + set re_loc3 "clone\[23\]? \\(\\) at \[^:\]+:$decimal" + + +base-commit: 1b57388d5731941f69010502bb59c24bd1db9f68 +-- +2.43.0 + diff --git a/gdb-testsuite-fix-regexp-in-vgdb_start.patch b/gdb-testsuite-fix-regexp-in-vgdb_start.patch deleted file mode 100644 index 2591fa6..0000000 --- a/gdb-testsuite-fix-regexp-in-vgdb_start.patch +++ /dev/null @@ -1,66 +0,0 @@ -From acc30323a8bc8aa04d404356e96b003a9a30543f Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Thu, 25 Jan 2024 16:36:09 +0100 -Subject: [PATCH 06/48] [gdb/testsuite] Fix regexp in vgdb_start - -On Fedora 39 aarch64 I run into: -... -(gdb) target remote | vgdb --wait=2 --max-invoke-ms=2500 --pid=2114437^M -Remote debugging using | vgdb --wait=2 --max-invoke-ms=2500 --pid=2114437^M -relaying data between gdb and process 2114437^M -warning: remote target does not support file transfer, \ - attempting to access files from local filesystem.^M -Reading symbols from /lib/ld-linux-aarch64.so.1...^M -_start () at ../sysdeps/aarch64/dl-start.S:22^M -warning: 22 ../sysdeps/aarch64/dl-start.S: No such file or directory^M -(gdb) FAIL: gdb.base/valgrind-infcall.exp: target remote for vgdb -... - -For contrast, on openSUSE Leap 15.4 x86_64 I have: -... -(gdb) target remote | vgdb --wait=2 --max-invoke-ms=2500 --pid=18797^M -Remote debugging using | vgdb --wait=2 --max-invoke-ms=2500 --pid=18797^M -relaying data between gdb and process 18797^M -warning: remote target does not support file transfer, \ - attempting to access files from local filesystem.^M -Reading symbols from /lib64/ld-linux-x86-64.so.2...^M -(No debugging symbols found in /lib64/ld-linux-x86-64.so.2)^M -0x0000000004002550 in _start () from /lib64/ld-linux-x86-64.so.2^M -(gdb) PASS: gdb.base/valgrind-infcall.exp: target remote for vgdb -... - -The fail happens in vgdb_start because the regexp only matches the -"in _start ()" variant, not the "_start () at": -... - gdb_test "$vgdbcmd" " in \\.?_start .*" "target remote for vgdb" -... -Which variant you get is determined by presence of debug info. - -Fix this by also matching the "_start () at" variant. - -Tested aarch64-linux and x86_64-linux. - -Approved-By: Tom Tromey ---- - gdb/testsuite/lib/valgrind.exp | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/gdb/testsuite/lib/valgrind.exp b/gdb/testsuite/lib/valgrind.exp -index a1cd85a7b09..f9096663509 100644 ---- a/gdb/testsuite/lib/valgrind.exp -+++ b/gdb/testsuite/lib/valgrind.exp -@@ -92,7 +92,10 @@ proc vgdb_start { {active_at_startup 1} } { - set vgdbcmd "target remote | vgdb --wait=2 --max-invoke-ms=2500 --pid=$vgdbpid" - - if { $active_at_startup } { -- gdb_test "$vgdbcmd" " in \\.?_start .*" "target remote for vgdb" -+ set start_re1 " in \\.?_start " -+ set start_re2 "\\.?_start \\(\\) at " -+ gdb_test "$vgdbcmd" "($start_re1|$start_re2).*" \ -+ "target remote for vgdb" - } else { - # Let $binfile run a bit before attaching. This is a bit of a hack, - # in that it lets test-case valgrind-infcall-2.exp run to the point of --- -2.35.3 - diff --git a/gdb-testsuite-fix-spurious-fails-with-examine-backwa.patch b/gdb-testsuite-fix-spurious-fails-with-examine-backwa.patch deleted file mode 100644 index a786701..0000000 --- a/gdb-testsuite-fix-spurious-fails-with-examine-backwa.patch +++ /dev/null @@ -1,221 +0,0 @@ -From 8bf7fdfc16f5d5fd9a94c233c0c41d307ba86cd2 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Tue, 21 Nov 2023 13:15:29 +0100 -Subject: [PATCH 04/48] [gdb/testsuite] Fix spurious FAILs with - examine-backward.exp, again - -Commit 59a561480d5 ("Fix spurious FAILs with examine-backward.exp") describes -the problem that: -... -The test case examine-backward.exp issues the command "x/-s" after the end -of the first string in TestStrings, but without making sure that this -string is preceded by a string terminator. Thus GDB may spuriously print -some random characters from before that string, and then the test fails. -... - -The commit fixes the problem by adding a Barrier variable before the TestStrings -variable: -... -+const char Barrier[] = { 0x0 }; - const char TestStrings[] = { -... - -There is however no guarantee that Barrier is placed immediately before -TestStrings. - -Before recent commit 169fe7ab54b ("Change gdb.base/examine-backwards.exp for -AIX.") on x86_64-linux, I see: -... -0000000000400660 R Barrier -0000000000400680 R TestStrings -... - -So while the Barrier variable is the first before the TestStrings variable, -it's not immediately preceding TestStrings. - -After commit 169fe7ab54b: -... -0000000000402259 B Barrier -0000000000402020 D TestStrings -... -they're not even in the same section anymore. - -Fix this reliably by adding the zero in the array itself: -... -char TestStringsBase[] = { - 0x0, - ... -}; -char *TestStrings = &TestStringsBase[1]; -... -and do likewise for TestStringsH and TestStringsW. - -Tested on x86_64-linux. - -PR testsuite/31064 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31064 ---- - gdb/testsuite/gdb.base/examine-backward.c | 35 ++++++++++++++------- - gdb/testsuite/gdb.base/examine-backward.exp | 18 +++++------ - 2 files changed, 33 insertions(+), 20 deletions(-) - -diff --git a/gdb/testsuite/gdb.base/examine-backward.c b/gdb/testsuite/gdb.base/examine-backward.c -index 354c2e2f323..5549cc20a4a 100644 ---- a/gdb/testsuite/gdb.base/examine-backward.c -+++ b/gdb/testsuite/gdb.base/examine-backward.c -@@ -32,15 +32,12 @@ literals. The content of each array is the same as followings: - }; - */ - --/* This is here just to ensure we have a null character before -- TestStrings, to avoid showing garbage when we look for strings -- backwards from TestStrings. */ -+unsigned char TestStringsBase[] = { -+ /* This is here just to ensure we have a null character before -+ TestStrings, to avoid showing garbage when we look for strings -+ backwards from TestStrings. */ -+ 0x0, - --unsigned char Barrier[] = { -- 0x00, --}; -- --unsigned char TestStrings[] = { - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, - 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, -@@ -54,7 +51,14 @@ unsigned char TestStrings[] = { - 0x00 - }; - --short TestStringsH[] = { -+unsigned char *TestStrings = &TestStringsBase[1]; -+ -+short TestStringsHBase[] = { -+ /* This is here just to ensure we have a null character before -+ TestStringsH, to avoid showing garbage when we look for strings -+ backwards from TestStringsH. */ -+ 0x0, -+ - 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, - 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, - 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, -@@ -67,7 +71,14 @@ short TestStringsH[] = { - 0x0000 - }; - --int TestStringsW[] = { -+short *TestStringsH = &TestStringsHBase[1]; -+ -+int TestStringsWBase[] = { -+ /* This is here just to ensure we have a null character before -+ TestStringsW, to avoid showing garbage when we look for strings -+ backwards from TestStringsW. */ -+ 0x0, -+ - 0x00000041, 0x00000042, 0x00000043, 0x00000044, - 0x00000045, 0x00000046, 0x00000047, 0x00000048, - 0x00000049, 0x0000004a, 0x0000004b, 0x0000004c, -@@ -89,11 +100,13 @@ int TestStringsW[] = { - 0x00000000 - }; - -+int *TestStringsW = &TestStringsWBase[1]; -+ - int - main (void) - { - /* Clang++ eliminates the variables if nothing references them. */ -- int dummy = Barrier[0] + TestStrings[0] + TestStringsH[0] + TestStringsW[0]; -+ int dummy = TestStrings[0] + TestStringsH[0] + TestStringsW[0]; - - /* Backward disassemble test requires at least 20 instructions in - this function. Adding a simple bubble sort. */ -diff --git a/gdb/testsuite/gdb.base/examine-backward.exp b/gdb/testsuite/gdb.base/examine-backward.exp -index 7c8a08c0726..4e197d7d725 100644 ---- a/gdb/testsuite/gdb.base/examine-backward.exp -+++ b/gdb/testsuite/gdb.base/examine-backward.exp -@@ -145,7 +145,7 @@ gdb_test_no_output "set charset ASCII" - - with_test_prefix "char-width=1, print-max=20" { - gdb_test_no_output "set print elements 20" -- gdb_test_sequence "x/6s &TestStrings" "take 6 strings forward" { -+ gdb_test_sequence "x/6s TestStrings" "take 6 strings forward" { - "\"ABCDEFGHIJKLMNOPQRST\"\.\.\." - "\"UVWXYZ\"" - "\"\"" -@@ -162,7 +162,7 @@ with_test_prefix "char-width=1, print-max=20" { - "\"[^\"]+\"" - "\"01234567890123456789\"\.\.\." - } -- gdb_test_sequence "x/6s &TestStrings" "take 6 strings forward again" { -+ gdb_test_sequence "x/6s TestStrings" "take 6 strings forward again" { - "\"ABCDEFGHIJKLMNOPQRST\"\.\.\." - "\"UVWXYZ\"" - "\"\"" -@@ -187,7 +187,7 @@ with_test_prefix "char-width=1, print-max=20" { - - with_test_prefix "char-width=2, print-max=20" { - gdb_test_no_output "set print elements 20" -- gdb_test_sequence "x/6sh &TestStringsH" "take 6 strings forward" { -+ gdb_test_sequence "x/6sh TestStringsH" "take 6 strings forward" { - "u\"ABCDEFGHIJKLMNOPQRST\"\.\.\." - "u\"UVWXYZ\"" - "u\"\"" -@@ -204,7 +204,7 @@ with_test_prefix "char-width=2, print-max=20" { - "u\"[^\"]+\"" - "u\"01234567890123456789\"\.\.\." - } -- gdb_test_sequence "x/6sh &TestStringsH" "take 6 strings forward again" { -+ gdb_test_sequence "x/6sh TestStringsH" "take 6 strings forward again" { - "u\"ABCDEFGHIJKLMNOPQRST\"\.\.\." - "u\"UVWXYZ\"" - "u\"\"" -@@ -229,7 +229,7 @@ with_test_prefix "char-width=2, print-max=20" { - - with_test_prefix "char-width=4, print-max=20" { - gdb_test_no_output "set print elements 20" -- gdb_test_sequence "x/6sw &TestStringsW" "take 6 strings forward" { -+ gdb_test_sequence "x/6sw TestStringsW" "take 6 strings forward" { - "U\"ABCDEFGHIJKLMNOPQRST\"\.\.\." - "U\"UVWXYZ\"" - "U\"\"" -@@ -246,7 +246,7 @@ with_test_prefix "char-width=4, print-max=20" { - "U\"[^\"]+\"" - "U\"01234567890123456789\"\.\.\." - } -- gdb_test_sequence "x/6sw &TestStringsW" "take 6 strings forward again" { -+ gdb_test_sequence "x/6sw TestStringsW" "take 6 strings forward again" { - "U\"ABCDEFGHIJKLMNOPQRST\"\.\.\." - "U\"UVWXYZ\"" - "U\"\"" -@@ -271,7 +271,7 @@ with_test_prefix "char-width=4, print-max=20" { - - with_test_prefix "char-width=2, print-max=0" { - gdb_test_no_output "set print elements 0" -- gdb_test_sequence "x/6sh &TestStringsH" "take 6 strings forward" { -+ gdb_test_sequence "x/6sh TestStringsH" "take 6 strings forward" { - "u\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"" - "u\"\"" - "u\"\"" -@@ -289,7 +289,7 @@ with_test_prefix "char-width=2, print-max=0" { - "u\"012345678901234567890123456789\"" - "u\"!!!!!!\"" - } -- gdb_test_sequence "x/6sh &TestStringsH" "take 6 strings forward again" { -+ gdb_test_sequence "x/6sh TestStringsH" "take 6 strings forward again" { - "u\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"" - "u\"\"" - "u\"\"" -@@ -314,7 +314,7 @@ with_test_prefix "char-width=2, print-max=0" { - - with_test_prefix "char-width=1, print-max=4" { - gdb_test_no_output "set print elements 4" -- gdb_test_sequence "x/9s &TestStrings" "take 9 strings forward" { -+ gdb_test_sequence "x/9s TestStrings" "take 9 strings forward" { - "\"ABCD\"\.\.\." - "\"EFGH\"\.\.\." - "\"IJKL\"\.\.\." --- -2.35.3 - diff --git a/gdb-testsuite-fix-test-case-gdb.threads-attach-stopp.patch b/gdb-testsuite-fix-test-case-gdb.threads-attach-stopp.patch deleted file mode 100644 index beef20a..0000000 --- a/gdb-testsuite-fix-test-case-gdb.threads-attach-stopp.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 3596f8119753089d8dd8c0aff800dbf2e283a111 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Thu, 28 Mar 2024 08:26:31 +0100 -Subject: [PATCH 34/48] [gdb/testsuite] Fix test-case - gdb.threads/attach-stopped.exp on manjaro linux - -When running test-case gdb.threads/attach-stopped.exp on aarch64-linux, using -the manjaro linux distro, I get: -... - (gdb) thread apply all bt^M - ^M - Thread 2 (Thread 0xffff8d8af120 (LWP 278116) "attach-stopped"):^M - #0 0x0000ffff8d964864 in clock_nanosleep () from /usr/lib/libc.so.6^M - #1 0x0000ffff8d969cac in nanosleep () from /usr/lib/libc.so.6^M - #2 0x0000ffff8d969b68 in sleep () from /usr/lib/libc.so.6^M - #3 0x0000aaaade370828 in func (arg=0x0) at attach-stopped.c:29^M - #4 0x0000ffff8d930aec in ?? () from /usr/lib/libc.so.6^M - #5 0x0000ffff8d99a5dc in ?? () from /usr/lib/libc.so.6^M - ^M - Thread 1 (Thread 0xffff8db62020 (LWP 278111) "attach-stopped"):^M - #0 0x0000ffff8d92d2d8 in ?? () from /usr/lib/libc.so.6^M - #1 0x0000ffff8d9324b8 in ?? () from /usr/lib/libc.so.6^M - #2 0x0000aaaade37086c in main () at attach-stopped.c:45^M - (gdb) FAIL: gdb.threads/attach-stopped.exp: threaded: attach2 to stopped bt -... - -The problem is that the test-case expects to see start_thread: -... - gdb_test "thread apply all bt" ".*sleep.*start_thread.*" \ - "$threadtype: attach2 to stopped bt" -... -but lack of symbols makes that impossible. - -Fix this by allowing " in ?? () from " as well. - -Tested on aarch64-linux. - -PR testsuite/31451 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31451 ---- - gdb/testsuite/gdb.threads/attach-stopped.exp | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/gdb/testsuite/gdb.threads/attach-stopped.exp b/gdb/testsuite/gdb.threads/attach-stopped.exp -index acdfcb5d8c5..b28fbd1a3d3 100644 ---- a/gdb/testsuite/gdb.threads/attach-stopped.exp -+++ b/gdb/testsuite/gdb.threads/attach-stopped.exp -@@ -54,10 +54,12 @@ proc corefunc { threadtype } { - } - - # ".*sleep.*clone.*" would fail on s390x as bt stops at START_THREAD there. -+ set test "$threadtype: attach2 to stopped bt" - if {[string equal $threadtype threaded]} { -- gdb_test "thread apply all bt" ".*sleep.*start_thread.*" "$threadtype: attach2 to stopped bt" -+ gdb_test "thread apply all bt" \ -+ ".*sleep.*(start_thread| in \\?\\? \\(\\) from ).*" $test - } else { -- gdb_test "bt" ".*sleep.*main.*" "$threadtype: attach2 to stopped bt" -+ gdb_test "bt" ".*sleep.*main.*" $test - } - - gdb_exit --- -2.35.3 - diff --git a/gdb-testsuite-fix-test-in-gdb.python-py-finish-break.patch b/gdb-testsuite-fix-test-in-gdb.python-py-finish-break.patch deleted file mode 100644 index b977f01..0000000 --- a/gdb-testsuite-fix-test-in-gdb.python-py-finish-break.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 7658c4d52562eef199e30fcd2da7da9a56d5d9b3 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Tue, 27 Feb 2024 16:18:32 +0100 -Subject: [PATCH 41/48] [gdb/testsuite] Fix test in - gdb.python/py-finish-breakpoint.exp - -With test-case gdb.python/py-finish-breakpoint.exp, we run into: -... -(gdb) python print (finishbp_default.hit_count) -Traceback (most recent call last): - File "", line 1, in -RuntimeError: Breakpoint 3 is invalid. -Error while executing Python code. -(gdb) PASS: gdb.python/py-finish-breakpoint.exp: normal conditions: \ - check finishBP on default frame has been hit -... - -The test producing the pass is: -... - gdb_test "python print (finishbp_default.hit_count)" "1.*" \ - "check finishBP on default frame has been hit" -... -so the pass is produced because the 1 in "line 1" matches "1.*". - -Temporary breakpoints are removed when hit, and consequently accessing the -hit_count attribute of a temporary python breakpoint (gdb.Breakpoint class) is -not possible, and as per spec we get a RuntimeError. - -So the RuntimeError is correct, and not specific to finish breakpoints. - -The test presumably attempts to match: -... -(gdb) python print (finishbp_default.hit_count) -1 -... -but most likely this output was never produced by any gdb version. - -Fix this by checking whether the finishbp_default breakpoint has hit by -checking that finishbp_default.is_valid() is False. - -Tested on aarch64-linux. - -Approved-By: Tom Tromey - -PR testsuite/31391 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31391 ---- - gdb/testsuite/gdb.python/py-finish-breakpoint.exp | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/gdb/testsuite/gdb.python/py-finish-breakpoint.exp b/gdb/testsuite/gdb.python/py-finish-breakpoint.exp -index e5a46874afd..687b9ad38cb 100644 ---- a/gdb/testsuite/gdb.python/py-finish-breakpoint.exp -+++ b/gdb/testsuite/gdb.python/py-finish-breakpoint.exp -@@ -73,7 +73,8 @@ with_test_prefix "normal conditions" { - "check MyFinishBreakpoint hit" - gdb_test "python print (finishbp.return_value)" "-5.*" "check return_value" - -- gdb_test "python print (finishbp_default.hit_count)" "1.*" "check finishBP on default frame has been hit" -+ gdb_test "python print (finishbp_default.is_valid())" "False" \ -+ "check finishBP on default frame has been hit" - gdb_test "python print (finishbp.is_valid())" "False.*"\ - "ensure that finish bp is invalid afer normal hit" - --- -2.35.3 - diff --git a/gdb-testsuite-fix-timeout-in-gdb.mi-mi-multi-command.patch b/gdb-testsuite-fix-timeout-in-gdb.mi-mi-multi-command.patch new file mode 100644 index 0000000..f69b515 --- /dev/null +++ b/gdb-testsuite-fix-timeout-in-gdb.mi-mi-multi-command.patch @@ -0,0 +1,69 @@ +From 25157766c1f81deecb53f2b784177a0d14c3d945 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Mon, 23 Sep 2024 07:45:54 +0200 +Subject: [PATCH 41/46] [gdb/testsuite] Fix timeout in + gdb.mi/mi-multi-commands.exp + +On aarch64-linux, with test-case gdb.mi/mi-multi-commands.exp once in a while +I run into (edited for readability): +... +(gdb) ^M +-data-evaluate-expression $a^M +-data-evaluate-^done,value="\"FIRST COMMAND\""^M +expression $b(gdb) ^M +^M +^done,value="\"TEST COMPLETE\""^M +(gdb) ^M +PASS: $exp: args=: look for first command output, command length 236 +FAIL: $exp: args=: look for second command output, command length 236 (timeout) +... + +This is more likely to trigger when running the test-case using +taskset -c (where in a big.little setup we pick a little cpu). + +The setup here is that the test-case issues these two commands at once: +... +-data-evaluate-expression $a +-data-evaluate-expression $b +... +where the length of the first command is artificially increased by prefixing +it with spaces, show as above. + +What happens is that gdb, after parsing the first command, executes it. +Then the output of the first command intermixes with the echoing of the second +command, which produces this line containing the first prompt: +... +expression $b(gdb) ^M +... +which doesn't match the \r\n prefix of the regexp supposed to consume the +first prompt: +... + -re "\r\n$mi_gdb_prompt" { +... + +Fix this by dropping the \r\n prefix. + +Tested on aarch64-linux. + +PR testsuite/29781 +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29781 +--- + gdb/testsuite/gdb.mi/mi-multi-commands.exp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gdb/testsuite/gdb.mi/mi-multi-commands.exp b/gdb/testsuite/gdb.mi/mi-multi-commands.exp +index 3a2e774bddc..028e187366a 100644 +--- a/gdb/testsuite/gdb.mi/mi-multi-commands.exp ++++ b/gdb/testsuite/gdb.mi/mi-multi-commands.exp +@@ -103,7 +103,7 @@ proc run_test { args } { + set seen_first_message true + exp_continue + } +- -re "\r\n$mi_gdb_prompt" { ++ -re "$mi_gdb_prompt" { + gdb_assert $seen_first_message $gdb_test_name + } + } +-- +2.43.0 + diff --git a/gdb-testsuite-fix-timeouts-in-gdb.threads-step-over-.patch b/gdb-testsuite-fix-timeouts-in-gdb.threads-step-over-.patch new file mode 100644 index 0000000..64ad453 --- /dev/null +++ b/gdb-testsuite-fix-timeouts-in-gdb.threads-step-over-.patch @@ -0,0 +1,103 @@ +From 2723a9ea67f16593591c4db9101e423ff73e6353 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Thu, 16 Jan 2025 09:39:55 +0100 +Subject: [PATCH 31/37] [gdb/testsuite] Fix timeouts in + gdb.threads/step-over-thread-exit.exp + +Once in a while, I run into a timeout in test-case +gdb.threads/step-over-thread-exit.exp: +... +(gdb) continue^M +Continuing.^M +[New Thread 0xfffff7cff1a0 (LWP 2874854)]^M +^M +Thread 97 "step-over-threa" hit Breakpoint 2, 0x0000000000410314 in \ + my_exit_syscall () at gdb/testsuite/lib/my-syscalls.S:74^M +74 SYSCALL (my_exit, __NR_exit)^M +(gdb) [Thread 0xfffff7cff1a0 (LWP 2874853) exited]^M +FAIL: $exp: step_over_mode=displaced: non-stop=on: target-non-stop=on: \ + schedlock=off: cmd=continue: ns_stop_all=0: iter 95: continue (timeout) +... + +I can reproduce it more frequently by running with taskset -c . + +Fix this by using -no-prompt-anchor. + +This requires us to add -no-prompt-anchor to proc gdb_test_multiple. + +Tested on aarch64-linux. + +PR testsuite/32489 +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32489 +--- + gdb/testsuite/gdb.threads/step-over-thread-exit.exp | 5 +++-- + gdb/testsuite/lib/gdb.exp | 9 ++++++++- + 2 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/gdb/testsuite/gdb.threads/step-over-thread-exit.exp b/gdb/testsuite/gdb.threads/step-over-thread-exit.exp +index 8eb93995657..98cc94e9528 100644 +--- a/gdb/testsuite/gdb.threads/step-over-thread-exit.exp ++++ b/gdb/testsuite/gdb.threads/step-over-thread-exit.exp +@@ -193,7 +193,7 @@ proc test {step_over_mode non-stop target-non-stop schedlock cmd ns_stop_all} { + with_test_prefix "iter $i" { + set ok 0 + set thread "" +- gdb_test_multiple "continue" "" { ++ gdb_test_multiple "continue" "" -no-prompt-anchor { + -re -wrap "Thread ($::decimal) .*hit Breakpoint $::decimal.* my_exit_syscall .*" { + set thread $expect_out(1,string) + set ok 1 +@@ -206,7 +206,8 @@ proc test {step_over_mode non-stop target-non-stop schedlock cmd ns_stop_all} { + } + + if {${non-stop}} { +- gdb_test -nopass "thread $thread" "Switching to thread .*" \ ++ gdb_test -nopass -no-prompt-anchor "thread $thread" \ ++ "Switching to thread .*" \ + "switch to event thread" + } + } +diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp +index c32dccab43e..008c1b83c1e 100644 +--- a/gdb/testsuite/lib/gdb.exp ++++ b/gdb/testsuite/lib/gdb.exp +@@ -977,6 +977,10 @@ proc fill_in_default_prompt {prompt_regexp with_anchor} { + # if one of them matches. If MESSAGE is empty COMMAND will be used. + # -prompt PROMPT_REGEXP specifies a regexp matching the expected prompt + # after the command output. If empty, defaults to "$gdb_prompt $". ++# -no-prompt-anchor specifies that if the default prompt regexp is used, it ++# should not be anchored at the end of the buffer. This means that the ++# pattern can match even if there is stuff output after the prompt. Does not ++# have any effect if -prompt is specified. + # -lbl specifies that line-by-line matching will be used. + # EXPECT_ARGUMENTS will be fed to expect in addition to the standard + # patterns. Pattern elements will be evaluated in the caller's +@@ -1076,6 +1080,7 @@ proc gdb_test_multiple { command message args } { + + set line_by_line 0 + set prompt_regexp "" ++ set prompt_anchor 1 + for {set i 0} {$i < [llength $args]} {incr i} { + set arg [lindex $args $i] + if { $arg == "-prompt" } { +@@ -1083,6 +1088,8 @@ proc gdb_test_multiple { command message args } { + set prompt_regexp [lindex $args $i] + } elseif { $arg == "-lbl" } { + set line_by_line 1 ++ } elseif { $arg == "-no-prompt-anchor" } { ++ set prompt_anchor 0 + } else { + set user_code $arg + break +@@ -1094,7 +1101,7 @@ proc gdb_test_multiple { command message args } { + error "Too few arguments to gdb_test_multiple" + } + +- set prompt_regexp [fill_in_default_prompt $prompt_regexp true] ++ set prompt_regexp [fill_in_default_prompt $prompt_regexp $prompt_anchor] + + if { $message == "" } { + set message $command +-- +2.43.0 + diff --git a/gdb-testsuite-fix-typo-in-gdb.base-catch-syscall.exp.patch b/gdb-testsuite-fix-typo-in-gdb.base-catch-syscall.exp.patch deleted file mode 100644 index 22bd445..0000000 --- a/gdb-testsuite-fix-typo-in-gdb.base-catch-syscall.exp.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 22655d76bc767d938dc9a72e0f50816a2f97f4c0 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Sun, 31 Dec 2023 09:39:45 +0100 -Subject: [PATCH 47/48] [gdb/testsuite] Fix typo in gdb.base/catch-syscall.exp - -On aarch64-linux with a gdb build without libexpat, I run into: -... -(gdb) PASS: gdb.base/catch-syscall.exp: determine pipe syscall: \ - catch syscall 59 -continue -Continuing. - -Catchpoint 5 (call to syscall 59), 0x0000fffff7e04578 in pipe () from \ - /lib64/libc.so.6 -(gdb) FAIL: gdb.base/catch-syscall.exp: determine pipe syscall: continue -... - -In the test-case, this pattern handles either the syscall name or number for -the pipe syscall: -... - -re -wrap "Catchpoint $decimal \\(call to syscall (pipe|$SYS_pipe)\\).*" { -... -but the pattern for the pipe2 syscall mistakenly uses SYS_pipe instead of -SYS_pipe2: -... - -re -wrap "Catchpoint $decimal \\(call to syscall (pipe2|$SYS_pipe)\\).*" { -... -and consequently doesn't handle the pipe2 syscall number. - -Fix the typo by using SYS_pipe2 instead. - -Tested on aarch64-linux. ---- - gdb/testsuite/gdb.base/catch-syscall.exp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gdb/testsuite/gdb.base/catch-syscall.exp b/gdb/testsuite/gdb.base/catch-syscall.exp -index 0588cb35d87..f7d499cb10b 100644 ---- a/gdb/testsuite/gdb.base/catch-syscall.exp -+++ b/gdb/testsuite/gdb.base/catch-syscall.exp -@@ -752,7 +752,7 @@ proc setup_all_syscalls {} { - pass $gdb_test_name - set ok 1 - } -- -re -wrap "Catchpoint $decimal \\(call to syscall (pipe2|$SYS_pipe)\\).*" { -+ -re -wrap "Catchpoint $decimal \\(call to syscall (pipe2|$SYS_pipe2)\\).*" { - lappend all_syscalls pipe2 - pass $gdb_test_name - set ok 1 --- -2.35.3 - diff --git a/gdb-testsuite-fix-valgrind-tests-on-debian.patch b/gdb-testsuite-fix-valgrind-tests-on-debian.patch deleted file mode 100644 index d1453cd..0000000 --- a/gdb-testsuite-fix-valgrind-tests-on-debian.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 489d8a4ff8c5998dad5a55694e346532695c911b Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Tue, 26 Mar 2024 17:32:09 +0100 -Subject: [PATCH 36/48] [gdb/testsuite] Fix valgrind tests on debian - -On debian 12, I run into: -... -(gdb) target remote | vgdb --wait=2 --max-invoke-ms=2500 --pid=618591^M -Remote debugging using | vgdb --wait=2 --max-invoke-ms=2500 --pid=618591^M -relaying data between gdb and process 618591^M -warning: remote target does not support file transfer, \ - attempting to access files from local filesystem.^M -Reading symbols from /lib/ld-linux-aarch64.so.1...^M -(No debugging symbols found in /lib/ld-linux-aarch64.so.1)^M -0x000000000401a980 in ?? () from /lib/ld-linux-aarch64.so.1^M -(gdb) FAIL: gdb.base/valgrind-infcall.exp: target remote for vgdb -... - -The problem is that we're expecting to match either of these regexps: -... - set start_re1 " in \\.?_start " - set start_re2 "\\.?_start \\(\\) at " -... -but there are no dwarf or elf symbols present. - -Fix this by also allowing: -... - set start_re3 "$::hex in \\?\\? \\(\\) from " -... - -Tested on aarch64-linux. - -Approved-By: Tom Tromey ---- - gdb/testsuite/lib/valgrind.exp | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/gdb/testsuite/lib/valgrind.exp b/gdb/testsuite/lib/valgrind.exp -index f9096663509..52ef603a803 100644 ---- a/gdb/testsuite/lib/valgrind.exp -+++ b/gdb/testsuite/lib/valgrind.exp -@@ -94,7 +94,8 @@ proc vgdb_start { {active_at_startup 1} } { - if { $active_at_startup } { - set start_re1 " in \\.?_start " - set start_re2 "\\.?_start \\(\\) at " -- gdb_test "$vgdbcmd" "($start_re1|$start_re2).*" \ -+ set start_re3 "$::hex in \\?\\? \\(\\) from " -+ gdb_test "$vgdbcmd" "($start_re1|$start_re2|$start_re3).*" \ - "target remote for vgdb" - } else { - # Let $binfile run a bit before attaching. This is a bit of a hack, --- -2.35.3 - diff --git a/gdb-testsuite-further-handle-long-filenames-in-gdb.b.patch b/gdb-testsuite-further-handle-long-filenames-in-gdb.b.patch deleted file mode 100644 index b21d5a9..0000000 --- a/gdb-testsuite-further-handle-long-filenames-in-gdb.b.patch +++ /dev/null @@ -1,49 +0,0 @@ -From dba128204017c9a12b3b6840bf1e3a6fec83f3e4 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Mon, 26 Feb 2024 15:59:47 +0100 -Subject: [PATCH 42/48] [gdb/testsuite] Further handle long filenames in - gdb.base/startup-with-shell.exp - -In commit 52498004a34 ("gdb/testsuite: handle long filenames in -gdb.base/startup-with-shell.exp") we fixed a FAIL reported by the Linaro CI: -... -(gdb) print argv[1] -$1 = 0xfffed978 "/startup-with-shell/unique-file.unique-e"... -(gdb) FAIL: gdb.base/startup-with-shell.exp: startup_with_shell = on; \ - run_args = *.unique-extension: first argument expanded -... - -PR testsuite/31410 reports a similar failure: -... -(gdb) print argv[1] -$1 = 0xfffeda96 "/startup-with-shell/*.unique-extens"... -(gdb) FAIL: gdb.base/startup-with-shell.exp: startup_with_shell = off; \ - run_args = *.unique-extension: first argument not expanded -... - -Fix this in the same way, using "set print characters unlimited". - -Tested on x86_64-linux. - -Approved-By: Tom Tromey - -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31410 ---- - gdb/testsuite/gdb.base/startup-with-shell.exp | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/gdb/testsuite/gdb.base/startup-with-shell.exp b/gdb/testsuite/gdb.base/startup-with-shell.exp -index 51b1e4fa922..24135972b72 100644 ---- a/gdb/testsuite/gdb.base/startup-with-shell.exp -+++ b/gdb/testsuite/gdb.base/startup-with-shell.exp -@@ -65,6 +65,7 @@ with_test_prefix "startup_with_shell = on; run_args = *.unique-extension" { - - with_test_prefix "startup_with_shell = off; run_args = *.unique-extension" { - initial_setup_simple "off" "$unique_file_dir/*.unique-extension" -+ gdb_test_no_output "set print characters unlimited" - gdb_test "print argv\[1\]" "\\\$$decimal = $hex \"$unique_file_dir/\\\*\.unique-extension\"" \ - "first argument not expanded" - } --- -2.35.3 - diff --git a/gdb-testsuite-handle-core-without-build-id-in-gdb.ba.patch b/gdb-testsuite-handle-core-without-build-id-in-gdb.ba.patch deleted file mode 100644 index 7969335..0000000 --- a/gdb-testsuite-handle-core-without-build-id-in-gdb.ba.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 163358e7c426183521d34c96e6959f615862ff1f Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Wed, 20 Mar 2024 19:29:18 +0100 -Subject: [PATCH 38/48] [gdb/testsuite] Handle core without build-id in - gdb.base/corefile-buildid.exp - -On aarch64-linux (debian 12), when running test-case gdb.base/corefile-buildid.exp, I get: -... -expecting exec file "debugdir-exec/.build-id/ec/f10ec5d39648774f8c35d3cf757c8db52f5163" -info files^M -Local core dump file:^M - `build-exec/corefile-buildid.core', file type elf64-littleaarch64.^M - 0x0000aaaac1d70000 - 0x0000aaaac1d71000 is load1^M - ... - 0x0000ffffffa8b000 - 0x0000ffffffaac000 is load16^M -(gdb) FAIL: gdb.base/corefile-buildid.exp: exec: info files -... - -The problem is that the test-case expect the build-id to be available in the -core file, while it isn't. - -Fix this by detecting that the build-id isn't available in the core file using eu-readelf, as in -gdb.base/coredump-filter-build-id.exp. - -Tested on aarch64-linux. - -Approved-By: Tom Tromey ---- - gdb/testsuite/gdb.base/corefile-buildid.exp | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - -diff --git a/gdb/testsuite/gdb.base/corefile-buildid.exp b/gdb/testsuite/gdb.base/corefile-buildid.exp -index 3c2702e0cd3..630e812bd6b 100644 ---- a/gdb/testsuite/gdb.base/corefile-buildid.exp -+++ b/gdb/testsuite/gdb.base/corefile-buildid.exp -@@ -217,7 +217,7 @@ proc locate_exec_from_core_build_id {corefile buildid suffix \ - # of shared and/or stripped/.debug executables. - - proc do_corefile_buildid_tests {args} { -- global binfile testfile srcfile execdir sharedir -+ global binfile testfile srcfile execdir sharedir hex - - # Parse options. - parse_args [list {sepdebug} {shared}] -@@ -266,6 +266,18 @@ proc do_corefile_buildid_tests {args} { - } - verbose -log "corefile is $corefile" - -+ if { [catch "exec [gdb_find_eu-unstrip] -n --core $corefile" output] == 0 } { -+ set line [lindex [split $output "\n"] 0] -+ set binfile_re (?:[string_to_regexp $program_to_run]|\\\[(?:exe|pie)\\\]) -+ if { ![regexp "^${hex}\\+${hex} \[a-f0-9\]+@${hex}.*$binfile_re$" $line] } { -+ unsupported "build id for exec" -+ return -+ } -+ } else { -+ unsupported "eu-unstrip execution" -+ return -+ } -+ - # Grab the build-id from the binary, removing ".debug" from the end. - set buildid [build_id_debug_filename_get $program_to_run] - if {$buildid == ""} { --- -2.35.3 - diff --git a/gdb-testsuite-handle-pac-marker.patch b/gdb-testsuite-handle-pac-marker.patch deleted file mode 100644 index b357c75..0000000 --- a/gdb-testsuite-handle-pac-marker.patch +++ /dev/null @@ -1,213 +0,0 @@ -From f70536d3f72601b286967ed3031a3fb1ce0c834f Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Thu, 4 Jan 2024 13:42:45 +0100 -Subject: [PATCH 02/48] [gdb/testsuite] Handle PAC marker - -On aarch64-linux, I run into: -... -FAIL: gdb.base/annota1.exp: backtrace from shlibrary (timeout) -... -due to the PAC marker showing up: -... -^Z^Zframe-address^M -0x000000000041025c [PAC]^M -^Z^Zframe-address-end^M -... - -In the docs the marker is documented as follows: -... -When GDB is debugging the AArch64 architecture, and the program is using the -v8.3-A feature Pointer Authentication (PAC), then whenever the link register -$lr is pointing to an PAC function its value will be masked. When GDB prints -a backtrace, any addresses that required unmasking will be postfixed with the -marker [PAC]. When using the MI, this is printed as part of the addr_flags -field. -... - -Update the test-case to allow the PAC marker. - -Likewise in a few other test-cases. - -While we're at it, rewrite the affected pattern pat_begin in annota1.exp into -a more readable form. Likewise for the corresponding pat_end. - -Tested on aarch64-linux. - -Approved-By: Luis Machado - -PR testsuite/31202 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31202 ---- - gdb/testsuite/gdb.base/annota1.exp | 47 ++++++++++++++++++- - gdb/testsuite/gdb.cp/exception.exp | 8 ++-- - .../gdb.dwarf2/entry-value-typedef.exp | 2 +- - .../gdb.mi/mi-catch-cpp-exceptions.exp | 2 +- - gdb/testsuite/gdb.mi/mi-syn-frame.exp | 2 +- - .../gdb.threads/pthread_cond_wait.exp | 2 +- - gdb/testsuite/gdb.threads/tls.exp | 2 +- - 7 files changed, 54 insertions(+), 11 deletions(-) - -diff --git a/gdb/testsuite/gdb.base/annota1.exp b/gdb/testsuite/gdb.base/annota1.exp -index 3c2bbb43761..d8552b5be85 100644 ---- a/gdb/testsuite/gdb.base/annota1.exp -+++ b/gdb/testsuite/gdb.base/annota1.exp -@@ -286,9 +286,52 @@ gdb_test_multiple "continue" "continue to printf" { - # annotate-frame-address - # annotate-frame-address-end - # --set pat_begin "\r\n\032\032post-prompt\r\n\r\n\032\032frame-begin 0 $hex\r\n.0 \r\n(\032\032frame-address\r\n$hex\r\n\032\032frame-address-end\r\n in \r\n)*\032\032frame-function-name\r\n.*printf(@.*)?\r\n\032\032frame-args\r\n \\(.*frame-end\r\n\r\n\032\032frame-begin 1 $hex\r\n.1 \r\n\032\032frame-address\r\n$hex\r\n\032\032frame-address-end\r\n in \r\n\032\032frame-function-name\r\nmain\r\n\032\032frame-args\r\n \\(\\)\r\n\032\032frame-source-begin\r\n at \r\n\032\032frame-source-file\r\n" -+set pat_begin \ -+ [list \ -+ "\r\n\032\032post-prompt\r\n" \ -+ "\r\n\032\032frame-begin 0 $hex\r\n" \ -+ ".0 \r\n" \ -+ "(" \ -+ "\032\032frame-address\r\n" \ -+ "${hex}( \\\[PAC\\\])?" \ -+ "\r\n\032\032frame-address-end\r\n" \ -+ " in \r\n" \ -+ ")*" \ -+ "\032\032frame-function-name\r\n" \ -+ ".*printf(@.*)?" \ -+ "\r\n\032\032frame-args\r\n" \ -+ " \\(.*frame-end\r\n" \ -+ "\r\n\032\032frame-begin 1 $hex\r\n" \ -+ ".1 " \ -+ "\r\n\032\032frame-address\r\n" \ -+ "${hex}( \\\[PAC\\\])?" \ -+ "\r\n\032\032frame-address-end\r\n" \ -+ " in " \ -+ "\r\n\032\032frame-function-name\r\n" \ -+ "main" \ -+ "\r\n\032\032frame-args\r\n" \ -+ " \\(\\)" \ -+ "\r\n\032\032frame-source-begin\r\n" \ -+ " at " \ -+ "\r\n\032\032frame-source-file\r\n"] -+ -+set pat_begin [join $pat_begin ""] -+ -+set pat_end \ -+ [list \ -+ "\r\n\032\032frame-source-file-end\r\n" \ -+ ":" \ -+ "\r\n\032\032frame-source-line\r\n" \ -+ ".*" \ -+ "\r\n\032\032frame-source-end\r\n\r\n" \ -+ "\r\n\032\032frame-end\r\n" \ -+ "(" \ -+ "\r\n\032\032frame-begin .*\r\n" \ -+ "\r\n\032\032frame-end\r\n" \ -+ ")*" \ -+ "$gdb_prompt$"] - --set pat_end "\r\n\032\032frame-source-file-end\r\n:\r\n\032\032frame-source-line\r\n.*\r\n\032\032frame-source-end\r\n\r\n\r\n\032\032frame-end\r\n(\r\n\032\032frame-begin .*\r\n\r\n\032\032frame-end\r\n)*$gdb_prompt$" -+set pat_end [join $pat_end ""] - - gdb_test_multiple "backtrace" "backtrace from shlibrary" { - -re "$pat_begin$escapedsrcfile$pat_end" { -diff --git a/gdb/testsuite/gdb.cp/exception.exp b/gdb/testsuite/gdb.cp/exception.exp -index 2c7ef7793ee..03dd0cb3aeb 100644 ---- a/gdb/testsuite/gdb.cp/exception.exp -+++ b/gdb/testsuite/gdb.cp/exception.exp -@@ -111,7 +111,7 @@ gdb_test "continue" \ - - set name "backtrace after first throw" - gdb_test_multiple "backtrace" $name { -- -re ".*#\[0-9\]+.*\[\[:<:\]\]__cxa_throw\[\[:>:\]\].*#\[0-9\]+${ws}$hex in foo \\(i=20\\) at .*${srcfile}:\[0-9\]+\r\n#\[0-9\]+${ws}$hex in main \\(.*\\) at .*${srcfile}:\[0-9\]+\r\n$gdb_prompt $" { -+ -re ".*#\[0-9\]+.*\[\[:<:\]\]__cxa_throw\[\[:>:\]\].*#\[0-9\]+${ws}$hex (\\\[PAC\\\] )?in foo \\(i=20\\) at .*${srcfile}:\[0-9\]+\r\n#\[0-9\]+${ws}$hex in main \\(.*\\) at .*${srcfile}:\[0-9\]+\r\n$gdb_prompt $" { - # Either __cxxabiv1::__cxa_throw or __cxa_throw can be printed - # depending on debug info presence. - pass $name -@@ -129,7 +129,7 @@ gdb_test "continue" \ - - set name "backtrace after first catch" - gdb_test_multiple "backtrace" $name { -- -re ".*#\[0-9\]+.*\[\[:<:\]\]__cxa_begin_catch\[\[:>:\]\].*#\[0-9\]+${ws}$hex in main \\(.*\\) at .*$srcfile:\[0-9\]+\r\n$gdb_prompt $" { -+ -re ".*#\[0-9\]+.*\[\[:<:\]\]__cxa_begin_catch\[\[:>:\]\].*#\[0-9\]+${ws}$hex (\\\[PAC\\\] )?in main \\(.*\\) at .*$srcfile:\[0-9\]+\r\n$gdb_prompt $" { - pass $name - } - } -@@ -148,7 +148,7 @@ gdb_test "continue" \ - - set name "backtrace after second throw" - gdb_test_multiple "backtrace" $name { -- -re ".*#\[0-9\]+.*\[\[:<:\]\]__cxa_throw\[\[:>:\]\].*#\[0-9\]+${ws}$hex in foo \\(i=20\\) at .*${srcfile}:\[0-9\]+\r\n#\[0-9\]+${ws}$hex in main \\(.*\\) at .*${srcfile}:\[0-9\]+\r\n$gdb_prompt $" { -+ -re ".*#\[0-9\]+.*\[\[:<:\]\]__cxa_throw\[\[:>:\]\].*#\[0-9\]+${ws}$hex (\\\[PAC\\\] )?in foo \\(i=20\\) at .*${srcfile}:\[0-9\]+\r\n#\[0-9\]+${ws}$hex in main \\(.*\\) at .*${srcfile}:\[0-9\]+\r\n$gdb_prompt $" { - pass $name - } - } -@@ -164,7 +164,7 @@ gdb_test "continue" \ - - set name "backtrace after second catch" - gdb_test_multiple "backtrace" $name { -- -re ".*#\[0-9\]+.*\[\[:<:\]\]__cxa_begin_catch\[\[:>:\]\].*#\[0-9\]+${ws}$hex in main \\(.*\\) at .*$srcfile:\[0-9\]+\r\n$gdb_prompt $" { -+ -re ".*#\[0-9\]+.*\[\[:<:\]\]__cxa_begin_catch\[\[:>:\]\].*#\[0-9\]+${ws}$hex (\\\[PAC\\\] )?in main \\(.*\\) at .*$srcfile:\[0-9\]+\r\n$gdb_prompt $" { - pass $name - } - } -diff --git a/gdb/testsuite/gdb.dwarf2/entry-value-typedef.exp b/gdb/testsuite/gdb.dwarf2/entry-value-typedef.exp -index b56c9ceab6a..3d25e2a50b9 100644 ---- a/gdb/testsuite/gdb.dwarf2/entry-value-typedef.exp -+++ b/gdb/testsuite/gdb.dwarf2/entry-value-typedef.exp -@@ -42,4 +42,4 @@ gdb_test "continue" "Catchpoint $::decimal \\(exception thrown\\).*" - - # Without the corresponding fix, GDB would hit an internal error before - # printing the frame for main. --gdb_test "backtrace" " $::hex in func \\(t=t@entry=@$::hex: 1234\\).* $::hex in main .*" -+gdb_test "backtrace" " $::hex (\\\[PAC\\\] )?in func \\(t=t@entry=@$::hex: 1234\\).* $::hex in main .*" -diff --git a/gdb/testsuite/gdb.mi/mi-catch-cpp-exceptions.exp b/gdb/testsuite/gdb.mi/mi-catch-cpp-exceptions.exp -index 595ae929e9a..1f119ec3a87 100644 ---- a/gdb/testsuite/gdb.mi/mi-catch-cpp-exceptions.exp -+++ b/gdb/testsuite/gdb.mi/mi-catch-cpp-exceptions.exp -@@ -68,7 +68,7 @@ proc continue_to_next_exception { func line testname } { - mi_expect_stop "exception-caught" ".*" ".*" ".*" ".*" \ - {} "run until an exception is caught: $testname" - mi_gdb_test "-stack-list-frames 1 1" \ -- "\\^done,stack=\\\[frame=\{level=\"1\",addr=\"$hex\",func=\"${func}\",.*,line=\"${line}\".*\}\\\]" \ -+ "\\^done,stack=\\\[frame=\{level=\"1\",addr=\"$hex\",(addr_flags=\"PAC\",)?func=\"${func}\",.*,line=\"${line}\".*\}\\\]" \ - "check previous frame: $testname" - } - -diff --git a/gdb/testsuite/gdb.mi/mi-syn-frame.exp b/gdb/testsuite/gdb.mi/mi-syn-frame.exp -index 40df312a1cc..dd484cd80fa 100644 ---- a/gdb/testsuite/gdb.mi/mi-syn-frame.exp -+++ b/gdb/testsuite/gdb.mi/mi-syn-frame.exp -@@ -76,7 +76,7 @@ mi_gdb_test "406-data-evaluate-expression have_a_very_merry_interrupt()" \ - # in this next output. - - mi_gdb_test "407-stack-list-frames" \ -- "407\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",func=\"subroutine\",file=\".*mi-syn-frame.c\",fullname=\"${fullname_syntax}${srcfile}\",line=\"$decimal\",arch=\"$any\"\},frame=\{level=\"1\",addr=\"$hex\",func=\"handler\",file=\".*mi-syn-frame.c\",fullname=\"${fullname_syntax}${srcfile}\",line=\"$decimal\",arch=\"$any\"\},frame=\{level=\"2\",addr=\"$hex\",func=\"\"\},.*frame=\{level=\"$decimal\",addr=\"$hex\",func=\"have_a_very_merry_interrupt\",file=\".*mi-syn-frame.c\",fullname=\"${fullname_syntax}${srcfile}\",line=\"$decimal\",arch=\"$any\"\},frame=\{level=\"$decimal\",addr=\"$hex\",func=\"\"\},frame=\{level=\"$decimal\",addr=\"$hex\",func=\"main\",file=\".*mi-syn-frame.c\",fullname=\"${fullname_syntax}${srcfile}\",line=\"$decimal\",arch=\"$any\"\}.*\\\]" \ -+ "407\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",func=\"subroutine\",file=\".*mi-syn-frame.c\",fullname=\"${fullname_syntax}${srcfile}\",line=\"$decimal\",arch=\"$any\"\},frame=\{level=\"1\",addr=\"$hex\",func=\"handler\",file=\".*mi-syn-frame.c\",fullname=\"${fullname_syntax}${srcfile}\",line=\"$decimal\",arch=\"$any\"\},frame=\{level=\"2\",addr=\"$hex\",func=\"\"\},.*frame=\{level=\"$decimal\",addr=\"$hex\",(addr_flags=\"PAC\",)?func=\"have_a_very_merry_interrupt\",file=\".*mi-syn-frame.c\",fullname=\"${fullname_syntax}${srcfile}\",line=\"$decimal\",arch=\"$any\"\},frame=\{level=\"$decimal\",addr=\"$hex\",func=\"\"\},frame=\{level=\"$decimal\",addr=\"$hex\",func=\"main\",file=\".*mi-syn-frame.c\",fullname=\"${fullname_syntax}${srcfile}\",line=\"$decimal\",arch=\"$any\"\}.*\\\]" \ - "list stack frames, with signal handler and dummy frame" - - -diff --git a/gdb/testsuite/gdb.threads/pthread_cond_wait.exp b/gdb/testsuite/gdb.threads/pthread_cond_wait.exp -index ff3097cb519..b29be9e4191 100644 ---- a/gdb/testsuite/gdb.threads/pthread_cond_wait.exp -+++ b/gdb/testsuite/gdb.threads/pthread_cond_wait.exp -@@ -51,7 +51,7 @@ global decimal - # - # This is a "backtrace break" ("btb"): - # --set btb "\[^\r\n\]+\[\r\n\]+\#${decimal}\[ \t\]+${hex} in " -+set btb "\[^\r\n\]+\[\r\n\]+\#${decimal}\[ \t\]+${hex} (\\\[PAC\\\] )?in " - - # One of the threads is blocked on a call to pthread_cond_wait, and - # we want to verify that we are able to get a sensible backtrace for -diff --git a/gdb/testsuite/gdb.threads/tls.exp b/gdb/testsuite/gdb.threads/tls.exp -index 89f6fb89bac..91a7f80b438 100644 ---- a/gdb/testsuite/gdb.threads/tls.exp -+++ b/gdb/testsuite/gdb.threads/tls.exp -@@ -132,7 +132,7 @@ proc check_thread_stack {number spin_threads spin_threads_level} { - } - send_gdb "where\n" - gdb_expect { -- -re ".*(\[0-9\]+)\[ \t\]+$hex in spin \\(vp=(0x\[0-9a-f\]+).*\r\n$gdb_prompt $" { -+ -re ".*(\[0-9\]+)\[ \t\]+$hex (\\\[PAC\\\] )?in spin \\(vp=(0x\[0-9a-f\]+).*\r\n$gdb_prompt $" { - if {[info exists tarr($number)]} { - fail "backtrace of thread number $number in spin" - } else { --- -2.35.3 - diff --git a/gdb-testsuite-handle-unordered-dict-in-gdb.python-py.patch b/gdb-testsuite-handle-unordered-dict-in-gdb.python-py.patch new file mode 100644 index 0000000..8df3593 --- /dev/null +++ b/gdb-testsuite-handle-unordered-dict-in-gdb.python-py.patch @@ -0,0 +1,65 @@ +From 83fafbe970614f89e7e106542bdb9181b0568f0f Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Thu, 30 Jan 2025 13:21:56 +0100 +Subject: [PATCH] [gdb/testsuite] Handle unordered dict in + gdb.python/py-mi-notify.exp + +With test-case gdb.python/py-mi-notify.exp and python 3.4, I occasionally run +into: +... +python gdb.notify_mi('-test-notification', { 'data1' : 1 , 'data2' : 2 }) +&"python gdb.notify_mi('-test-notification', { 'data1' : 1 , 'data2' : 2 })\n" +=-test-notification,data2="2",data1="1" +^done +(gdb) +FAIL: $exp: python notification, with additional data (unexpected output) +... + +In contrast, a passing version looks like: +... +python gdb.notify_mi('-test-notification', { 'data1' : 1 , 'data2' : 2 }) +&"python gdb.notify_mi('-test-notification', { 'data1' : 1 , 'data2' : 2 })\n" +=-test-notification,data1="1",data2="2" +^done +(gdb) +PASS: gdb.python/py-mi-notify.exp: python notification, with additional data +... + +The python method "gdb.notify_mi(name, data)" has parameter data which is a +dictionary, and it iterates over that dictionary. + +The problem is that dictionaries are only guaranteed to be iterating in +insertion order starting python 3.7 (though cpython does this starting python +3.6). + +Fix this in the same way as in commit 362a867f2ac ("[gdb/testsuite] Handle +unordered dict in gdb.python/py-mi-cmd.exp"): by allowing the alternative +order. + +Tested on x86_64-linux. +--- + gdb/testsuite/gdb.python/py-mi-notify.exp | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/gdb/testsuite/gdb.python/py-mi-notify.exp b/gdb/testsuite/gdb.python/py-mi-notify.exp +index f808fb2502e..7776976613e 100644 +--- a/gdb/testsuite/gdb.python/py-mi-notify.exp ++++ b/gdb/testsuite/gdb.python/py-mi-notify.exp +@@ -42,8 +42,11 @@ mi_gdb_test "python gdb.notify_mi('-test-notification', None)" \ + ".*=-test-notification\r\n\\^done" \ + "python notification, no additional data" + ++set re_data1 {data1="1"} ++set re_data2 {data2="2"} ++set re_data1_data2 ($re_data1,$re_data2|$re_data2,$re_data1) + mi_gdb_test "python gdb.notify_mi('-test-notification', \{ 'data1' : 1 , 'data2' : 2 })" \ +- ".*=-test-notification,data1=\"1\",data2=\"2\"\r\n\\^done" \ ++ ".*=-test-notification,$re_data1_data2\r\n\\^done" \ + "python notification, with additional data" + + mi_gdb_test "python gdb.notify_mi('-test-notification', 1)" \ + +base-commit: 625cadfb85ae46901ee8cbed08638ed3be8d96f5 +-- +2.43.0 + diff --git a/gdb-testsuite-make-gdb.base-solib-search.exp-more-ro.patch b/gdb-testsuite-make-gdb.base-solib-search.exp-more-ro.patch deleted file mode 100644 index 0ce3dc5..0000000 --- a/gdb-testsuite-make-gdb.base-solib-search.exp-more-ro.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 17ab80b7af4c388c44d0981d76de396d85bcba76 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Mon, 8 Jan 2024 10:37:44 +0100 -Subject: [PATCH 05/48] [gdb/testsuite] Make gdb.base/solib-search.exp more - robust - -On aarch64-linux, with gcc 13.2.1, I run into: -... - (gdb) backtrace^M - #0 break_here () at solib-search.c:30^M - #1 0x0000fffff7f20194 in lib2_func4 () at solib-search-lib2.c:50^M - #2 0x0000fffff7f70194 in lib1_func3 () at solib-search-lib1.c:50^M - #3 0x0000fffff7f20174 in lib2_func2 () at solib-search-lib2.c:30^M - #4 0x0000fffff7f70174 in lib1_func1 () at solib-search-lib1.c:30^M - #5 0x00000000004101b4 in main () at solib-search.c:23^M - (gdb) PASS: gdb.base/solib-search.exp: \ - backtrace (with wrong libs) (data collection) - FAIL: gdb.base/solib-search.exp: backtrace (with wrong libs) -... - -The FAIL is generated by this code in the test-case: -... - if { $expect_fail } { - # If the backtrace output is correct the test isn't sufficiently - # testing what it should. - if { $count == $total_expected } { - set fail 1 - } -... - -The test-case: -- builds two versions of two shared libs, a "right" and "wrong" version, the - difference being an additional dummy function (called spacer function), -- uses the "right" version to generate a core file, -- uses the "wrong" version to interpret the core file, and -- generates a backtrace. - -The intent is that the backtrace is incorrect due to using the "wrong" -version, but actually it's correct. This is because the spacer functions -aren't large enough. - -Fix this by increasing the size of the spacer functions by adding a dummy -loop, after which we have, as expected, an incorrect backtrace: -... - (gdb) backtrace^M - #0 break_here () at solib-search.c:30^M - #1 0x0000fffff7f201c0 in ?? ()^M - #2 0x0000fffff7f20174 in lib2_func2 () at solib-search-lib2.c:30^M - #3 0x0000fffff7f20174 in lib2_func2 () at solib-search-lib2.c:30^M - #4 0x0000fffff7f70174 in lib1_func1 () at solib-search-lib1.c:30^M - #5 0x00000000004101b4 in main () at solib-search.c:23^M - (gdb) PASS: gdb.base/solib-search.exp: \ - backtrace (with wrong libs) (data collection) - PASS: gdb.base/solib-search.exp: backtrace (with wrong libs) -... - -Tested on aarch64-linux. ---- - gdb/testsuite/gdb.base/solib-search-lib1.c | 3 +++ - gdb/testsuite/gdb.base/solib-search-lib2.c | 3 +++ - 2 files changed, 6 insertions(+) - -diff --git a/gdb/testsuite/gdb.base/solib-search-lib1.c b/gdb/testsuite/gdb.base/solib-search-lib1.c -index 76338a8e216..6a4cc9aa1a7 100644 ---- a/gdb/testsuite/gdb.base/solib-search-lib1.c -+++ b/gdb/testsuite/gdb.base/solib-search-lib1.c -@@ -39,6 +39,9 @@ lib1_func1 (void) - void - lib1_spacer (void) - { -+ int i; -+ for (i = 0; i < 10; ++i) -+ ; - } - - #endif -diff --git a/gdb/testsuite/gdb.base/solib-search-lib2.c b/gdb/testsuite/gdb.base/solib-search-lib2.c -index bf7c7bd071c..fb004d7377f 100644 ---- a/gdb/testsuite/gdb.base/solib-search-lib2.c -+++ b/gdb/testsuite/gdb.base/solib-search-lib2.c -@@ -39,6 +39,9 @@ lib2_func2 (void) - void - lib2_spacer (void) - { -+ int i; -+ for (i = 0; i < 10; ++i) -+ ; - } - - #endif --- -2.35.3 - diff --git a/gdb-testsuite-make-portnum-a-persistent-global.patch b/gdb-testsuite-make-portnum-a-persistent-global.patch deleted file mode 100644 index 1d264ba..0000000 --- a/gdb-testsuite-make-portnum-a-persistent-global.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 81f752e905f9ef4d0f2e046acf3fabcddf952057 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Sat, 4 May 2024 10:41:09 +0200 -Subject: [PATCH 17/48] [gdb/testsuite] Make portnum a persistent global - -When instrumenting get_portnum using: -... - puts "PORTNUM: $res" -... -and running: -... -$ cd build/gdb -$ make check TESTS=gdb.server/*.exp -... -we get: -... -Running gdb.server/target-exec-file.exp ... -PORTNUM: 2345 -Running gdb.server/stop-reply-no-thread-multi.exp ... -PORTNUM: 2345 -PORTNUM: 2346 -PORTNUM: 2347 -PORTNUM: 2348 -PORTNUM: 2349 -PORTNUM: 2350 -... - -So, while get_portnum does return increasing numbers in a single test-case, it -restarts at each test-case. - -This is a regression since the introduction of persistent globals. - -Fix this by using "gdb_persistent_global portnum", such that we get: -... -Running gdb.server/target-exec-file.exp ... -PORTNUM: 2345 -Running gdb.server/stop-reply-no-thread-multi.exp ... -PORTNUM: 2346 -PORTNUM: 2347 -PORTNUM: 2348 -PORTNUM: 2349 -PORTNUM: 2350 -PORTNUM: 2351 -... - -Tested on aarch64-linux. - -Approved-By: Tom Tromey ---- - gdb/testsuite/lib/gdbserver-support.exp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gdb/testsuite/lib/gdbserver-support.exp b/gdb/testsuite/lib/gdbserver-support.exp -index 8aaca946b7d..4f7effaacf7 100644 ---- a/gdb/testsuite/lib/gdbserver-support.exp -+++ b/gdb/testsuite/lib/gdbserver-support.exp -@@ -142,7 +142,7 @@ proc get_portnum {} { - set initial_portnum 2345 - - # Currently available port number. -- global portnum -+ gdb_persistent_global portnum - - # Initialize, if necessary. - if { ![info exists portnum] } { --- -2.35.3 - diff --git a/gdb-testsuite-move-gpu-parallel.lock-to-cache-dir.patch b/gdb-testsuite-move-gpu-parallel.lock-to-cache-dir.patch deleted file mode 100644 index 604a3c8..0000000 --- a/gdb-testsuite-move-gpu-parallel.lock-to-cache-dir.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 40ffee49122d3856292d2374c25f619805f76f1f Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Sat, 4 May 2024 10:41:09 +0200 -Subject: [PATCH 20/48] [gdb/testsuite] Move gpu-parallel.lock to cache dir - -The lock directory returned by lock_dir is currently $objdir. - -It seems possible to leave a stale lock file that blocks progress in a -following run. - -Fix this by using a directory that is guaranteed to be initially empty when -using GDB_PARALLEL, like temp or cache. - -In gdb/testsuite/README I found: -... -cache in particular is used to share data across invocations of runtest -... -which seems appropriate, so let's use cache for this. - -Tested on aarch64-linux. - -Approved-By: Tom Tromey ---- - gdb/testsuite/lib/gdb-utils.exp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gdb/testsuite/lib/gdb-utils.exp b/gdb/testsuite/lib/gdb-utils.exp -index 63f6b8c3698..cfaa7905997 100644 ---- a/gdb/testsuite/lib/gdb-utils.exp -+++ b/gdb/testsuite/lib/gdb-utils.exp -@@ -180,7 +180,7 @@ proc lock_file_release {info} { - # Return directory where we keep lock files. - - proc lock_dir {} { -- return $objdir -+ return [make_gdb_parallel_path cache] - } - - # Run body under lock LOCK_FILE. --- -2.35.3 - diff --git a/gdb-testsuite-record-less-in-gdb.reverse-time-revers.patch b/gdb-testsuite-record-less-in-gdb.reverse-time-revers.patch new file mode 100644 index 0000000..1061ee6 --- /dev/null +++ b/gdb-testsuite-record-less-in-gdb.reverse-time-revers.patch @@ -0,0 +1,92 @@ +From fc88d3c31d277ad466ae961b585fbb2fac982d3e Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Fri, 24 Jan 2025 16:37:36 +0100 +Subject: [PATCH 1/2] [gdb/testsuite] Record less in + gdb.reverse/time-reverse.exp + +While stepping through gdb.reverse/time-reverse.exp I realized that we're +recording the instructions for resolving the PLT entries for functions time +and syscall, while that's not really the focus of the test-case. + +Limit the scope of the test, by calling the functions once before starting +to record. + +Also call "info record" after recording to make it clear how many +instructions were recorded. + +On x86_64-linux, before this patch (but with info record added), we have: +... +$ grep "Log contains" gdb.log +Log contains 750 instructions. +Log contains 1218 instructions. +... +and with this patch we have: +... +$ grep "Log contains" gdb.log +Log contains 24 instructions. +Log contains 19 instructions. +... + +Tested on x86_64-linux. + +Approved-By: Guinevere Larsen +--- + gdb/testsuite/gdb.reverse/time-reverse.c | 12 ++++++++++++ + gdb/testsuite/gdb.reverse/time-reverse.exp | 7 +++---- + 2 files changed, 15 insertions(+), 4 deletions(-) + +diff --git a/gdb/testsuite/gdb.reverse/time-reverse.c b/gdb/testsuite/gdb.reverse/time-reverse.c +index c22ecd849d8..0ed52244a30 100644 +--- a/gdb/testsuite/gdb.reverse/time-reverse.c ++++ b/gdb/testsuite/gdb.reverse/time-reverse.c +@@ -41,8 +41,20 @@ time_t time_global = -1; + int + main (void) + { ++ /* Call once before recording to resolve the PLT, if any. This reduces the ++ amount of instructions that is recorded. */ ++ my_time (&time_global); ++ ++ /* Reset back to initial value. */ ++ time_global = -1; ++ ++ /* Start recording here. */ + marker1 (); ++ + my_time (&time_global); ++ ++ /* Stop recording here. */ + marker2 (); ++ + return 0; + } +diff --git a/gdb/testsuite/gdb.reverse/time-reverse.exp b/gdb/testsuite/gdb.reverse/time-reverse.exp +index 91f9911c33a..b02245c6c77 100644 +--- a/gdb/testsuite/gdb.reverse/time-reverse.exp ++++ b/gdb/testsuite/gdb.reverse/time-reverse.exp +@@ -38,7 +38,7 @@ proc test {mode} { + return + } + +- runto_main ++ runto marker1 + + if [supports_process_record] { + # Activate process record/replay +@@ -51,9 +51,8 @@ proc test {mode} { + + gdb_continue_to_breakpoint "marker2" ".*$::srcfile:.*" + +- gdb_test "break marker1" \ +- "Breakpoint $::decimal at $::hex: file .*$::srcfile, line $::decimal.*" \ +- "set breakpoint at marker1" ++ # Show how many instructions we've recorded. ++ gdb_test "info record" "Active record target: .*" + + gdb_test "reverse-continue" ".*$::srcfile:$::decimal.*" "reverse to marker1" + + +base-commit: 8764f9e601b4ef996d9b1d8eab16f8cfec3561c4 +-- +2.43.0 + diff --git a/gdb-testsuite-remove-spurious-in-save_vars.patch b/gdb-testsuite-remove-spurious-in-save_vars.patch deleted file mode 100644 index 63cdf99..0000000 --- a/gdb-testsuite-remove-spurious-in-save_vars.patch +++ /dev/null @@ -1,53 +0,0 @@ -From d3fbb4d91ba2784df267fe1ac2e9ec42581a6fac Mon Sep 17 00:00:00 2001 -From: Simon Marchi -Date: Mon, 15 Jan 2024 16:23:42 +0000 -Subject: [PATCH] gdb/testsuite: remove spurious $ in save_vars - -I noticed that running the whole testsuite in serial mode (which means -all the .exp files are ran in the same TCL environment, one after the -other) with the native-extended-gdbserver board caused some weird -failures, for instance a lot of internal errors in the reverse tests, -like: - - continue^M - Continuing.^M - /home/jenkins/workspace/binutils-gdb_master_linuxbuild/platform/deb12-amd64/target_board/native-extended-gdbserver/src/binutils-gdb/gdb/remot e.c:6922: internal-error: resume: Assertion `scope_ptid == inferior_ptid' failed.^M - A problem internal to GDB has been detected,^M - further debugging may prove unreliable.^M - ----- Backtrace -----^M - FAIL: gdb.reverse/break-precsave.exp: run to end of main (GDB internal error) - -This only happens after running gdb.multi/attach-while-running.exp. -That test does not restore GDBFLAGS properly when it's done, it leaves -`-ex \"maint set target-non-stop on\""` in there, which breaks some -subsequent tests. The problem is that this line: - - save_vars { $::GDBFLAGS } { - -should not use a `$` before the variable name. Passes the content of -`::GDBFLAGS` to save_vars, which is not what we want. We want to pass -the `::GDBFLAGS` string. Fix that. - -Change-Id: I5ad32c527795fd10d0d94020e4fd15cebaca3a77 ---- - gdb/testsuite/gdb.multi/attach-while-running.exp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gdb/testsuite/gdb.multi/attach-while-running.exp b/gdb/testsuite/gdb.multi/attach-while-running.exp -index d3e0d462413..8fce34eaa65 100644 ---- a/gdb/testsuite/gdb.multi/attach-while-running.exp -+++ b/gdb/testsuite/gdb.multi/attach-while-running.exp -@@ -46,7 +46,7 @@ if { [build_executable "failed to prepare" ${testfile} ${srcfile}] } { - } - - proc do_test {} { -- save_vars { $::GDBFLAGS } { -+ save_vars { ::GDBFLAGS } { - append ::GDBFLAGS " -ex \"maint set target-non-stop on\"" - clean_restart $::binfile - } - -base-commit: 08ce0d63c343f7db9a504d37de25391a997b46e2 --- -2.35.3 - diff --git a/gdb-testsuite-require-can_spawn_for_attach-in-gdb.ba.patch b/gdb-testsuite-require-can_spawn_for_attach-in-gdb.ba.patch new file mode 100644 index 0000000..98c3d82 --- /dev/null +++ b/gdb-testsuite-require-can_spawn_for_attach-in-gdb.ba.patch @@ -0,0 +1,40 @@ +From 86ab8a78a6947891eaf93fc6910febf3eb7fa8f0 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Wed, 8 Jan 2025 16:07:08 +0100 +Subject: [PATCH 42/46] [gdb/testsuite] Require can_spawn_for_attach in + gdb.base/gstack.exp + +I ran test-case gdb.base/gstack.exp on a machine with kernel.yama.ptrace_scope +set to 1 and ran into: +... +PASS: gdb.base/gstack.exp: spawn gstack +ptrace: Operation not permitted.^M +GSTACK-END^M +PASS: gdb.base/gstack.exp: gstack exits with no error +PASS: gdb.base/gstack.exp: gstack's exit status is 0 +FAIL: gdb.base/gstack.exp: got backtrace +... + +Fix this by requiring can_spawn_for_attach. + +Tested on x86_64-linux. +--- + gdb/testsuite/gdb.base/gstack.exp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/gdb/testsuite/gdb.base/gstack.exp b/gdb/testsuite/gdb.base/gstack.exp +index a5dacd582ff..d8a6d78e550 100644 +--- a/gdb/testsuite/gdb.base/gstack.exp ++++ b/gdb/testsuite/gdb.base/gstack.exp +@@ -13,6 +13,8 @@ + # You should have received a copy of the GNU General Public License + # along with this program. If not, see . + ++require can_spawn_for_attach ++ + set testfile gstack + set executable ${testfile} + set binfile [standard_output_file $executable] +-- +2.43.0 + diff --git a/gdb-testsuite-require-supports_process_record-in-gdb.patch b/gdb-testsuite-require-supports_process_record-in-gdb.patch new file mode 100644 index 0000000..666f569 --- /dev/null +++ b/gdb-testsuite-require-supports_process_record-in-gdb.patch @@ -0,0 +1,36 @@ +From e910a619716a2554f583679ff062a363699b2b93 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Wed, 8 Jan 2025 12:48:08 +0100 +Subject: [PATCH 31/46] [gdb/testsuite] Require supports_process_record in + gdb.reverse/test_ioctl_TCSETSW.exp + +I ran test-case gdb.reverse/test_ioctl_TCSETSW.exp on riscv64-linux, and got: +... +(gdb) record full^M +Process record: the current architecture doesn't support record function.^M +(gdb) FAIL: gdb.reverse/test_ioctl_TCSETSW.exp: record full +... + +Fix this by requiring supports_process_record. + +Tested on riscv64-linux and x86_64-linux. +--- + gdb/testsuite/gdb.reverse/test_ioctl_TCSETSW.exp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/gdb/testsuite/gdb.reverse/test_ioctl_TCSETSW.exp b/gdb/testsuite/gdb.reverse/test_ioctl_TCSETSW.exp +index f6346bc86bf..6d54683982d 100644 +--- a/gdb/testsuite/gdb.reverse/test_ioctl_TCSETSW.exp ++++ b/gdb/testsuite/gdb.reverse/test_ioctl_TCSETSW.exp +@@ -16,6 +16,8 @@ + # Test ioctl TCSETSW record for PowerPC. + # + ++require supports_process_record ++ + standard_testfile .c + + if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { +-- +2.43.0 + diff --git a/gdb-testsuite-reset-errcnt-and-warncnt-in-default_gd.patch b/gdb-testsuite-reset-errcnt-and-warncnt-in-default_gd.patch deleted file mode 100644 index 68f087e..0000000 --- a/gdb-testsuite-reset-errcnt-and-warncnt-in-default_gd.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 37b67fd94ed38959fecc67847666b758b29fe31c Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Tue, 27 Feb 2024 16:24:15 +0100 -Subject: [PATCH 40/48] [gdb/testsuite] Reset errcnt and warncnt in - default_gdb_init - -Say we do: -... -$ make check RUNTESTFLAGS="gdb.dap/ada-nested.exp gdb.dap/pause.exp" -... -and add a perror at the end of pause.exp: -... - dap_shutdown -+ -+perror "foo" -... - -We run into: -... -UNRESOLVED: gdb.dap/ada-nested.exp: compilation prog.adb -... - -This happens because the perror increases the errcnt, which is not reset at -the end of the test-case, and consequently the first pass in the following -test-case is changed into an unresolved. - -Version 1.6.3 of dejagnu contains a fix which produces an unresolved at the -end of the test-case, which does reset the errcnt, but this is with version -1.6.1. - -Furthermore, we reset the errcnt in clean_restart, but the pass is produced -before, so that doesn't help either. - -Fix this by resetting errcnt and warncnt in default_gdb_init. - -Tested on x86_64-linux. - -Approved-By: Tom Tromey - -PR testsuite/31351 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31351 ---- - gdb/testsuite/lib/gdb.exp | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp -index 70c2db4ac84..990d0c8a70f 100644 ---- a/gdb/testsuite/lib/gdb.exp -+++ b/gdb/testsuite/lib/gdb.exp -@@ -6851,6 +6851,15 @@ proc default_gdb_init { test_file_name } { - return [uplevel 1 ::gdb_tcl_unknown $args] - } - } -+ -+ # Dejagnu version 1.6.3 and later produce an unresolved at the end of a -+ # testcase if an error triggered, resetting errcnt and warncnt to 0, in -+ # order to avoid errors in one test-case influencing the following -+ # test-case. Do this manually here, to support older versions. -+ global errcnt -+ global warncnt -+ set errcnt 0 -+ set warncnt 0 - } - - # Return a path using GDB_PARALLEL. --- -2.35.3 - diff --git a/gdb-testsuite-simplify-gdb.server-server-kill-python.patch b/gdb-testsuite-simplify-gdb.server-server-kill-python.patch deleted file mode 100644 index 3156050..0000000 --- a/gdb-testsuite-simplify-gdb.server-server-kill-python.patch +++ /dev/null @@ -1,65 +0,0 @@ -From afab95df8ff5b3bc57e3cacca813df987ce84af2 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Wed, 17 Apr 2024 11:45:02 +0200 -Subject: [PATCH 27/48] [gdb/testsuite] Simplify - gdb.server/server-kill-python.exp - -In test-case gdb.server/server-kill-python.exp we have: -... -if {[gdb_spawn_with_cmdline_opts \ - "-quiet -iex \"set height 0\" -iex \"set width 0\" -ex \"source $host_file1\""] != 0} { - fail "spawn" - return -} -... - -I reproduced the problem by reverting the fix at the commit adding both the -fix and the test-case, and the reproduced the same problem using: -... -(gdb) source $host_file1 -... -so there doesn't seem to be a specific need to source the python file using -"-ex". - -Simplify the test-case by sourcing the python file using send_gdb. - -This also allow us to simplify the python script. - -Tested on x86_64-linux. ---- - gdb/testsuite/gdb.server/server-kill-python.exp | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/gdb/testsuite/gdb.server/server-kill-python.exp b/gdb/testsuite/gdb.server/server-kill-python.exp -index ae85791c770..dcb6eddd6eb 100644 ---- a/gdb/testsuite/gdb.server/server-kill-python.exp -+++ b/gdb/testsuite/gdb.server/server-kill-python.exp -@@ -48,8 +48,6 @@ puts $fd \ - "import gdb - - def do_gdb_stuff (): -- gdb.execute ('file $host_binfile') -- gdb.execute ('target $gdbserver_protocol $gdbserver_gdbport') - gdb.execute ('break $srcfile:$break_linenr') - gdb.execute ('continue') - gdb.execute ('p server_pid') -@@ -63,11 +61,15 @@ set host_file1 [gdb_remote_download host $file1] - # Now start GDB, sourcing the python command file we generated above. - # Set the height and width so we don't end up at a paging prompt. - if {[gdb_spawn_with_cmdline_opts \ -- "-quiet -iex \"set height 0\" -iex \"set width 0\" -ex \"source $host_file1\""] != 0} { -+ "-quiet -iex \"set height 0\" -iex \"set width 0\""] != 0} { - fail "spawn" - return - } - -+gdb_load $binfile -+gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport -+send_gdb "source $host_file1\n" -+ - # Get the gdbserver PID. - set gdbserver_pid 0 - --- -2.35.3 - diff --git a/gdb-testsuite-use-c-flag-in-c-test-cases.patch b/gdb-testsuite-use-c-flag-in-c-test-cases.patch new file mode 100644 index 0000000..afdce17 --- /dev/null +++ b/gdb-testsuite-use-c-flag-in-c-test-cases.patch @@ -0,0 +1,454 @@ +From e20cbb7c969752fb039c7ecfba5d7c3211e3238b Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Mon, 24 Apr 2023 16:15:48 +0200 +Subject: [PATCH] [gdb/testsuite] Use c++ flag in c++ test-cases + +In some cases, test-cases use c++, but don't add "c++" to the compilation +flags. This can cause problems with some compilers. + +Fix this in some test-cases. + +PR testsuite/30380 +https://sourceware.org/bugzilla/show_bug.cgi?id=30380 +--- + gdb/testsuite/gdb.arch/amd64-entry-value.exp | 4 +++- + gdb/testsuite/gdb.arch/amd64-tailcall-cxx.exp | 4 +++- + .../gdb.base/condbreak-multi-context.exp | 6 +++++- + gdb/testsuite/gdb.base/main-psymtab.exp | 6 +++++- + gdb/testsuite/gdb.base/persistent-lang.exp | 6 +++++- + gdb/testsuite/gdb.base/skipcxx.exp | 6 +++++- + gdb/testsuite/gdb.base/start-cpp.exp | 6 +++++- + gdb/testsuite/gdb.cp/call-method-register.exp | 15 +++++++++++---- + gdb/testsuite/gdb.cp/empty-enum.exp | 1 + + .../gdb.cp/incomplete-type-overload.exp | 15 ++++++++++++--- + gdb/testsuite/gdb.cp/main-cp.exp | 6 +++++- + gdb/testsuite/gdb.cp/method-call-in-c.exp | 1 + + gdb/testsuite/gdb.cp/minsym-fallback.exp | 14 +++++++++++--- + gdb/testsuite/gdb.cp/vla-cxx.exp | 6 +++++- + gdb/testsuite/gdb.dwarf2/gdb-index-cxx.exp | 1 + + gdb/testsuite/gdb.dwarf2/method-ptr.exp | 2 +- + .../missing-type-name-for-templates.exp | 16 ++++++++++++++-- + gdb/testsuite/gdb.dwarf2/subrange.exp | 2 +- + gdb/testsuite/gdb.guile/types-module.exp | 6 +++++- + gdb/testsuite/gdb.linespec/cpcompletion.exp | 4 ++++ + gdb/testsuite/gdb.linespec/cpls-ops.exp | 6 +++++- + 21 files changed, 108 insertions(+), 25 deletions(-) + +diff --git a/gdb/testsuite/gdb.arch/amd64-entry-value.exp b/gdb/testsuite/gdb.arch/amd64-entry-value.exp +index 4a28b7ed1fd..3d119d07219 100644 +--- a/gdb/testsuite/gdb.arch/amd64-entry-value.exp ++++ b/gdb/testsuite/gdb.arch/amd64-entry-value.exp +@@ -19,7 +19,9 @@ set opts {nopie} + if [info exists COMPILE] { + # make check RUNTESTFLAGS="gdb.arch/amd64-entry-value.exp COMPILE=1" + set srcfile ${testfile}.cc +- lappend opts debug optimize=-O2 ++ lappend opts debug ++ lappend opts optimize=-O2 ++ lappend opts c++ + } else { + require is_x86_64_m64_target + } +diff --git a/gdb/testsuite/gdb.arch/amd64-tailcall-cxx.exp b/gdb/testsuite/gdb.arch/amd64-tailcall-cxx.exp +index 8bd26c4611b..24d99450f06 100644 +--- a/gdb/testsuite/gdb.arch/amd64-tailcall-cxx.exp ++++ b/gdb/testsuite/gdb.arch/amd64-tailcall-cxx.exp +@@ -19,7 +19,9 @@ standard_testfile amd64-tailcall-cxx1.S amd64-tailcall-cxx2.S + if [info exists COMPILE] { + # make check RUNTESTFLAGS="gdb.arch/amd64-tailcall-cxx.exp COMPILE=1" + standard_testfile amd64-tailcall-cxx1.cc amd64-tailcall-cxx2.cc +- lappend opts debug optimize=-O2 ++ lappend opts debug ++ lappend opts optimize=-O2 ++ lappend opts c++ + } else { + require is_x86_64_m64_target + } +diff --git a/gdb/testsuite/gdb.base/condbreak-multi-context.exp b/gdb/testsuite/gdb.base/condbreak-multi-context.exp +index 3af37081e44..3a4fe37317b 100644 +--- a/gdb/testsuite/gdb.base/condbreak-multi-context.exp ++++ b/gdb/testsuite/gdb.base/condbreak-multi-context.exp +@@ -18,7 +18,11 @@ + + standard_testfile .cc + +-if {[prepare_for_testing "failed to prepare" ${binfile} ${srcfile}]} { ++set flags {} ++lappend flags debug ++lappend flags c++ ++ ++if {[prepare_for_testing "failed to prepare" ${binfile} ${srcfile} $flags]} { + return + } + +diff --git a/gdb/testsuite/gdb.base/main-psymtab.exp b/gdb/testsuite/gdb.base/main-psymtab.exp +index 2cd0d6145bf..cc0ca65ef89 100644 +--- a/gdb/testsuite/gdb.base/main-psymtab.exp ++++ b/gdb/testsuite/gdb.base/main-psymtab.exp +@@ -15,7 +15,11 @@ + + standard_testfile persistent-lang.cc + +-if {[build_executable "failed to prepare" $testfile $srcfile debug]} { ++set flags {} ++lappend flags debug ++lappend flags c++ ++ ++if {[build_executable "failed to prepare" $testfile $srcfile $flags]} { + return -1 + } + +diff --git a/gdb/testsuite/gdb.base/persistent-lang.exp b/gdb/testsuite/gdb.base/persistent-lang.exp +index f8139159a4f..d3bedae1007 100644 +--- a/gdb/testsuite/gdb.base/persistent-lang.exp ++++ b/gdb/testsuite/gdb.base/persistent-lang.exp +@@ -15,7 +15,11 @@ + + standard_testfile .cc + +-if {[build_executable "failed to prepare" $testfile $srcfile debug]} { ++set flags {} ++lappend flags debug ++lappend flags c++ ++ ++if {[build_executable "failed to prepare" $testfile $srcfile $flags]} { + return -1 + } + +diff --git a/gdb/testsuite/gdb.base/skipcxx.exp b/gdb/testsuite/gdb.base/skipcxx.exp +index 60b8fa19cd5..73beed8bb75 100644 +--- a/gdb/testsuite/gdb.base/skipcxx.exp ++++ b/gdb/testsuite/gdb.base/skipcxx.exp +@@ -15,7 +15,11 @@ + + standard_testfile .cc + +-if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} { ++set flags {} ++lappend flags debug ++lappend flags c++ ++ ++if {[prepare_for_testing "failed to prepare" $testfile $srcfile $flags]} { + return -1 + } + +diff --git a/gdb/testsuite/gdb.base/start-cpp.exp b/gdb/testsuite/gdb.base/start-cpp.exp +index b4a036eac28..330c6ea9a67 100644 +--- a/gdb/testsuite/gdb.base/start-cpp.exp ++++ b/gdb/testsuite/gdb.base/start-cpp.exp +@@ -17,7 +17,11 @@ require !use_gdb_stub + + standard_testfile .cc + +-if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} { ++set flags {} ++lappend flags debug ++lappend flags c++ ++ ++if {[prepare_for_testing "failed to prepare" $testfile $srcfile $flags]} { + return -1 + } + +diff --git a/gdb/testsuite/gdb.cp/call-method-register.exp b/gdb/testsuite/gdb.cp/call-method-register.exp +index 1019d4fd8f3..b06620fcb2d 100644 +--- a/gdb/testsuite/gdb.cp/call-method-register.exp ++++ b/gdb/testsuite/gdb.cp/call-method-register.exp +@@ -23,8 +23,15 @@ load_lib dwarf.exp + + standard_testfile .cc -dw.S + +-if {[prepare_for_testing "failed to prepare" $testfile $srcfile \ +- {debug c++}]} { ++set flags_debug {} ++lappend flags_debug debug ++lappend flags_debug c++ ++ ++set flags_nodebug {} ++lappend flags_nodebug nodebug ++lappend flags_nodebug c++ ++ ++if {[prepare_for_testing "failed to prepare" $testfile $srcfile $flags_debug]} { + return -1 + } + +@@ -32,7 +39,7 @@ set asm_file [standard_output_file $srcfile2] + Dwarf::assemble $asm_file { + + set main_result \ +- [function_range main ${::srcdir}/${::subdir}/${::srcfile}] ++ [function_range main ${::srcdir}/${::subdir}/${::srcfile} $::flags_debug] + set main_start [lindex $main_result 0] + set main_length [lindex $main_result 1] + +@@ -97,7 +104,7 @@ Dwarf::assemble $asm_file { + } + + if { [prepare_for_testing "failed to prepare" ${testfile} \ +- [list $srcfile $asm_file] {nodebug}] } { ++ [list $srcfile $asm_file] $::flags_nodebug] } { + return -1 + } + +diff --git a/gdb/testsuite/gdb.cp/empty-enum.exp b/gdb/testsuite/gdb.cp/empty-enum.exp +index 6acae551845..2a0f695a35a 100644 +--- a/gdb/testsuite/gdb.cp/empty-enum.exp ++++ b/gdb/testsuite/gdb.cp/empty-enum.exp +@@ -31,6 +31,7 @@ standard_testfile .cc + + set opts {} + lappend opts debug ++lappend opts c++ + lappend opts additional_flags=-std=c++11 + + if {[prepare_for_testing "failed to prepare" $testfile $srcfile $opts]} { +diff --git a/gdb/testsuite/gdb.cp/incomplete-type-overload.exp b/gdb/testsuite/gdb.cp/incomplete-type-overload.exp +index 1f94c3e6bc7..83f09282df4 100644 +--- a/gdb/testsuite/gdb.cp/incomplete-type-overload.exp ++++ b/gdb/testsuite/gdb.cp/incomplete-type-overload.exp +@@ -25,7 +25,15 @@ require dwarf2_support allow_cplus_tests + standard_testfile .cc .S + set asm_file [standard_output_file ${srcfile2}] + +-if [prepare_for_testing "failed to prepare" $testfile $srcfile {debug c++}] { ++set flags_debug {} ++lappend flags_debug debug ++lappend flags_debug c++ ++ ++set flags_nodebug {} ++lappend flags_nodebug nodebug ++lappend flags_nodebug c++ ++ ++if [prepare_for_testing "failed to prepare" $testfile $srcfile $flags_debug] { + return + } + +@@ -38,7 +46,7 @@ set int_size [get_sizeof "int" -1] + set addr_size [get_sizeof "void *" -1] + set struct_base_size [get_sizeof "base" 4] + set struct_complete_size [get_sizeof "complete" 4] +-get_func_info foo ++get_func_info foo $flags_debug + + # Create fake DWARF for the .cc file. + # This is the best way to ensure we have an incomplete type. +@@ -159,7 +167,8 @@ Dwarf::assemble ${asm_file} { + } + } + +-if [prepare_for_testing "failed to prepare" $testfile [list $asm_file $srcfile] {}] { ++if [prepare_for_testing "failed to prepare" $testfile \ ++ [list $asm_file $srcfile] $flags_nodebug] { + return + } + +diff --git a/gdb/testsuite/gdb.cp/main-cp.exp b/gdb/testsuite/gdb.cp/main-cp.exp +index 6c247e9d22f..98024bf3664 100644 +--- a/gdb/testsuite/gdb.cp/main-cp.exp ++++ b/gdb/testsuite/gdb.cp/main-cp.exp +@@ -20,7 +20,11 @@ standard_testfile main.cc + + require !readnow + +-if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { ++set opts {} ++lappend opts debug ++lappend opts c++ ++ ++if { [prepare_for_testing "failed to prepare" $testfile $srcfile $opts] } { + return -1 + } + +diff --git a/gdb/testsuite/gdb.cp/method-call-in-c.exp b/gdb/testsuite/gdb.cp/method-call-in-c.exp +index 4676a1b06c6..1c2b432c142 100644 +--- a/gdb/testsuite/gdb.cp/method-call-in-c.exp ++++ b/gdb/testsuite/gdb.cp/method-call-in-c.exp +@@ -22,6 +22,7 @@ standard_testfile .cc + + set opts {} + lappend opts debug ++lappend opts c++ + lappend opts additional_flags=-std=c++11 + + if { [prepare_for_testing "failed to prepare" $testfile $srcfile $opts] } { +diff --git a/gdb/testsuite/gdb.cp/minsym-fallback.exp b/gdb/testsuite/gdb.cp/minsym-fallback.exp +index 19ff264893a..6d8fd485840 100644 +--- a/gdb/testsuite/gdb.cp/minsym-fallback.exp ++++ b/gdb/testsuite/gdb.cp/minsym-fallback.exp +@@ -21,13 +21,21 @@ standard_testfile .cc minsym-fallback-main.cc + + include_file minsym-fallback.h + ++set debug_flags {} ++lappend debug_flags debug ++lappend debug_flags c++ ++ ++set nodebug_flags {} ++lappend nodebug_flags nodebug ++lappend nodebug_flags c++ ++ + set executable $testfile + set objfile [standard_output_file ${testfile}.o] + set objmainfile [standard_output_file ${testfile}-main.o] + +-if {[gdb_compile $srcdir/$subdir/$srcfile $objfile object {}] != "" +- || [gdb_compile $srcdir/$subdir/$srcfile2 $objmainfile object {debug}] != "" +- || [gdb_compile "$objfile $objmainfile" $binfile executable {c++}] != ""} { ++if {[gdb_compile $srcdir/$subdir/$srcfile $objfile object $nodebug_flags] != "" ++ || [gdb_compile $srcdir/$subdir/$srcfile2 $objmainfile object $debug_flags] != "" ++ || [gdb_compile "$objfile $objmainfile" $binfile executable $debug_flags] != ""} { + untested "failed to compile" + return -1 + } +diff --git a/gdb/testsuite/gdb.cp/vla-cxx.exp b/gdb/testsuite/gdb.cp/vla-cxx.exp +index bf3ca792d58..4303383d8f4 100644 +--- a/gdb/testsuite/gdb.cp/vla-cxx.exp ++++ b/gdb/testsuite/gdb.cp/vla-cxx.exp +@@ -15,7 +15,11 @@ + + standard_testfile .cc + +-if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { ++set flags {} ++lappend flags debug ++lappend flags c++ ++ ++if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} $flags] } { + return -1 + } + +diff --git a/gdb/testsuite/gdb.dwarf2/gdb-index-cxx.exp b/gdb/testsuite/gdb.dwarf2/gdb-index-cxx.exp +index a62de7b1c72..7083ab7be17 100644 +--- a/gdb/testsuite/gdb.dwarf2/gdb-index-cxx.exp ++++ b/gdb/testsuite/gdb.dwarf2/gdb-index-cxx.exp +@@ -19,6 +19,7 @@ standard_testfile index.cc + + set opts {} + lappend opts debug ++lappend opts c++ + lappend opts additional_flags=-std=c++11 + + if {[prepare_for_testing "failed to prepare" "${testfile}" \ +diff --git a/gdb/testsuite/gdb.dwarf2/method-ptr.exp b/gdb/testsuite/gdb.dwarf2/method-ptr.exp +index 4b4c2229fc2..9bb477681af 100644 +--- a/gdb/testsuite/gdb.dwarf2/method-ptr.exp ++++ b/gdb/testsuite/gdb.dwarf2/method-ptr.exp +@@ -76,7 +76,7 @@ Dwarf::assemble $asm_file { + } + + if { [prepare_for_testing "failed to prepare" ${testfile} \ +- [list $srcfile $asm_file] {nodebug}] } { ++ [list $srcfile $asm_file] {nodebug c++}] } { + return -1 + } + +diff --git a/gdb/testsuite/gdb.dwarf2/missing-type-name-for-templates.exp b/gdb/testsuite/gdb.dwarf2/missing-type-name-for-templates.exp +index 06bd896c56a..869b29f09f6 100644 +--- a/gdb/testsuite/gdb.dwarf2/missing-type-name-for-templates.exp ++++ b/gdb/testsuite/gdb.dwarf2/missing-type-name-for-templates.exp +@@ -25,6 +25,17 @@ require dwarf2_support + + standard_testfile .cc .S + ++set debug_flags {} ++lappend debug_flags debug ++lappend debug_flags c++ ++ ++set nodebug_flags {} ++lappend nodebug_flags nodebug ++lappend nodebug_flags c++ ++ ++get_func_info main $debug_flags ++ ++ + set asm_file [standard_output_file $srcfile2] + Dwarf::assemble $asm_file { + cu {} { +@@ -47,7 +58,8 @@ Dwarf::assemble $asm_file { + + DW_TAG_subprogram { + {DW_AT_name "main"} +- {MACRO_AT_range "main"} ++ {DW_AT_low_pc $::main_start DW_FORM_addr} ++ {DW_AT_high_pc $::main_end DW_FORM_addr} + {DW_AT_type :$int} + {DW_AT_external 1 DW_FORM_flag} + } { +@@ -141,7 +153,7 @@ Dwarf::assemble $asm_file { + } + + if { [prepare_for_testing "failed to prepare" ${testfile} \ +- [list $srcfile $asm_file] {nodebug c++}] } { ++ [list $srcfile $asm_file] $nodebug_flags] } { + return -1 + } + +diff --git a/gdb/testsuite/gdb.dwarf2/subrange.exp b/gdb/testsuite/gdb.dwarf2/subrange.exp +index 2671f829fe8..d384fb6d491 100644 +--- a/gdb/testsuite/gdb.dwarf2/subrange.exp ++++ b/gdb/testsuite/gdb.dwarf2/subrange.exp +@@ -102,7 +102,7 @@ Dwarf::assemble $asm_file { + } + + if { [prepare_for_testing "failed to prepare" ${testfile} \ +- [list $srcfile $asm_file] {nodebug}] } { ++ [list $srcfile $asm_file] {nodebug c++}] } { + return -1 + } + +diff --git a/gdb/testsuite/gdb.guile/types-module.exp b/gdb/testsuite/gdb.guile/types-module.exp +index d95ff21df5e..0da28ad0506 100644 +--- a/gdb/testsuite/gdb.guile/types-module.exp ++++ b/gdb/testsuite/gdb.guile/types-module.exp +@@ -22,7 +22,11 @@ require allow_guile_tests + + standard_testfile .cc + +-if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { ++set flags {} ++lappend flags debug ++lappend flags c++ ++ ++if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} $flags] } { + return -1 + } + +diff --git a/gdb/testsuite/gdb.linespec/cpcompletion.exp b/gdb/testsuite/gdb.linespec/cpcompletion.exp +index 480e03406f2..355a05dd014 100644 +--- a/gdb/testsuite/gdb.linespec/cpcompletion.exp ++++ b/gdb/testsuite/gdb.linespec/cpcompletion.exp +@@ -22,8 +22,12 @@ standard_testfile cpls.cc cpls2.cc cpls-hyphen.cc + + set opts {} + lappend opts debug ++lappend opts c++ + lappend opts additional_flags=-std=c++11 + ++set flags {} ++lappend flags debug ++ + if {[prepare_for_testing "failed to prepare" $testfile \ + [list $srcfile $srcfile2 $srcfile3] $opts]} { + return -1 +diff --git a/gdb/testsuite/gdb.linespec/cpls-ops.exp b/gdb/testsuite/gdb.linespec/cpls-ops.exp +index 22428da905f..7ffcc5c768e 100644 +--- a/gdb/testsuite/gdb.linespec/cpls-ops.exp ++++ b/gdb/testsuite/gdb.linespec/cpls-ops.exp +@@ -19,8 +19,12 @@ load_lib completion-support.exp + + standard_testfile cpls-ops.cc + ++set flags {} ++lappend flags debug ++lappend flags c++ ++ + if {[prepare_for_testing "failed to prepare" $testfile \ +- [list $srcfile] {debug}]} { ++ [list $srcfile] $flags]} { + return -1 + } + + +base-commit: e0c1db6156fa8ee35661a9964062eeb69a963576 +-- +2.43.0 + diff --git a/gdb-testsuite-use-find_gnatmake-instead-of-gdb_find_.patch b/gdb-testsuite-use-find_gnatmake-instead-of-gdb_find_.patch deleted file mode 100644 index f25dcd8..0000000 --- a/gdb-testsuite-use-find_gnatmake-instead-of-gdb_find_.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 6914ab446b7eb9b284b6bfef8d04c3bacafcaa97 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Thu, 18 Apr 2024 17:02:13 +0200 -Subject: [PATCH 26/48] [gdb/testsuite] Use find_gnatmake instead of - gdb_find_gnatmake - -On SLE-11, with an older dejagnu version, I ran into: -... -Running gdb.ada/mi_prot.exp ... -UNRESOLVED: gdb.ada/mi_prot.exp: \ - testcase aborted due to invalid command name: gdb_find_gnatmake -ERROR: tcl error sourcing gdb.ada/mi_prot.exp. -ERROR: invalid command name "gdb_find_gnatmake" - while executing -"::gdb_tcl_unknown gdb_find_gnatmake" - ("uplevel" body line 1) - invoked from within -"uplevel 1 ::gdb_tcl_unknown $args" - (procedure "::unknown" line 5) - invoked from within -"gdb_find_gnatmake" - (procedure "gnatmake_version_at_least" line 2) - invoked from within -... - -Proc gdb_find_gnatmake is actually a backup for find_gnatmake: -... -if {[info procs find_gnatmake] == ""} { - rename gdb_find_gnatmake find_gnatmake -... -so gnatmake_version_at_least should use find_gnatmake instead. - -For a recent dejagnu with find_gnatmake, gdb_find_gnatmake is kept, and we -don't run into this error. - -For an older dejagnu without find_gnatmake, gdb_find_gnatmake is renamed to -find_gnatmake, and we do run into the error. - -It's confusing that we're using the gdb_ prefix for gdb_find_gnatmake, it -seems something legitimate to use. Maybe we should use future_ or gdb_future_ -prefix instead to make this more clear, but I've left that alone for now. - -Fix this by: -- triggering the same error with a recent dejagnu by removing - gdb_find_gnatmake unless used (and likewise for other procs in future.exp), - and -- using find_gnatmake in gnatmake_version_at_least. - -Tested on x86_64-linux. - -Approved-By: Tom Tromey - -PR testsuite/31647 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31647 ---- - gdb/testsuite/lib/ada.exp | 2 +- - gdb/testsuite/lib/future.exp | 15 +++++++++++++++ - 2 files changed, 16 insertions(+), 1 deletion(-) - -diff --git a/gdb/testsuite/lib/ada.exp b/gdb/testsuite/lib/ada.exp -index d45d75994dd..4bf1368f29f 100644 ---- a/gdb/testsuite/lib/ada.exp -+++ b/gdb/testsuite/lib/ada.exp -@@ -151,7 +151,7 @@ proc find_ada_tool {tool} { - # Return 1 if gnatmake is at least version $MAJOR.x.x - - proc gnatmake_version_at_least { major } { -- set gnatmake [gdb_find_gnatmake] -+ set gnatmake [find_gnatmake] - set gnatmake [lindex [split $gnatmake] 0] - if {[catch {exec $gnatmake --version} output]} { - return 0 -diff --git a/gdb/testsuite/lib/future.exp b/gdb/testsuite/lib/future.exp -index 807053b8f94..204e11effa4 100644 ---- a/gdb/testsuite/lib/future.exp -+++ b/gdb/testsuite/lib/future.exp -@@ -694,12 +694,16 @@ if {[info procs find_gnatmake] == ""} { - rename gdb_find_gnatmake find_gnatmake - set use_gdb_compile(ada) 1 - gdb_note [join [list $note_prefix "Ada" $note_suffix] ""] -+} else { -+ rename gdb_find_gnatmake "" - } - - if {[info procs find_gfortran] == ""} { - rename gdb_find_gfortran find_gfortran - set use_gdb_compile(fortran) 1 - gdb_note [join [list $note_prefix "Fortran" $note_suffix] ""] -+} else { -+ rename gdb_find_gfortran "" - } - - if {[info procs find_go_linker] == ""} { -@@ -707,24 +711,33 @@ if {[info procs find_go_linker] == ""} { - rename gdb_find_go_linker find_go_linker - set use_gdb_compile(go) 1 - gdb_note [join [list $note_prefix "Go" $note_suffix] ""] -+} else { -+ rename gdb_find_go "" -+ rename gdb_find_go_linker "" - } - - if {[info procs find_gdc] == ""} { - rename gdb_find_gdc find_gdc - set use_gdb_compile(d) 1 - gdb_note [join [list $note_prefix "D" $note_suffix] ""] -+} else { -+ rename gdb_find_gdc "" - } - - if {[info procs find_rustc] == ""} { - rename gdb_find_rustc find_rustc - set use_gdb_compile(rust) 1 - gdb_note [join [list $note_prefix "Rust" $note_suffix] ""] -+} else { -+ rename gdb_find_rustc "" - } - - if {[info procs find_hipcc] == ""} { - rename gdb_find_hipcc find_hipcc - set use_gdb_compile(hip) 1 - gdb_note [join [list $note_prefix "HIP" $note_suffix] ""] -+} else { -+ rename gdb_find_hipcc "" - } - - # If dejagnu's default_target_compile is missing support for any language, -@@ -732,6 +745,8 @@ if {[info procs find_hipcc] == ""} { - if { [array size use_gdb_compile] != 0 } { - catch {rename default_target_compile dejagnu_default_target_compile} - rename gdb_default_target_compile default_target_compile -+} else { -+ rename gdb_default_target_compile "" - } - - --- -2.35.3 - diff --git a/gdb-testsuite-use-more-progbits-for-arm.patch b/gdb-testsuite-use-more-progbits-for-arm.patch deleted file mode 100644 index bba4283..0000000 --- a/gdb-testsuite-use-more-progbits-for-arm.patch +++ /dev/null @@ -1,858 +0,0 @@ -From d9951c3c9ea2e542d071710e9706ed505046fe36 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Fri, 24 Nov 2023 15:41:22 +0100 -Subject: [PATCH 48/48] [gdb/testsuite] Use more %progbits for arm - -On pinebook I ran into: -... -Running gdb.tui/tui-layout-asm-short-prog.exp ... -gdb compile failed, gdb.tui/tui-layout-asm-short-prog.S: Assembler messages: -gdb.tui/tui-layout-asm-short-prog.S:23: Error: \ - junk at end of line, first unrecognized character is `,' -... - -Fix this by using %progbits instead of @progbits for arm. - -Approved-by: Luis Machado - -Tested on x86_64-linux and pinebook. ---- - gdb/testsuite/gdb.arch/pr25124.S | 2 +- - gdb/testsuite/gdb.base/dup-sect.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dup-psym.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-abs-hi-pc-hello-dbg.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-abs-hi-pc-world-dbg.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-ada-ffffffff.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-anon-mptr.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-anonymous-func.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-bad-elf-other.S | 8 ++++++++ - gdb/testsuite/gdb.dwarf2/dw2-bad-parameter-type.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-basic.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-canonicalize-type.S | 4 ++++ - .../gdb.dwarf2/dw2-case-insensitive-debug.S | 8 ++++++++ - gdb/testsuite/gdb.dwarf2/dw2-compdir-oldgcc.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-compressed.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-const.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-cp-infcall-ref-static.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-cu-size.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-dos-drive.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-double-set-die-type.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-dummy-cu.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-empty-namespace.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-empty-pc-range.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-entry-value.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-filename.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-icc-opaque.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-icycle.S | 12 ++++++++++++ - gdb/testsuite/gdb.dwarf2/dw2-inheritance.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-inline-param.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-intercu.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-intermix.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-linkage-name-trust.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-minsym-in-cu.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-modula2-self-type.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-noloc.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-objfile-overlap-inner.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-objfile-overlap-outer.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-op-call.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-op-stack-value.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-param-error.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-producer.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-ref-missing-frame.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-stack-boundary.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-strp.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-unresolved.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw2-var-zero-addr.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/dw4-sig-type-unused.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/fission-reread.S | 4 ++++ - .../gdb.dwarf2/frame-inlined-in-outer-frame.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/mac-fileno.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/pr11465.S | 4 ++++ - gdb/testsuite/gdb.dwarf2/pr13961.S | 4 ++++ - gdb/testsuite/gdb.linespec/break-asm-file.exp | 4 ++-- - .../{break-asm-file0.s => break-asm-file0.S} | 12 ++++++++---- - .../{break-asm-file1.s => break-asm-file1.S} | 8 ++++++-- - gdb/testsuite/gdb.mi/dw2-ref-missing-frame.S | 4 ++++ - gdb/testsuite/gdb.tui/tui-layout-asm-short-prog.S | 4 ++++ - 59 files changed, 253 insertions(+), 9 deletions(-) - rename gdb/testsuite/gdb.linespec/{break-asm-file0.s => break-asm-file0.S} (96%) - rename gdb/testsuite/gdb.linespec/{break-asm-file1.s => break-asm-file1.S} (97%) - -diff --git a/gdb/testsuite/gdb.arch/pr25124.S b/gdb/testsuite/gdb.arch/pr25124.S -index a7ed1a02472..27b4e683488 100644 ---- a/gdb/testsuite/gdb.arch/pr25124.S -+++ b/gdb/testsuite/gdb.arch/pr25124.S -@@ -33,4 +33,4 @@ main: - mov r0, #0 - bx lr - .size main, .-main -- .section .note.GNU-stack,"",@progbits -+ .section .note.GNU-stack,"",%progbits -diff --git a/gdb/testsuite/gdb.base/dup-sect.S b/gdb/testsuite/gdb.base/dup-sect.S -index e374d578dc0..c51bc91d6d8 100644 ---- a/gdb/testsuite/gdb.base/dup-sect.S -+++ b/gdb/testsuite/gdb.base/dup-sect.S -@@ -20,4 +20,8 @@ var1: .byte 1 - - .section sect2, "a" - var2: .byte 2 -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dup-psym.S b/gdb/testsuite/gdb.dwarf2/dup-psym.S -index ec180e65080..4e50c0fe885 100644 ---- a/gdb/testsuite/gdb.dwarf2/dup-psym.S -+++ b/gdb/testsuite/gdb.dwarf2/dup-psym.S -@@ -197,4 +197,8 @@ func_cu1: - .byte 1 - - .Lline1_end: -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-abs-hi-pc-hello-dbg.S b/gdb/testsuite/gdb.dwarf2/dw2-abs-hi-pc-hello-dbg.S -index f0276adf3be..e1fccd1979f 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-abs-hi-pc-hello-dbg.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-abs-hi-pc-hello-dbg.S -@@ -149,4 +149,8 @@ LELTP: - .uleb128 0x1 - .byte 0x1 - LELT: -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-abs-hi-pc-world-dbg.S b/gdb/testsuite/gdb.dwarf2/dw2-abs-hi-pc-world-dbg.S -index 59dd26c3c85..2ff445e36a4 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-abs-hi-pc-world-dbg.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-abs-hi-pc-world-dbg.S -@@ -149,4 +149,8 @@ LELTP: - .uleb128 0x1 - .byte 0x1 - LELT: -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-ada-ffffffff.S b/gdb/testsuite/gdb.dwarf2/dw2-ada-ffffffff.S -index 960a97c39a8..d58c8bfedf8 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-ada-ffffffff.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-ada-ffffffff.S -@@ -53,4 +53,8 @@ debug_end: - .byte 0x0 - .byte 0x0 - .byte 0x0 -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-anon-mptr.S b/gdb/testsuite/gdb.dwarf2/dw2-anon-mptr.S -index 2c62b613c57..dc6b86648bd 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-anon-mptr.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-anon-mptr.S -@@ -375,4 +375,8 @@ - - .section .debug_line - .Ldebug_line0: -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-anonymous-func.S b/gdb/testsuite/gdb.dwarf2/dw2-anonymous-func.S -index 8b88ba6d1ef..45cd7c42fb8 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-anonymous-func.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-anonymous-func.S -@@ -246,4 +246,8 @@ func_cu2: - .byte 1 - - .Lline1_end: -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-bad-elf-other.S b/gdb/testsuite/gdb.dwarf2/dw2-bad-elf-other.S -index d90d4e2b4ac..192bfac844f 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-bad-elf-other.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-bad-elf-other.S -@@ -15,7 +15,11 @@ - - .section ".other", "x" - .global some_func, some_func_end -+#ifdef __arm__ -+ .type some_func, %function -+#else - .type some_func, @function -+#endif - nop - nop - nop -@@ -27,4 +31,8 @@ some_func: - .size some_func,.-some_func - some_func_end: - nop -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-bad-parameter-type.S b/gdb/testsuite/gdb.dwarf2/dw2-bad-parameter-type.S -index d7654bb1c14..10ea1ae24cb 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-bad-parameter-type.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-bad-parameter-type.S -@@ -71,4 +71,8 @@ debug_end: - .byte 0x0 - .byte 0x0 - .byte 0x0 -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-basic.S b/gdb/testsuite/gdb.dwarf2/dw2-basic.S -index 372ab23cb3b..7b37162b037 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-basic.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-basic.S -@@ -197,4 +197,8 @@ func_cu1: - .byte 1 - - .Lline1_end: -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-canonicalize-type.S b/gdb/testsuite/gdb.dwarf2/dw2-canonicalize-type.S -index 39e462b7149..ffe29d17a3a 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-canonicalize-type.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-canonicalize-type.S -@@ -154,4 +154,8 @@ debug_end: - .byte 0x0 - .byte 0x0 - .byte 0x0 -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive-debug.S b/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive-debug.S -index 1059ace3b3e..84e6ee9a485 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive-debug.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive-debug.S -@@ -60,7 +60,11 @@ - /* The .debug_names-based index support depends on - .debug_aranges generated by GCC. (.gdb_index includes a - gdb-generated map instead.) */ -+#ifdef __arm__ -+ .section .debug_aranges,"",%progbits -+#else - .section .debug_aranges,"",@progbits -+#endif - .4byte .Laranges_end - .Laranges_start // Length of Address Ranges Info - .Laranges_start: - .2byte 0x2 // DWARF Version -@@ -126,4 +130,8 @@ - - .byte 0x0 /* Terminator */ - .byte 0x0 /* Terminator */ -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-compdir-oldgcc.S b/gdb/testsuite/gdb.dwarf2/dw2-compdir-oldgcc.S -index 8a8ecfc397b..4d626817f1a 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-compdir-oldgcc.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-compdir-oldgcc.S -@@ -239,4 +239,8 @@ gcc43: .globl gcc43 - .uleb128 1 - .byte 1 - .Lgcc43_end: -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-compressed.S b/gdb/testsuite/gdb.dwarf2/dw2-compressed.S -index 509fbea4a3b..14cf286f393 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-compressed.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-compressed.S -@@ -218,4 +218,8 @@ func_cu1: - .byte 0x9c - .byte 0x00 - .byte 0x92 -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-const.S b/gdb/testsuite/gdb.dwarf2/dw2-const.S -index dfc882ac530..ff81c18732d 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-const.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-const.S -@@ -249,4 +249,8 @@ func_cu1: - .byte 1 - - .Lline1_end: -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-cp-infcall-ref-static.S b/gdb/testsuite/gdb.dwarf2/dw2-cp-infcall-ref-static.S -index 070f24b407d..e217c736dd8 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-cp-infcall-ref-static.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-cp-infcall-ref-static.S -@@ -113,4 +113,8 @@ - - .byte 0x0 /* Terminator */ - .byte 0x0 /* Terminator */ -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-cu-size.S b/gdb/testsuite/gdb.dwarf2/dw2-cu-size.S -index 99465e2c015..b6f8a2117b3 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-cu-size.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-cu-size.S -@@ -107,4 +107,8 @@ - - .byte 0x0 /* Terminator .debug_abbrev - section. */ -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-dos-drive.S b/gdb/testsuite/gdb.dwarf2/dw2-dos-drive.S -index d0bdce9ef8b..e4d13a8cd04 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-dos-drive.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-dos-drive.S -@@ -74,4 +74,8 @@ dieb: - .byte 0x0 - - .byte 0x0 -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-double-set-die-type.S b/gdb/testsuite/gdb.dwarf2/dw2-double-set-die-type.S -index 973d5020342..d4fdb1d3077 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-double-set-die-type.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-double-set-die-type.S -@@ -617,4 +617,8 @@ - .byte 0x0 - .byte 0x0 - -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-dummy-cu.S b/gdb/testsuite/gdb.dwarf2/dw2-dummy-cu.S -index 781b87e7115..f44db05f266 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-dummy-cu.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-dummy-cu.S -@@ -31,4 +31,8 @@ main_end: - .section .debug_abbrev - .Ldebug_abbrev0: - .byte 0x0 -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-empty-namespace.S b/gdb/testsuite/gdb.dwarf2/dw2-empty-namespace.S -index d78b7e87ff5..5e08776ba39 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-empty-namespace.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-empty-namespace.S -@@ -106,4 +106,8 @@ var: .4byte 1 - - .byte 0x0 /* Terminator */ - .byte 0x0 /* Terminator */ -+#ifdef __arm__ -+ .type some_func, %function -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-empty-pc-range.S b/gdb/testsuite/gdb.dwarf2/dw2-empty-pc-range.S -index ea8dd092cb0..e4678d86695 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-empty-pc-range.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-empty-pc-range.S -@@ -80,4 +80,8 @@ dieb: - .byte 0x0 - - .byte 0x0 -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-entry-value.S b/gdb/testsuite/gdb.dwarf2/dw2-entry-value.S -index 82d4549b8b5..5fdfeecbb09 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-entry-value.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-entry-value.S -@@ -102,4 +102,8 @@ loclist: - .byte 0x0 - .byte 0x0 - .byte 0x0 -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-filename.S b/gdb/testsuite/gdb.dwarf2/dw2-filename.S -index 1cdd94a12f5..a1f0867aed5 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-filename.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-filename.S -@@ -51,4 +51,8 @@ - - .byte 0x0 /* Terminator */ - .byte 0x0 /* Terminator */ -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-icc-opaque.S b/gdb/testsuite/gdb.dwarf2/dw2-icc-opaque.S -index f954c4f7cc7..67ba8a47d37 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-icc-opaque.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-icc-opaque.S -@@ -252,4 +252,8 @@ debug_info_seg3_end: - .byte 0x08 /* DW_FORM_string. */ - .2byte 0x0000 /* End abbrev. */ - .byte 0x00 /* End abbrev table. */ -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-icycle.S b/gdb/testsuite/gdb.dwarf2/dw2-icycle.S -index 8856eb6e5d3..e432f629cae 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-icycle.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-icycle.S -@@ -18,7 +18,11 @@ - .text - - .Ltext0: -+#ifdef __arm__ -+ .type p__top__middle__inside.3062, %function -+#else - .type p__top__middle__inside.3062, @function -+#endif - p__top__middle__inside.3062: - .LFB4: - .file 1 "p.adb" -@@ -26,7 +30,11 @@ p__top__middle__inside.3062: - .LBE6: - - .globl p__top -+#ifdef __arm__ -+ .type p__top, %function -+#else - .type p__top, @function -+#endif - p__top: - .LFB2: - .4byte 0 -@@ -246,4 +254,8 @@ p__top: - .Lline1_begin: - .byte 0 - -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inheritance.S b/gdb/testsuite/gdb.dwarf2/dw2-inheritance.S -index f83762503ac..1585d8ac576 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-inheritance.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-inheritance.S -@@ -96,4 +96,8 @@ - - .byte 0x0 /* Terminator */ - .byte 0x0 /* Terminator */ -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inline-param.S b/gdb/testsuite/gdb.dwarf2/dw2-inline-param.S -index 540bbb38342..c460dddb732 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-inline-param.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-param.S -@@ -150,4 +150,8 @@ - - .byte 0x0 /* Terminator */ - .byte 0x0 /* Terminator */ -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-intercu.S b/gdb/testsuite/gdb.dwarf2/dw2-intercu.S -index a068ba116f9..2cdc3049bc0 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-intercu.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-intercu.S -@@ -314,4 +314,8 @@ func_cu1: - .byte 1 - - .Lline1_end: -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-intermix.S b/gdb/testsuite/gdb.dwarf2/dw2-intermix.S -index a9a474e2b7c..010bdb22454 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-intermix.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-intermix.S -@@ -198,4 +198,8 @@ func_cu1: - .byte 1 - - .Lline1_end: -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-linkage-name-trust.S b/gdb/testsuite/gdb.dwarf2/dw2-linkage-name-trust.S -index aa3ec9d486c..8a16022bd8f 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-linkage-name-trust.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-linkage-name-trust.S -@@ -132,4 +132,8 @@ c: .4byte 0 - - .byte 0x0 /* Terminator */ - .byte 0x0 /* Terminator */ -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-minsym-in-cu.S b/gdb/testsuite/gdb.dwarf2/dw2-minsym-in-cu.S -index 4169f720837..cbc1c87bb91 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-minsym-in-cu.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-minsym-in-cu.S -@@ -115,4 +115,8 @@ func2: - - .byte 0x0 /* Terminator */ - .byte 0x0 /* Terminator */ -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-modula2-self-type.S b/gdb/testsuite/gdb.dwarf2/dw2-modula2-self-type.S -index 82236a7091a..6289c36f01e 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-modula2-self-type.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-modula2-self-type.S -@@ -121,4 +121,8 @@ die221: - .string "GNU Modula-2 0.78 (20100402) grafted onto GCC 4.1.2" - .LASF2: - .string "" -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-noloc.S b/gdb/testsuite/gdb.dwarf2/dw2-noloc.S -index 4b742437b56..d9e31d30ed9 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-noloc.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-noloc.S -@@ -324,4 +324,8 @@ resolvable: - - .byte 0x0 /* Terminator */ - .byte 0x0 /* Terminator */ -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-objfile-overlap-inner.S b/gdb/testsuite/gdb.dwarf2/dw2-objfile-overlap-inner.S -index 93abcf6e09a..57c58123fb8 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-objfile-overlap-inner.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-objfile-overlap-inner.S -@@ -178,4 +178,8 @@ inner: - .byte 1 - - .Lline1_end: -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-objfile-overlap-outer.S b/gdb/testsuite/gdb.dwarf2/dw2-objfile-overlap-outer.S -index 6031ad26d93..99ff8c1151e 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-objfile-overlap-outer.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-objfile-overlap-outer.S -@@ -209,4 +209,8 @@ outer_after: - .byte 1 - - .Lline1_end: -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-op-call.S b/gdb/testsuite/gdb.dwarf2/dw2-op-call.S -index 2ae7bae9a4b..e5bba2cf053 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-op-call.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-op-call.S -@@ -166,4 +166,8 @@ loclist: - - .byte 0x0 /* Terminator */ - .byte 0x0 /* Terminator */ -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-op-stack-value.S b/gdb/testsuite/gdb.dwarf2/dw2-op-stack-value.S -index 003732618b2..6983f0ed675 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-op-stack-value.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-op-stack-value.S -@@ -130,4 +130,8 @@ aa551234: .byte 0xaa, 0x55, 0x12, 0x34 - - .byte 0x0 /* Terminator */ - .byte 0x0 /* Terminator */ -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-param-error.S b/gdb/testsuite/gdb.dwarf2/dw2-param-error.S -index 3c7ca3c8ad3..a8b8155b966 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-param-error.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-param-error.S -@@ -106,4 +106,8 @@ debug_end: - .byte 0x0 - .byte 0x0 - .byte 0x0 -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-producer.S b/gdb/testsuite/gdb.dwarf2/dw2-producer.S -index ca63697e90d..30338ebd652 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-producer.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-producer.S -@@ -198,4 +198,8 @@ func_cu1: - .byte 1 - - .Lline1_end: -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-ref-missing-frame.S b/gdb/testsuite/gdb.dwarf2/dw2-ref-missing-frame.S -index 1091dbc895e..3e3502a441b 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-ref-missing-frame.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-ref-missing-frame.S -@@ -149,4 +149,8 @@ - - .byte 0x0 /* Terminator */ - .byte 0x0 /* Terminator */ -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.S b/gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.S -index f199994bcdf..5844ebe4f6d 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.S -@@ -167,4 +167,8 @@ d: - .string "sizetype" - .LASF1: - .string "char" -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.S b/gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.S -index d19ee72ebf3..c94147430c3 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.S -@@ -397,4 +397,8 @@ loclist: - .byte 1 - - .Lline1_end: -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-stack-boundary.S b/gdb/testsuite/gdb.dwarf2/dw2-stack-boundary.S -index 8ea03b126ac..6d4a7be3834 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-stack-boundary.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-stack-boundary.S -@@ -66,4 +66,8 @@ debug_end: - .byte 0x0 - .byte 0x0 - .byte 0x0 -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-strp.S b/gdb/testsuite/gdb.dwarf2/dw2-strp.S -index dd4eb4fe46a..e0e27ce7548 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-strp.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-strp.S -@@ -176,4 +176,8 @@ - .string "hello world!\n" - .Lemptyname: - .string "" -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-unresolved.S b/gdb/testsuite/gdb.dwarf2/dw2-unresolved.S -index c52852d7463..2a0a8de6793 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-unresolved.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-unresolved.S -@@ -178,4 +178,8 @@ SYMBOL(var): .byte 2 - - .byte 0x0 /* Terminator */ - .byte 0x0 /* Terminator */ -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw2-var-zero-addr.S b/gdb/testsuite/gdb.dwarf2/dw2-var-zero-addr.S -index f2fb3c39a23..2abb4f7ee25 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw2-var-zero-addr.S -+++ b/gdb/testsuite/gdb.dwarf2/dw2-var-zero-addr.S -@@ -90,4 +90,8 @@ - - .byte 0x0 /* Terminator */ - .byte 0x0 /* Terminator */ -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/dw4-sig-type-unused.S b/gdb/testsuite/gdb.dwarf2/dw4-sig-type-unused.S -index d4b4bb64a3c..4678c0fe0f2 100644 ---- a/gdb/testsuite/gdb.dwarf2/dw4-sig-type-unused.S -+++ b/gdb/testsuite/gdb.dwarf2/dw4-sig-type-unused.S -@@ -85,4 +85,8 @@ types_start: - .byte 0x0 - .byte 0x0 - .byte 0x0 -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/fission-reread.S b/gdb/testsuite/gdb.dwarf2/fission-reread.S -index bdb20e76330..6171453c4a5 100644 ---- a/gdb/testsuite/gdb.dwarf2/fission-reread.S -+++ b/gdb/testsuite/gdb.dwarf2/fission-reread.S -@@ -460,4 +460,8 @@ SYMBOL(main): - .Ldebug_addr0: - .4byte .LFB0 /* DW_AT_low_pc */ - .4byte SYMBOL(baz) /* DW_AT_location */ -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/frame-inlined-in-outer-frame.S b/gdb/testsuite/gdb.dwarf2/frame-inlined-in-outer-frame.S -index 7e5971c50c9..a41b2851394 100644 ---- a/gdb/testsuite/gdb.dwarf2/frame-inlined-in-outer-frame.S -+++ b/gdb/testsuite/gdb.dwarf2/frame-inlined-in-outer-frame.S -@@ -164,4 +164,8 @@ __start_high_pc: - - .global __cu_high_pc - __cu_high_pc: -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/mac-fileno.S b/gdb/testsuite/gdb.dwarf2/mac-fileno.S -index 77730401515..71401bc81c7 100644 ---- a/gdb/testsuite/gdb.dwarf2/mac-fileno.S -+++ b/gdb/testsuite/gdb.dwarf2/mac-fileno.S -@@ -209,4 +209,8 @@ func_cu1: - .uleb128 0x0 /* Included from line number 0 */ - .uleb128 0x0 /* Filename we just started (bug: number too small) */ - .byte 0x0 /* end of CU's macro information */ -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/pr11465.S b/gdb/testsuite/gdb.dwarf2/pr11465.S -index 5308abebee0..b974f0e9c63 100644 ---- a/gdb/testsuite/gdb.dwarf2/pr11465.S -+++ b/gdb/testsuite/gdb.dwarf2/pr11465.S -@@ -360,4 +360,8 @@ die149: .uleb128 0x16 /* DW_TAG_variable */ - .LASF4: - .string "GNU C++ 4.4.2" - .ident "GCC: (GNU) 4.4.2" -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.dwarf2/pr13961.S b/gdb/testsuite/gdb.dwarf2/pr13961.S -index fc9d7afa838..4c1162591c3 100644 ---- a/gdb/testsuite/gdb.dwarf2/pr13961.S -+++ b/gdb/testsuite/gdb.dwarf2/pr13961.S -@@ -378,4 +378,8 @@ SYMBOL(main): - .LASF3: - .string "main" - -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.mi/dw2-ref-missing-frame.S b/gdb/testsuite/gdb.mi/dw2-ref-missing-frame.S -index 684b9d93541..e37b04a4219 100644 ---- a/gdb/testsuite/gdb.mi/dw2-ref-missing-frame.S -+++ b/gdb/testsuite/gdb.mi/dw2-ref-missing-frame.S -@@ -163,4 +163,8 @@ - - .byte 0x0 /* Terminator */ - .byte 0x0 /* Terminator */ -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif -diff --git a/gdb/testsuite/gdb.tui/tui-layout-asm-short-prog.S b/gdb/testsuite/gdb.tui/tui-layout-asm-short-prog.S -index d577804e4bb..461e322628a 100644 ---- a/gdb/testsuite/gdb.tui/tui-layout-asm-short-prog.S -+++ b/gdb/testsuite/gdb.tui/tui-layout-asm-short-prog.S -@@ -20,4 +20,8 @@ _start: - .rept 5 - nop - .endr -+#ifdef __arm__ -+ .section .note.GNU-stack,"",%progbits -+#else - .section .note.GNU-stack,"",@progbits -+#endif --- -2.35.3 - diff --git a/gdb-testsuite-use-nostdlib-in-gdb.base-list-dot-node.patch b/gdb-testsuite-use-nostdlib-in-gdb.base-list-dot-node.patch new file mode 100644 index 0000000..b460d8a --- /dev/null +++ b/gdb-testsuite-use-nostdlib-in-gdb.base-list-dot-node.patch @@ -0,0 +1,172 @@ +From 43be94acc8f9bbc0ff8da8c2b9fbaa56ee9b344e Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Tue, 4 Feb 2025 11:01:38 +0100 +Subject: [PATCH 40/46] [gdb/testsuite] Use -nostdlib in + gdb.base/list-dot-nodebug.exp + +When running test-case gdb.base/list-dot-nodebug.exp with target board +cc-with-gnu-debuglink, I run into: +... +(gdb) list .^M +warning: 1 ../sysdeps/x86_64/crtn.S: No such file or directory^M +(gdb) FAIL: gdb.base/list-dot-nodebug.exp: debug=none: print before start +... + +The problem is that the call to gdb_gnu_strip_debug in +gdb.base/list-dot-nodebug.exp has no effect, because the target board makes +sure that compilation delivers an executable that is already stripped, with a +.gnu_debuglink section linking to the debug info. + +Fix this by using -nostdlib instead of static, which means the call to +gdb_gnu_strip_debug can be removed. + +This also allows us to extend the test-case to excercise "list ." before +starting the inferior, for the debug=some scenario, which is currently +skipped: +... + # We don't test "list ." before starting with some debug info + # because GDB will choose the symtab that has debuginfo, and + # print the copyright blurb. This test isn't interested (yet?) + # in checking if this default location choice is consistent. +... + +While we're at it, make the effect of "list ." on the current source location +explicit using "info source" before and after "list .". + +While we're at it, make sure when running with target board +cc-with-gdb-index or cc-with-debug-names, that the failure to compile the +debug=none variant due to: +... +Error while writing index ...: No debugging symbols +... +doesn't stop the test-case from running the debug=some variant. + +Tested on x86_64-linux. +--- + gdb/testsuite/gdb.base/list-dot-nodebug.c | 9 +++ + gdb/testsuite/gdb.base/list-dot-nodebug.exp | 69 +++++++++++++-------- + 2 files changed, 52 insertions(+), 26 deletions(-) + +diff --git a/gdb/testsuite/gdb.base/list-dot-nodebug.c b/gdb/testsuite/gdb.base/list-dot-nodebug.c +index b37c3561c41..5d2a1a32d82 100644 +--- a/gdb/testsuite/gdb.base/list-dot-nodebug.c ++++ b/gdb/testsuite/gdb.base/list-dot-nodebug.c +@@ -31,3 +31,12 @@ main () + foo (&x); + return 0; + } ++ ++void ++_start () ++{ ++ (void) main (); ++ ++ while (1) ++ ; ++} +diff --git a/gdb/testsuite/gdb.base/list-dot-nodebug.exp b/gdb/testsuite/gdb.base/list-dot-nodebug.exp +index 107669de04d..e15e2bd58e1 100644 +--- a/gdb/testsuite/gdb.base/list-dot-nodebug.exp ++++ b/gdb/testsuite/gdb.base/list-dot-nodebug.exp +@@ -19,51 +19,64 @@ + + require !use_gdb_stub + +-set linkflags [list additional_flags="-static"] +- +-if { ![gdb_can_simple_compile static-libc \ +- { +- int main (void) { return 0; } +- } \ +- executable $linkflags] } { +- untested "Can't statically link" +- return -1 +-} +- + standard_testfile .c -extra.c + +-foreach_with_prefix debug {"none" "some"} { ++proc do_test { debug } { ++ ++ set opts {} ++ lappend opts additional_flags=-nostdlib + + if {$debug == "some"} { ++ lappend opts debug ++ + if {[prepare_for_testing_full "failed to prepare" \ +- [list ${testfile}-${debug} $linkflags \ +- $srcfile [list nodebug] \ +- $srcfile2 [list debug]]]} { ++ [list ${::testfile}-${debug} $opts \ ++ $::srcfile [list nodebug] \ ++ $::srcfile2 [list debug]]]} { + return -1 + } + +- # We don't test "list ." before starting with some debug info +- # because GDB will choose the symtab that has debuginfo, and +- # print the copyright blurb. This test isn't interested (yet?) +- # in checking if this default location choice is consistent. ++ ++ with_test_prefix "before list" { ++ gdb_test "info source" \ ++ [string_to_regexp "No current source file."] ++ } ++ ++ gdb_test "list ." \ ++ .*[string_to_regexp \ ++ "This testcase is part of GDB, the GNU debugger."].* \ ++ "print before start" ++ ++ with_test_prefix "after list" { ++ gdb_test "info source" \ ++ .*[string_to_regexp $::srcfile2].* ++ } ++ + } else { +- set executable ${testfile}-none ++ lappend opts nodebug ++ ++ set executable ${::testfile}-none + if {[build_executable "failed to prepare" ${executable} \ +- [list $srcfile $srcfile2] $linkflags]} { ++ [list $::srcfile $::srcfile2] $opts]} { + return -1 + } + +- # Stripping is a backup in case the system has static libc debuginfo. +- # We can continue the test even if it fails. +- gdb_gnu_strip_debug [standard_output_file $executable] no-debuglink +- + clean_restart ${executable} + ++ with_test_prefix "before list" { ++ gdb_test "info source" \ ++ [string_to_regexp "No current source file."] ++ } ++ + gdb_test "list ." \ + "^Insufficient debug info for showing source lines at default location" \ + "print before start" +- } + ++ with_test_prefix "after list" { ++ gdb_test "info source" \ ++ [string_to_regexp "No current source file."] ++ } ++ } + + if { ![runto bar] } { + return -1 +@@ -73,3 +86,7 @@ foreach_with_prefix debug {"none" "some"} { + "^Insufficient debug info for showing source lines at current PC \\($::hex\\)\\." \ + "print after start" + } ++ ++foreach_with_prefix debug {"none" "some"} { ++ do_test $debug ++} +-- +2.43.0 + diff --git a/gdb-testsuite-use-unique-portnum-in-parallel-testing-check-slash-slash-case.patch b/gdb-testsuite-use-unique-portnum-in-parallel-testing-check-slash-slash-case.patch deleted file mode 100644 index fb67c05..0000000 --- a/gdb-testsuite-use-unique-portnum-in-parallel-testing-check-slash-slash-case.patch +++ /dev/null @@ -1,95 +0,0 @@ -From f24d498c972be365c72c99f14ada42e3a300b3c4 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Sat, 4 May 2024 10:41:09 +0200 -Subject: [PATCH 22/48] [gdb/testsuite] Use unique portnum in parallel testing - (check//% case) - -Make target check//% is the gdb variant of a similar gcc make target [1]. - -When running tests using check//%: -... -$ cd build/gdb -$ make check//unix/{-fPIE/-pie,-fno-PIE/-no-pie} -j2 TESTS=gdb.server/*.exp -... -we get: -... -$ cat build/gdb/testsuite.unix.-fPIE.-pie/cache/portnum -2427 -$ cat build/gdb/testsuite.unix.-fno-PIE.-no-pie/cache/portnum -2423 -... - -The problem is that there are two portnum files used in parallel. - -Fix this by: -- creating a common lockdir build/gdb/testsuite.lockdir for make target - check//%, -- passing this down to the runtests invocations using variable GDB_LOCK_DIR, - and -- using GDB_LOCK_DIR in lock_dir. - -Tested on aarch64-linux. - -Approved-By: Tom Tromey - -PR testsuite/31632 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31632 - -[1] https://gcc.gnu.org/install/test.html ---- - gdb/Makefile.in | 8 ++++++-- - gdb/testsuite/lib/gdb-utils.exp | 5 +++++ - 2 files changed, 11 insertions(+), 2 deletions(-) - -diff --git a/gdb/Makefile.in b/gdb/Makefile.in -index 68e10cf47d8..f742eb5d009 100644 ---- a/gdb/Makefile.in -+++ b/gdb/Makefile.in -@@ -1971,6 +1971,10 @@ check-parallel: force - $(MAKE) $(TARGET_FLAGS_TO_PASS) check-parallel; \ - else true; fi - -+testsuite.lockdir: force -+ rm -rf $@ -+ mkdir -p $@ -+ - # The idea is to parallelize testing of multilibs, for example: - # make -j3 check//sh-hms-sim/{-m1,-m2,-m3,-m3e,-m4}/{,-nofpu} - # will run 3 concurrent sessions of check, eventually testing all 10 -@@ -1979,7 +1983,7 @@ check-parallel: force - # used, this rule will harmlessly fail to match. Used FORCE_PARALLEL to - # prevent serialized checking due to the passed RUNTESTFLAGS. - # FIXME: use config.status --config not --version, when available. --check//%: force -+check//%: force testsuite.lockdir - @if [ -f testsuite/config.status ]; then \ - rootme=`pwd`; export rootme; \ - rootsrc=`cd $(srcdir); pwd`; export rootsrc; \ -@@ -1997,7 +2001,7 @@ check//%: force - ); \ - else :; fi && cd $$testdir && \ - $(MAKE) $(TARGET_FLAGS_TO_PASS) \ -- RUNTESTFLAGS="--target_board=$$variant $(RUNTESTFLAGS)" \ -+ RUNTESTFLAGS="GDB_LOCK_DIR=$$rootme/testsuite.lockdir --target_board=$$variant $(RUNTESTFLAGS)" \ - FORCE_PARALLEL=$(if $(FORCE_PARALLEL),1,$(if $(RUNTESTFLAGS),,1)) \ - "$$target"; \ - else true; fi -diff --git a/gdb/testsuite/lib/gdb-utils.exp b/gdb/testsuite/lib/gdb-utils.exp -index cfaa7905997..7fd613e0b8f 100644 ---- a/gdb/testsuite/lib/gdb-utils.exp -+++ b/gdb/testsuite/lib/gdb-utils.exp -@@ -180,6 +180,11 @@ proc lock_file_release {info} { - # Return directory where we keep lock files. - - proc lock_dir {} { -+ if { [info exists ::GDB_LOCK_DIR] } { -+ # When using check//. -+ return $::GDB_LOCK_DIR -+ } -+ - return [make_gdb_parallel_path cache] - } - --- -2.35.3 - diff --git a/gdb-testsuite-use-unique-portnum-in-parallel-testing.patch b/gdb-testsuite-use-unique-portnum-in-parallel-testing.patch deleted file mode 100644 index c9b5ee4..0000000 --- a/gdb-testsuite-use-unique-portnum-in-parallel-testing.patch +++ /dev/null @@ -1,102 +0,0 @@ -From c8bf6704e64be92816527e9f3f3b582046e214c9 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Sat, 4 May 2024 10:41:09 +0200 -Subject: [PATCH 21/48] [gdb/testsuite] Use unique portnum in parallel testing - -When instrumenting get_portnum using: -... -puts "PORTNUM: $res" -... -and running: -... -$ cd build/gdb -$ make check-parallel -j2 TESTS=gdb.server/*.exp -... -we run into: -... -Running gdb.server/abspath.exp ... -PORTNUM: 2345 -... -and: -... -Running gdb.server/bkpt-other-inferior.exp ... -PORTNUM: 2345 -... - -This is because the test-cases are run in independent runtest invocations. - -Fix this by handling the parallel case in get_portnum using: -- a file $objdir/cache/portnum to keep the portnum variable, and -- a file $objdir/cache/portnum.lock to serialize access to it. - -Tested on aarch64-linux. - -Approved-By: Tom Tromey ---- - gdb/testsuite/lib/gdbserver-support.exp | 47 ++++++++++++++++++++----- - 1 file changed, 38 insertions(+), 9 deletions(-) - -diff --git a/gdb/testsuite/lib/gdbserver-support.exp b/gdb/testsuite/lib/gdbserver-support.exp -index 4f7effaacf7..a3cccf54a72 100644 ---- a/gdb/testsuite/lib/gdbserver-support.exp -+++ b/gdb/testsuite/lib/gdbserver-support.exp -@@ -141,18 +141,47 @@ proc get_portnum {} { - # starting at $initial_portnum, to avoid conflicts with hung ports. - set initial_portnum 2345 - -- # Currently available port number. -- gdb_persistent_global portnum -+ if { ![info exists ::GDB_PARALLEL] } { -+ # Sequential case. - -- # Initialize, if necessary. -- if { ![info exists portnum] } { -- set portnum $initial_portnum -+ # Currently available port number. -+ gdb_persistent_global portnum -+ -+ # Initialize, if necessary. -+ if { ![info exists portnum] } { -+ set portnum $initial_portnum -+ } -+ -+ # Return currently available port number, and update it. -+ set res $portnum -+ incr portnum -+ return $res -+ } -+ -+ # Parallel case. -+ with_lock portnum.lock { -+ # Keep portnum file alongside the lock that guards it. -+ set portnum_file [lock_dir]/portnum -+ -+ if { [file exists $portnum_file] } { -+ set fd [open $portnum_file r] -+ set portnum [read $fd] -+ close $fd -+ -+ set portnum [string trim $portnum] -+ } else { -+ # Initialize. -+ set portnum $initial_portnum -+ } -+ -+ set next_portnum [expr $portnum + 1] -+ -+ set fd [open $portnum_file w] -+ puts $fd $next_portnum -+ close $fd - } - -- # Return currently available port number, and update it. -- set res $portnum -- incr portnum -- return $res -+ return $portnum - } - - # Locate the gdbserver binary. Returns "" if gdbserver could not be found. --- -2.35.3 - diff --git a/gdb-tui-allow-command-window-of-1-or-2-lines.patch b/gdb-tui-allow-command-window-of-1-or-2-lines.patch deleted file mode 100644 index c67b949..0000000 --- a/gdb-tui-allow-command-window-of-1-or-2-lines.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 02616ce7c5571e5b2680cad52f8c58b27f77b2a5 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Thu, 9 Nov 2023 09:04:39 +0100 -Subject: [PATCH 4/6] [gdb/tui] Allow command window of 1 or 2 lines - -When starting TUI in a terminal with 2 lines (likewise with 1 line): -... -$ echo $LINES -2 -$ gdb -q -tui -... -we run into this assert in tui_apply_current_layout: -... - /* This should always be made visible by a layout. */ - gdb_assert (TUI_CMD_WIN != nullptr); -... - -The problem is that for the command window: -- the minimum height is 3 (the default), but -- the maximum height is only 2 because there are only 2 lines. - -This discrepancy eventually leads to a call to newwin in make_window with: -... -(gdb) p height -$1 = 3 -(gdb) p width -$2 = 66 -(gdb) p y -$3 = -1 -(gdb) p x -$4 = 0 -(gdb) -... -which results in a nullptr, which eventually triggers the assert. - -The easiest way to fix this is to change the minimum height of the command -window to 1. However, that would also change behaviour for the case that the -screen size is 3 lines or more. For instance, in gdb.tui/winheight.exp the -number of lines in the terminal is 24, and the test-case checks that the user -cannot increase the source window height to the point that the command window -height would be less than 3. - -Fix this by calculating the minimum height of the command window as follows: -- the default (3) if max_height () allows it, and -- max_height () otherwise. - -Tested on x86_64-linux. - -PR tui/31044 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31044 ---- - gdb/tui/tui-command.h | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/gdb/tui/tui-command.h b/gdb/tui/tui-command.h -index f6842880bb2..e8c96ecee30 100644 ---- a/gdb/tui/tui-command.h -+++ b/gdb/tui/tui-command.h -@@ -57,6 +57,18 @@ struct tui_cmd_window : public tui_win_info - /* The command window can't be made invisible. */ - } - -+ /* Compute the minimum height of this window. */ -+ virtual int min_height () const override -+ { -+ int preferred_min = tui_win_info::min_height (); -+ int max = max_height (); -+ /* If there is enough space to accommodate the preferred minimum height, -+ use it. Otherwise, use as much as possible. */ -+ return (preferred_min <= max -+ ? preferred_min -+ : max); -+ } -+ - int start_line = 0; - - protected: --- -2.35.3 - diff --git a/gdb-tui-fix-resizing-of-terminal-to-1-or-2-lines.patch b/gdb-tui-fix-resizing-of-terminal-to-1-or-2-lines.patch deleted file mode 100644 index d5a084b..0000000 --- a/gdb-tui-fix-resizing-of-terminal-to-1-or-2-lines.patch +++ /dev/null @@ -1,147 +0,0 @@ -From c55a452eaf9390d5659d3205f762aa2cb84511e1 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Thu, 9 Nov 2023 09:05:01 +0100 -Subject: [PATCH 6/6] [gdb/tui] Fix resizing of terminal to 1 or 2 lines - -When starting TUI in a terminal with 3 lines: -... -$ echo $LINES -3 -$ gdb -q -tui -... -and resizing the terminal to 2 lines we run into a segfault. - -The problem is that for the source window: -- the minimum height is 3 (the default), but -- the maximum height is only 2 because there are only 2 lines. - -This discrepancy eventually leads to a call to newwin in make_window with: -... -(gdb) p height -$1 = 3 -(gdb) p width -$2 = 56 -(gdb) p y -$3 = -1 -(gdb) p x -$4 = 0 -... -which results in a nullptr. - -This violates the assumption here in tui_apply_current_layout: -.... - /* Get the new list of currently visible windows. */ - std::vector new_tui_windows; - applied_layout->get_windows (&new_tui_windows); -... -that get_windows only returns visible windows, which leads to tui_windows -holding a dangling pointer, which results in the segfault. - -Fix this by: -- making sure get_windows only returns visible windows, and -- detecting the situation and dropping windows from the layout if - there's no room for them. - -Tested on x86_64-linux. - -PR tui/31044 -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31044 ---- - gdb/testsuite/gdb.tui/resize.exp | 9 +++++++++ - gdb/tui/tui-layout.c | 22 ++++++++++++++++++++-- - gdb/tui/tui-layout.h | 6 +++++- - 3 files changed, 34 insertions(+), 3 deletions(-) - -diff --git a/gdb/testsuite/gdb.tui/resize.exp b/gdb/testsuite/gdb.tui/resize.exp -index 60d5116886b..e15f8a2f507 100644 ---- a/gdb/testsuite/gdb.tui/resize.exp -+++ b/gdb/testsuite/gdb.tui/resize.exp -@@ -39,3 +39,12 @@ Term::check_contents "source at startup" "\\|.*21 *return 0" - - Term::resize 40 90 - Term::check_box "source box after resize" 0 0 90 26 -+ -+# Check that resizing to less than 3 lines doesn't cause problems. -+foreach lines { 2 1 } { -+ with_test_prefix lines=$lines { -+ Term::resize $lines 90 0 -+ Term::wait_for "" -+ Term::check_region_contents "has prompt" 0 0 90 $lines "$gdb_prompt" -+ } -+} -diff --git a/gdb/tui/tui-layout.c b/gdb/tui/tui-layout.c -index 27abee02087..362c1447910 100644 ---- a/gdb/tui/tui-layout.c -+++ b/gdb/tui/tui-layout.c -@@ -442,6 +442,13 @@ tui_layout_window::apply (int x_, int y_, int width_, int height_, - width = width_; - height = height_; - gdb_assert (m_window != nullptr); -+ if (width == 0 || height == 0) -+ { -+ /* The window was dropped, so it's going to be deleted, reset the -+ soon to be dangling pointer. */ -+ m_window = nullptr; -+ return; -+ } - m_window->resize (height, width, x, y); - } - -@@ -823,6 +830,7 @@ tui_layout_split::apply (int x_, int y_, int width_, int height_, - int available_size = m_vertical ? height : width; - int last_index = -1; - int total_weight = 0; -+ int prev = -1; - for (int i = 0; i < m_splits.size (); ++i) - { - bool cmd_win_already_exists = TUI_CMD_WIN != nullptr; -@@ -854,6 +862,14 @@ tui_layout_split::apply (int x_, int y_, int width_, int height_, - info[i].max_size = info[i].min_size; - } - -+ if (info[i].min_size > info[i].max_size) -+ { -+ /* There is not enough room for this window, drop it. */ -+ info[i].min_size = 0; -+ info[i].max_size = 0; -+ continue; -+ } -+ - if (info[i].min_size == info[i].max_size) - available_size -= info[i].min_size; - else -@@ -864,10 +880,12 @@ tui_layout_split::apply (int x_, int y_, int width_, int height_, - - /* Two adjacent boxed windows will share a border, making a bit - more size available. */ -- if (i > 0 -- && m_splits[i - 1].layout->last_edge_has_border_p () -+ if (prev != -1 -+ && m_splits[prev].layout->last_edge_has_border_p () - && m_splits[i].layout->first_edge_has_border_p ()) - info[i].share_box = true; -+ -+ prev = i; - } - - /* If last_index is set then we have a window that is not of a fixed -diff --git a/gdb/tui/tui-layout.h b/gdb/tui/tui-layout.h -index 206f1117445..ec013a3f051 100644 ---- a/gdb/tui/tui-layout.h -+++ b/gdb/tui/tui-layout.h -@@ -185,7 +185,11 @@ class tui_layout_window : public tui_layout_base - /* See tui_layout_base::get_windows. */ - void get_windows (std::vector *windows) override - { -- windows->push_back (m_window); -+ if (m_window != nullptr && m_window->is_visible ()) -+ { -+ /* Only get visible windows. */ -+ windows->push_back (m_window); -+ } - } - - protected: --- -2.35.3 - diff --git a/gdb-tui-fix-wmaybe-uninitialized-in-tui_find_disasse.patch b/gdb-tui-fix-wmaybe-uninitialized-in-tui_find_disasse.patch deleted file mode 100644 index 01738b0..0000000 --- a/gdb-tui-fix-wmaybe-uninitialized-in-tui_find_disasse.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 0f2bdd8648e47e10334f8cc8e47b277d4064d0a2 Mon Sep 17 00:00:00 2001 -From: Tom de Vries -Date: Mon, 13 Nov 2023 09:31:20 +0100 -Subject: [PATCH 3/6] [gdb/tui] Fix Wmaybe-uninitialized in - tui_find_disassembly_address -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When building gdb with -O2, we run into: -... -gdb/tui/tui-disasm.c: In function ‘CORE_ADDR tui_find_disassembly_address \ - (gdbarch*, CORE_ADDR, int)’: -gdb/tui/tui-disasm.c:293:7: warning: ‘last_addr’ may be used uninitialized \ - in this function [-Wmaybe-uninitialized] - if (last_addr < pc) - ^~ -... - -The warning triggers since commit 72535eb14bd ("[gdb/tui] Fix segfault in -tui_find_disassembly_address"). - -Fix the warning by ensuring that last_addr is initialized at the point of -use: -... -+ last_addr = asm_lines.back ().addr; - if (last_addr < pc) -... - -Tested on x86_64-linux. ---- - gdb/tui/tui-disasm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gdb/tui/tui-disasm.c b/gdb/tui/tui-disasm.c -index 03c78aa1291..bbbc92c8183 100644 ---- a/gdb/tui/tui-disasm.c -+++ b/gdb/tui/tui-disasm.c -@@ -281,7 +281,6 @@ tui_find_disassembly_address (struct gdbarch *gdbarch, CORE_ADDR pc, int from) - /* Take the best possible match we have. */ - new_low = *possible_new_low; - next_addr = tui_disassemble (gdbarch, asm_lines, new_low, max_lines); -- last_addr = asm_lines.back ().addr; - gdb_assert (asm_lines.size () >= max_lines); - } - -@@ -290,6 +289,7 @@ tui_find_disassembly_address (struct gdbarch *gdbarch, CORE_ADDR pc, int from) - We keep the disassembled instructions in the 'lines' window - and shift it downward (increasing its addresses). */ - int pos = max_lines - 1; -+ last_addr = asm_lines.back ().addr; - if (last_addr < pc) - do - { --- -2.35.3 - diff --git a/gdb.changes b/gdb.changes index 6d21d78..6ce9730 100644 --- a/gdb.changes +++ b/gdb.changes @@ -1,25 +1,76 @@ ------------------------------------------------------------------- -Thu Mar 13 14:25:52 UTC 2025 - Tom de Vries +Thu Mar 27 12:24:34 UTC 2025 - Tom de Vries + +- Patches added: + * gdb-testsuite-fix-gdb.threads-access-mem-running-thr.patch + +------------------------------------------------------------------- +Wed Mar 26 09:30:19 UTC 2025 - Tom de Vries + +- Patches updated (bsc#1240047): + * gdb-add-rpm-suggestion-script-suse.patch +- Patches added (bsc#1240047): + * gdb-6.6-buildid-locate-tests-suse.patch + +------------------------------------------------------------------- +Tue Mar 25 11:25:52 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ 8d5adc7. +- Maintenance script import-fedora.sh: + * Remove + gdb-6.6-buildid-locate-misleading-warning-missing-debuginfo-rhbz981154.patch + and gdb-remove-use-of-py-isascii from skip_patches. +- Patches dropped: + * gdb-6.6-buildid-locate-solib-missing-ids.patch + * gdb-6.6-buildid-locate.patch + * gdb-python-avoid-depending-on-the-curses-library.patch + * gdb-6.6-buildid-locate-rpm-suse.patch +- Patches added: + * gdb-6.6-buildid-locate-tests.patch + * gdb-add-deprecated-settings-py-script.patch + * gdb-backport-buildid-related-changes.patch + * gdb-remove-qnx-neutrino-support.patch + * fixup-gdb-add-rpm-suggestion-script.patch + * gdb-add-rpm-suggestion-script-suse.patch + * gdb-build-fix-unused-var-in-corelow.c.patch +- Patches updated: + * gdb-add-rpm-suggestion-script.patch + +------------------------------------------------------------------- +Tue Mar 25 08:08:37 UTC 2025 - Tom de Vries + +- Mention bsc#1216488. + +------------------------------------------------------------------- +Thu Mar 13 10:51:28 UTC 2025 - Tom de Vries + +- Patches added: + * gdb-record-fix-out-of-bounds-write-in-aarch64_record.patch + * gdb-tdep-backport-i386_canonicalize_syscall-rewrite-.patch +- Maintenance script qa.sh: + * Remove PR32770 kfail. + * Move PR32678 from kfail_i586 to kfail_factory. + +------------------------------------------------------------------- +Tue Mar 11 06:17:54 UTC 2025 - Tom de Vries + +- Maintenance script qa.sh: + * Add PR32688 and PR32770 kfails. +- Patches added: + * gdb-testsuite-fix-gdb.base-step-over-syscall.exp-with-m32-for-amd.patch + * gdb-testsuite-fix-gdb.base-step-over-syscall.exp-with-glibc-2-41.patch +- Patches dropped: + * gdb-testsuite-fix-gdb.base-step-over-syscall.exp-with-m32-amd-case.patch + +------------------------------------------------------------------- +Fri Mar 7 21:55:47 UTC 2025 - Tom de Vries + +- Drop "BuildRequires: libgo23". + +------------------------------------------------------------------- +Fri Mar 7 14:01:38 UTC 2025 - Tom de Vries - Patches added (jsc#PED-10305): - * s390-make-operand-table-indices-relative-to-each-oth.patch - * s390-align-optional-operand-definition-to-specs.patch - * s390-add-missing-extended-mnemonics.patch - * s390-correct-prno-instruction-name.patch - * fix-building-for-the-s390-target-with-clang.patch - * s390-support-for-jump-visualization-in-disassembly.patch - * s390-align-letter-case-of-instruction-descriptions.patch - * s390-enhance-error-handling-in-s390-mkopc.patch - * s390-use-safe-string-functions-and-length-macros-in-.patch - * s390-optionally-print-instruction-description-in-dis.patch - * s390-add-suffix-to-conditional-branch-instruction-de.patch - * add-note-to-translators-not-to-translate-z-architect.patch - * s390-whitespace-fixes-in-conditional-branch-flavor-d.patch - * s390-use-proper-string-lengths-when-parsing-opcode-t.patch - * s390-add-test-cases-for-base-index-register-0.patch - * s390-warn-when-register-name-type-does-not-match-ope.patch - * s390-print-base-register-0-as-0-in-disassembly.patch - * s390-flag-conditional-branch-relative-insns-as-condj.patch * s390-align-opcodes-to-lower-case.patch * s390-simplify-dis-assembly-of-insn-operands-with-con.patch * s390-relax-risbg-n-z-risb-h-l-gz-rns-ros-rxs-bgt-ope.patch @@ -31,6 +82,662 @@ Thu Mar 13 14:25:52 UTC 2025 - Tom de Vries * s390-treat-addressing-operand-sequence-as-one-in-dis.patch * gdb-testsuite-add-gdb.arch-s390-disassemble.exp.patch +------------------------------------------------------------------- +Tue Feb 18 06:58:58 UTC 2025 - Tom de Vries + +- Maintenance script qa.sh: + * Add PR32712 kfail. + +------------------------------------------------------------------- +Thu Feb 13 15:09:04 UTC 2025 - Tom de Vries + +- Mention changes in GDB 15: + * The MPX commands "show/set mpx bound" have been deprecated, as + Intel listed MPX as removed in 2019. + * GDB index now contains information about the main function. + * This speeds up startup when it is being used for some large + binaries. + * On hosts where threading is available, DWARF reading is now + done in the background, resulting in faster startup. This can + be controlled using "maint set dwarf synchronous". + * Changed commands: + * disassemble: + Attempting to use both the 'r' and 'b' flags with the + disassemble command will now give an error. Previously the + 'b' flag would always override the 'r' flag. + * gcore, generate-core-file: + GDB now generates sparse core files, on systems that support + it. + * maintenance info line-table: + Add an EPILOGUE-BEGIN column to the output of the command. + It indicates if the line is considered the start of the + epilogue, and thus a point at which the frame can be + considered destroyed. + * set unwindonsignal on|off, show unwindonsignal: + These commands are now aliases for the new + set/show unwind-on-signal. + * target record-full: + This command now gives an error if any unexpected arguments + are found after the command. + * list .: + When using the command "list ." in a location that has no + debug information or no file loaded, GDB now says that there + is no debug information to print lines. This makes it more + obvious that there is no information, as opposed to implying + there is no inferior loaded. + * New commands: + * info missing-debug-handler: + List all the registered missing debug handlers. + * enable missing-debug-handler LOCUS HANDLER, + disable missing-debug-handler LOCUS HANDLER: + Enable or disable a missing debug handler with a name + matching the regular expression HANDLER, in LOCUS. + LOCUS can be 'global' to operate on global missing debug + handler, 'progspace' to operate on handlers within the + current program space, or can be a regular expression which + is matched against the filename of the primary executable in + each program space. + * maintenance info linux-lwps: + List all LWPs under control of the linux-nat target. + * set remote thread-options-packet, + show remote thread-options-packet: + Set/show the use of the thread options packet. + * set direct-call-timeout SECONDS, show direct-call-timeout, + set indirect-call-timeout SECONDS, + show indirect-call-timeout: + These new settings can be used to limit how long GDB will + wait for an inferior function call to complete. The direct + timeout is used for inferior function calls from e.g. 'call' + and 'print' commands, while the indirect timeout is used for + inferior function calls from within a conditional breakpoint + expression. + The default for the direct timeout is unlimited, while the + default for the indirect timeout is 30 seconds. + These timeouts will only have an effect for targets that are + operating in async mode. For non-async targets the timeouts + are ignored, GDB will wait indefinitely for an inferior + function to complete, unless interrupted by the user using + Ctrl-C. + * set unwind-on-timeout on|off, show unwind-on-timeout: + These commands control whether GDB should unwind the stack + when a timeout occurs during an inferior function call. The + default is off, in which case the inferior will remain in + the frame where the timeout occurred. When on, GDB will + unwind the stack removing the dummy frame that was added for + the inferior call, and restoring the inferior state to how + it was before the inferior call started. + * set unwind-on-signal on|off, show unwind-on-signal: + These new commands replaces the existing set/show + unwindonsignal. The old command is maintained as an alias. + * New features in the GDB remote stub, GDBserver: + * The --remote-debug and --event-loop-debug command line + options have been removed. + * The --debug command line option now takes an optional comma + separated list of components to emit debug for. The + currently supported components are: all, threads, + event-loop, and remote. If no components are given then + threads is assumed. + * The 'monitor set remote-debug' and 'monitor set + event-loop-debug' command have been removed. + * The 'monitor set debug 0|1' command has been extended to + take a component name, e.g.: 'monitor set debug COMPONENT + off|on'. Possible component names are: all, threads, + event-loop, and remote. + * Python API: + * New function gdb.notify_mi(NAME, DATA), that emits custom + GDB/MI async notification. + * New read/write attribute gdb.Value.bytes that contains a + bytes object holding the contents of this value. + * New module gdb.missing_debug that facilitates dealing with + objfiles that are missing any debug information. + * New function gdb.missing_debug.register_handler that can + register an instance of a sub-class of + gdb.missing_debug.MissingDebugInfo as a handler for objfiles + that are missing debug information. + * New class gdb.missing_debug.MissingDebugInfo which can be + sub-classed to create handlers for objfiles with missing + debug information. + * Stop events now have a "details" attribute that holds a + dictionary that carries the same information as an MI + "*stopped" event. + * New function gdb.interrupt(), that interrupts GDB as if the + user typed control-c. + * New gdb.InferiorThread.ptid_string attribute. This + read-only attribute contains the string that appears in the + 'Target Id' column of the 'info threads' command output. + * It is no longer possible to create new gdb.Progspace object + using 'gdb.Progspace()', this will result in a TypeError. + Progspace objects can still be obtained through calling + other API functions, for example 'gdb.current_progspace()'. + * User defined attributes can be added to a gdb.Inferior + object, these will be stored in the object's new + Inferior.__dict__ attribute. + * User defined attributes can be added to a gdb.InferiorThread + object, these will be stored in the object's new + InferiorThread.__dict__ attribute. + * New constants gdb.SYMBOL_TYPE_DOMAIN, + gdb.SYMBOL_FUNCTION_DOMAIN, and gdb.SEARCH_*_DOMAIN + corresponding to all the existing symbol domains. Symbol + lookup can now search in multiple domains at once, and can + also narrowly search for just a type or function. + * Debugger Adapter Protocol changes: + * GDB now emits the "process" event. + * GDB now supports the "cancel" request. + * The "attach" request now supports specifying the program. + * New command "set debug dap-log-level" controls DAP logging. + * The "set debug dap-log-file" command is now documented. + This command was available in GDB 14 but not documented. + * Guile API: + * New constants SYMBOL_TYPE_DOMAIN, SYMBOL_FUNCTION_DOMAIN, + and SEARCH_*_DOMAIN corresponding to all the existing symbol + domains. Symbol lookup can now search in multiple domains + at once, and can also narrowly search for just a type or + function. + * Remote packets: + * New stop reason clone: + Indicates that a clone system call was executed. + * New remote packets: + * QThreadOptions: + Enable/disable optional event reporting, on a per-thread + basis. Currently supported options are + GDB_THREAD_OPTION_CLONE, to enable clone event reporting, + and GDB_THREAD_OPTION_EXIT to enable thread exit event + reporting. + * QThreadOptions in qSupported: + * The qSupported packet allows GDB to inform the stub it + supports the QThreadOptions packet, and the qSupported + response can contain the set of thread options the remote + stub supports. + * qIsAddressTagged: + This new packet allows GDB to query the stub about a given + address to check if it is tagged or not. Many memory + tagging-related GDB commands need to perform this check + before they read/write the allocation tag related to an + address. Currently, however, this is done through a 'vFile' + request to read the file /proc//smaps and check if the + address is in a region reported as memory tagged. Since not + all targets have a notion of what the smaps file is about, + this new packet provides a more generic way to perform such + a check. + +------------------------------------------------------------------- +Wed Feb 12 06:28:50 UTC 2025 - Tom de Vries + +- Maintenance script qa.sh: + * Fix 16.0 handling. +- Patches added: + * gdb-testsuite-fix-gdb.python-py-format-string.exp-wi.patch + * gdb-testsuite-fix-gdb.python-py-mi-cmd.exp-with-pyth.patch + * gdb-testsuite-fix-gdb.ada-mi_task_arg.exp-on-arm-lin.patch + * gdb-testsuite-fix-regexp-in-gdb.ada-mi_var_access.ex.patch + * gdb-testsuite-check-gnatmake-version-in-gdb.ada-scal.patch + * gdb-testsuite-fix-gdb.arch-arm-pseudo-unwind.exp-wit.patch + * gdb-symtab-fix-target-type-of-complex-long-double-on.patch + * gdb-testsuite-don-t-use-set-auto-solib-add-off.patch + * gdb-tdep-fix-arm-thumb2-hw-breakpoint.patch + * gdb-testsuite-fix-gdb.cp-m-static.exp-on-arm.patch + * gdb-testsuite-fix-gdb.dwarf2-dw2-fixed-point.exp-on-.patch + * gdb-testsuite-fix-gdb.dwarf2-dw2-lines.exp-on-arm-li.patch + * gdb-exp-fix-gdb.fortran-intrinsics.exp-fail-on-arm.patch + * gdb-tdep-handle-sycall-statx-for-arm-linux.patch + * gdb-tdep-fix-recording-of-t1-push.patch + * gdb-tdep-handle-syscall-clock_gettime64-for-arm-linu.patch + * fix-gdb.dwarf2-shortpiece.exp-on-s390x.patch + * handle-address-class-annotation-for-s390x-in-some-te.patch + * fix-gdb.dap-step-out.exp-on-s390x.patch + * use-setvariable-in-gdb.dap-scopes.exp.patch + * fix-gdb.base-finish-pretty.exp-on-s390x.patch + * fix-gdb.base-readnever.exp-on-s390x.patch + * add-dwarf_expr_piece.op.patch + * add-gdbarch_dwarf2_reg_piece_offset-hook.patch + * fix-gdb.base-store.exp-on-s390x.patch + * fix-gdb.ada-o2_float_param.exp-on-s390x-linux.patch + * gdb-testsuite-fix-gdb.base-branch-to-self.exp-on-arm.patch + * gdb-tdep-fix-gdb.cp-non-trivial-retval.exp-on-riscv6.patch + * gdb-testsuite-fix-gdb.cp-non-trivial-retval.exp-on-a.patch + * gdb-testsuite-fix-gdb.rust-completion.exp-timeout-on.patch + * gdb-testsuite-require-supports_process_record-in-gdb.patch + * gdb-testsuite-fix-regexp-in-gdb.arch-i386-disp-step-.patch + * gdb-testsuite-fix-gdb.arch-arm-single-step-kernel-he.patch + * gdb-testsuite-fix-gdb.python-py-format-address.exp-o.patch + * gdb-testsuite-fix-gdb.arch-riscv-tdesc-regs.exp.patch + * gdb-testsuite-fix-gdb.base-list-dot-nodebug-and-make.patch + * gdb-testsuite-fix-gdb.base-list-dot-nodebug.exp-on-o.patch + * gdb-testsuite-fix-gdb.base-empty-host-env-vars.exp.patch + * gdb-prune-inferior-after-switching-inferior.patch + * gdb-testsuite-use-nostdlib-in-gdb.base-list-dot-node.patch + * gdb-testsuite-fix-timeout-in-gdb.mi-mi-multi-command.patch + * gdb-testsuite-require-can_spawn_for_attach-in-gdb.ba.patch + * fixup-gdb-6.5-gcore-buffer-limit-test.patch + * gdb-testsuite-fix-gdb.ada-big_packed_array.exp-on-s3.patch + * gdb-testsuite-fix-gdb.ada-convvar_comp.exp-on-s390x-.patch + * gdb-testsuite-fix-regexp-in-gdb.threads-stepi-over-c.patch + +------------------------------------------------------------------- +Tue Feb 11 12:25:44 UTC 2025 - Tom de Vries + +- Maintenance script qa.sh: + * Add kfail for PR32678. + * Add kfail for missing g++ on SLE-12. + * Drop Leap 15.5, add 16.0. + * Move PR32167 kfail from kfail_sle12 to kfail, and extend + pattern. +- Use gcc 11 instead gcc 9 for SLE-12. +- Maintenance script qa-local.sh: + * Drop Leap 15.5, add 16.0. + +------------------------------------------------------------------- +Thu Feb 6 08:35:47 UTC 2025 - Tom de Vries + +- Patches dropped: + * gdb-rhbz1261564-aarch64-hw-watchpoint-test.patch + * gdb-test-bt-cfi-without-die.patch + * fixup-gdb-rhbz1261564-aarch64-hw-watchpoint-test.pat.patch + * fixup-gdb-test-bt-cfi-without-die.patch +- Maintenance script import-fedora.sh: + * Add gdb-rhbz1261564-aarch64-hw-watchpoint-test.patch and + gdb-test-bt-cfi-without-die.patch to skip_patches. + +------------------------------------------------------------------- +Thu Feb 6 08:14:25 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ a2f2e9e. +- Patches dropped: + * gdb-6.5-bz243845-stale-testing-zombie-test.patch + * fixup-gdb-6.5-bz243845-stale-testing-zombie-test.patch + +------------------------------------------------------------------- +Thu Feb 6 08:08:52 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ 1116b36. +- Patches dropped: + * gdb-test-dw2-aranges.patch + * fixup-gdb-test-dw2-aranges.patch + +------------------------------------------------------------------- +Thu Feb 6 08:04:34 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ 7c66c1c. +- Patches dropped: + * gdb-6.6-testsuite-timeouts.patch + +------------------------------------------------------------------- +Thu Feb 6 07:59:02 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ 2294280. +- Patches dropped: + * gdb-simultaneous-step-resume-breakpoint-test.patch + +------------------------------------------------------------------- +Fri Jan 31 15:07:27 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ 926c064 (gdb 15.2). +- Patches dropped: + * gdb-6.5-section-num-fixup-test.patch + * gdb-rhbz1007614-memleak-infpy_read_memory-test.patch +- Maintenance script qa-local.sh: + * Update version to 15.2. + +------------------------------------------------------------------- +Thu Jan 30 15:31:30 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ 4b0a2e1. +- Patches added: + * gdb-catchpoint-re-set.patch + +------------------------------------------------------------------- +Thu Jan 30 15:25:52 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ d8b64d9. +- Patches dropped: + * gdb-6.6-bz229517-gcore-without-terminal.patch + +------------------------------------------------------------------- +Thu Jan 30 15:20:59 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ a93b826. +- Patches dropped: + * gdb-rhbz947564-findvar-assertion-frame-failed-testcase.patch +- Maintenance script import-fedora.sh: + * Add gdb-remove-use-of-py-isascii to skip_patches. + * Remove gdb-6.7-ppc-clobbered-registers-O2-test.patch from + skip_patches. + +------------------------------------------------------------------- +Thu Jan 30 12:32:38 UTC 2025 - Tom de Vries + +- Always BuildRequire gcc-c++ to fix missing testing compiler on + SLE-12. +- Patches added: + * gdb-testsuite-handle-unordered-dict-in-gdb.python-py.patch +- Maintenance script qa.sh: + * Add PR32167 kfail. + +------------------------------------------------------------------- +Wed Jan 29 10:52:26 UTC 2025 - Tom de Vries + +- Maintenance script qa.sh: + * Extend SLE-12 -static unix/-fPIE/-fpie kfails. + * Extend ppc64le watchpoint kfail. + * Extend PR29405 kfail. +- Patches added: + * gdb-testsuite-fix-gdb.threads-leader-exit-attach.exp.patch + * gdb-testsuite-use-c-flag-in-c-test-cases.patch +------------------------------------------------------------------- +Mon Jan 27 06:00:38 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ a8e0b3d (gdb 15.1). +- Use gcc-9 for SLE-12 (default gcc 4.8.5 doesn't support C++17). +- Maintenance script qa-local.sh: + * Update version to 15.1. +- Maintenance script qa.sh: + * Add kfails due to gcc 4.8.5 DW_TAG_lexical_block oddity. + * Extend PR24845 kfails. + * Add PR31721 and PR32608 kfails. +- Patches added: + * gdb-guile-use-scm_debug_typing_strictness-0.patch + * gdb-doc-fix-gdb.unwinder-docs.patch + * gdb-doc-fix-qisaddresstagged-anchor.patch + * gdb-doc-fix-standard-replies-xref.patch + * gdb-testsuite-fix-gdb_py_module_available-for-python.patch + * gdb-testsuite-fix-another-regexp-in-gdb.threads-step.patch + * gdb-testsuite-fix-timeouts-in-gdb.threads-step-over-.patch +- Patches updated: + * gdb-6.3-gstack-20050411.patch + * gdb-6.6-buildid-locate-solib-missing-ids.patch + * gdb-6.6-buildid-locate.patch + * gdb-add-rpm-suggestion-script.patch + * gdb-gcore-bash.patch + * gdb-python-avoid-depending-on-the-curses-library.patch + * gdb-python-finishbreakpoint-update.patch +- Patches dropped: + * gdb-add-missing-debug-ext-lang-hook.patch + * gdb-add-missing-debug-info-python-hook.patch + * gdb-do-not-import-py-curses-ascii-module.patch + * gdb-ftbs-swapped-calloc-args.patch + * gdb-handle-no-python-gdb-module.patch + * gdb-merge-debug-symbol-lookup.patch + * gdb-refactor-find-and-add-separate-symbol-file.patch + * gdb-reformat-missing-debug-py-file.patch + * gdb-remove-path-in-test-name.patch + * gdb-rhbz-2232086-cpp-ify-mapped-symtab.patch + * gdb-rhbz-2232086-generate-dwarf-5-index-consistently.patch + * gdb-rhbz-2232086-generate-gdb-index-consistently.patch + * gdb-rhbz-2232086-reduce-size-of-gdb-index.patch + * gdb-rhbz2232086-refactor-selftest-support.patch + * gdb-rhbz2250652-avoid-PyOS_ReadlineTState.patch + * gdb-rhbz2250652-gdbpy_gil.patch + * gdb-rhbz2261580-intrusive_list-assertion-fix.patch + * gdb-rhbz2277160-apx-disasm.patch + * gdb-rhel2295897-pre-read-DWZ-file-in-DWARF-reader.patch + * gdb-sync-coffread-with-elfread.patch + * gdb-remove-use-of-py-isascii + * change-gdb.base-examine-backwards.exp-for-aix.patch + * fix-regression-on-aarch64-linux-gdbserver.patch + * fix-the-gdb.ada-inline-section-gc.exp-test.patch + * fixup-powerpc-and-aarch64-fix-reverse-stepping-failu.patch + * gdb-arm-fix-epilogue-frame-id.patch + * gdb-arm-remove-thumb-bit-in-arm_adjust_breakpoint_ad.patch + * gdb-arm-remove-tpidruro-register-from-non-freebsd-ta.patch + * gdb-build-fix-gdbserver-linux-aarch64-low.cc-build.patch + * gdb-exp-fix-cast-handling-for-indirection.patch + * gdb-exp-fix-printing-of-out-of-bounds-struct-members.patch + * gdb-exp-redo-cast-handling-for-indirection.patch + * gdb-fix-heap-use-after-free-in-select_event_lwp.patch + * gdb-fix-segfault-in-for_each_block-part-1.patch + * gdb-fix-segfault-in-for_each_block-part-2.patch + * gdb-python-fix-gdb.python-py-disasm.exp-on-arm-linux.patch + * gdb-python-make-gdb.unwindinfo.add_saved_register-mo-fixup.patch + * gdb-python-make-gdb.unwindinfo.add_saved_register-mo.patch + * gdb-remote-fix-abort-on-remote_close_error.patch + * gdb-s390-add-arch14-record-replay-support.patch + * gdb-symtab-add-producer_is_gas.patch + * gdb-symtab-don-t-defer-backward-refs-inter-cu-intra-.patch + * gdb-symtab-factor-out-m_deferred_entries-usage.patch + * gdb-symtab-factor-out-m_die_range_map-usage.patch + * gdb-symtab-fix-dw_tag_inlined_subroutine-entries-in-.patch + * gdb-symtab-handle-nullptr-parent-in-parent_map-set_p.patch + * gdb-symtab-keep-track-of-all-parents-for-cooked-inde.patch + * gdb-symtab-keep-track-of-processed-dies-in-shard.patch + * gdb-symtab-refactor-condition-in-scan_attributes.patch + * gdb-symtab-resolve-deferred-entries-inter-shard-case.patch + * gdb-symtab-resolve-deferred-entries-intra-shard-case.patch + * gdb-symtab-work-around-gas-pr28629.patch + * gdb-symtab-work-around-pr-gas-29517-dwarf2-case.patch + * gdb-symtab-work-around-pr-gas-29517.patch + * gdb-symtab-workaround-pr-gas-31115.patch + * gdb-tdep-fix-catching-syscall-execve-exit-for-arm.patch + * gdb-tdep-fix-gdb.base-watch-bitfields.exp-on-aarch64.patch + * gdb-tdep-fix-gdb.base-watchpoint-running-on-arm-ppc6.patch + * gdb-tdep-fix-gdb.base-watchpoint-unaligned.exp-on-aa.patch + * gdb-tdep-fix-nr-array-elements-in-ppc64_aggregate_ca.patch + * gdb-tdep-fix-reverse-execution-of-ldr-immediate-t4.patch + * gdb-testsuite-add-gdb.dwarf2-backward-spec-inter-cu..patch + * gdb-testsuite-add-gdb.dwarf2-forward-spec-inter-cu.e.patch + * gdb-testsuite-add-missing-include-in-gdb.base-ctf-pt.patch + * gdb-testsuite-add-missing-include-in-gdb.base-rtld-s.patch + * gdb-testsuite-add-missing-includes-in-gdb.trace-coll.patch + * gdb-testsuite-add-missing-no-prompt-anchor-in-gdb.ba.patch + * gdb-testsuite-add-pr-gdb-26967-kfail-in-two-more-tes.patch + * gdb-testsuite-call-ldd-version-in-gdb.testsuite-dump.patch + * gdb-testsuite-factor-out-proc-get_portnum.patch + * gdb-testsuite-factor-out-proc-lock_dir.patch + * gdb-testsuite-factor-out-proc-with_lock.patch + * gdb-testsuite-fix-gdb.ada-verylong.exp-on-32-bit-tar.patch + * gdb-testsuite-fix-gdb.base-eh_return.exp.patch + * gdb-testsuite-fix-gdb.base-ending-run.exp-on-manjaro.patch + * gdb-testsuite-fix-gdb.base-list-no-debug.exp-on-debi.patch + * gdb-testsuite-fix-gdb.cp-namespace.exp-with-read1.patch + * gdb-testsuite-fix-gdb.dwarf2-dw2-gas-workaround.exp.patch + * gdb-testsuite-fix-gdb.mi-mi-dprintf.exp-with-read1.patch + * gdb-testsuite-fix-gdbserver-pid-in-gdb.server-server.patch + * gdb-testsuite-fix-gdb.server-server-connect.exp-for-.patch + * gdb-testsuite-fix-license-text-in-gdb.reverse-map-to.patch + * gdb-testsuite-fix-missing-return-type-in-gdb.linespe.patch + * gdb-testsuite-fix-regexp-in-vgdb_start.patch + * gdb-testsuite-fix-spurious-fails-with-examine-backwa.patch + * gdb-testsuite-fix-test-case-gdb.threads-attach-stopp.patch + * gdb-testsuite-fix-test-in-gdb.python-py-finish-break.patch + * gdb-testsuite-fix-typo-in-gdb.base-catch-syscall.exp.patch + * gdb-testsuite-fix-valgrind-tests-on-debian.patch + * gdb-testsuite-further-handle-long-filenames-in-gdb.b.patch + * gdb-testsuite-handle-core-without-build-id-in-gdb.ba.patch + * gdb-testsuite-handle-pac-marker.patch + * gdb-testsuite-make-gdb.base-solib-search.exp-more-ro.patch + * gdb-testsuite-make-portnum-a-persistent-global.patch + * gdb-testsuite-move-gpu-parallel.lock-to-cache-dir.patch + * gdb-testsuite-remove-spurious-in-save_vars.patch + * gdb-testsuite-reset-errcnt-and-warncnt-in-default_gd.patch + * gdb-testsuite-simplify-gdb.server-server-kill-python.patch + * gdb-testsuite-use-find_gnatmake-instead-of-gdb_find_.patch + * gdb-testsuite-use-more-progbits-for-arm.patch + * gdb-testsuite-use-unique-portnum-in-parallel-testing-check-slash-slash-case.patch + * gdb-testsuite-use-unique-portnum-in-parallel-testing.patch + * gdb-tui-allow-command-window-of-1-or-2-lines.patch + * gdb-tui-fix-resizing-of-terminal-to-1-or-2-lines.patch + * gdb-tui-fix-wmaybe-uninitialized-in-tui_find_disasse.patch + * make-pascal_language-print_type-handle-varstring-nul.patch + * powerpc-and-aarch64-fix-reverse-stepping-failure.patch + * powerpc-fix-test-gdb.ada-finish-large.exp.patch + * riscv-lrsc.patch + * rs6000-unwind-on-each-instruction-fix.patch + * s390-provide-ibm-z16-arch14-instruction-descriptions.patch + +------------------------------------------------------------------- +Sat Jan 25 09:24:00 UTC 2025 - Tom de Vries + +- Patches added: + * gdb-testsuite-record-less-in-gdb.reverse-time-revers.patch + * gdb-cli-print-at_hwcap3-and-at_hwcap4.patch + +------------------------------------------------------------------- +Fri Jan 24 15:15:38 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ a455470. +- Patches added: + * gdb-rhel2295897-pre-read-DWZ-file-in-DWARF-reader.patch +------------------------------------------------------------------- +Fri Jan 24 15:13:30 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ 62add57. +- Patches updated: + * gdb-add-rpm-suggestion-script.patch +------------------------------------------------------------------- +Fri Jan 24 15:10:23 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ 199e8a4. +- Patches dropped: + * fixup-gdb-glibc-strstr-workaround.patch + * gdb-glibc-strstr-workaround.patch + +------------------------------------------------------------------- +Fri Jan 24 15:07:38 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ a247406. +- Patches dropped: + * gdb-core-open-vdso-warning.patch + +------------------------------------------------------------------- +Fri Jan 24 15:05:16 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ 485076c. +- Patches updated: + * gdb-add-rpm-suggestion-script.patch + +------------------------------------------------------------------- +Fri Jan 24 15:00:56 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ 1672291. +- Patches updated: + * gdb-6.6-buildid-locate-rpm-suse.patch + * gdb-add-rpm-suggestion-script.patch + +------------------------------------------------------------------- +Fri Jan 24 13:37:51 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ f9386b1. +- Patches dropped: + * gdb-fedora-libncursesw.patch + +------------------------------------------------------------------- +Fri Jan 24 13:34:07 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ 93db514. +- Patches added: + * gdb-rhbz2277160-apx-disasm.patch + +------------------------------------------------------------------- +Thu Jan 23 15:29:00 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ deb8227. +- Patches dropped: + * fixup-gdb-linux_perf-bundle.patch + * gdb-linux_perf-bundle.patch + +------------------------------------------------------------------- +Thu Jan 23 15:23:25 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ 7b0d0c4. +- Patches dropped: + * gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch +- Patches updated: + * gdb-6.6-buildid-locate.patch + * gdb-add-missing-debug-info-python-hook.patch + +------------------------------------------------------------------- +Thu Jan 23 15:19:19 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ 94829f0. +- Patches dropped: + * fixup-gdb-bz634108-solib_address.patch + * gdb-bz634108-solib_address.patch + +------------------------------------------------------------------- +Thu Jan 23 15:14:19 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ 2024966. +- Maintenance script import-fedora.sh: + * Remove gdb-container-rh-pkg.patch from skip_patches. + +------------------------------------------------------------------- +Thu Jan 23 15:10:16 UTC 2025 - Tom de Vries + +- Patches dropped (unused): + * fixup-gdb-6.3-attach-see-vdso-test.patch + +------------------------------------------------------------------- +Thu Jan 23 15:05:22 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ a54b5ef. +- Patches dropped: + * gdb-6.3-attach-see-vdso-test.patch + +------------------------------------------------------------------- +Thu Jan 23 11:40:47 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ 08bfd0a. +- Patches dropped: + * fixup-gdb-6.3-gstack-20050411.patch + * fixup-skip-tests.patch + * gdb-6.6-buildid-locate-rpm-librpm-workaround.patch + * gdb-6.6-buildid-locate-rpm.patch +- Patches added: + * gdb-add-missing-debug-ext-lang-hook.patch + * gdb-add-missing-debug-info-python-hook.patch + * gdb-add-rpm-suggestion-script.patch + * gdb-do-not-import-py-curses-ascii-module.patch + * gdb-handle-no-python-gdb-module.patch + * gdb-merge-debug-symbol-lookup.patch + * gdb-python-avoid-depending-on-the-curses-library.patch + * gdb-refactor-find-and-add-separate-symbol-file.patch + * gdb-reformat-missing-debug-py-file.patch + * gdb-remove-path-in-test-name.patch + * gdb-remove-use-of-py-isascii + * gdb-sync-coffread-with-elfread.patch +- Patches updated: + * fixup-gdb-bz634108-solib_address.patch + * gdb-6.3-gstack-20050411.patch + * gdb-6.6-buildid-locate-rpm-suse.patch + * gdb-6.6-buildid-locate-solib-missing-ids.patch + * gdb-6.6-buildid-locate.patch + * gdb-archer-next-over-throw-cxx-exec.patch + * gdb-bz634108-solib_address.patch + * gdb-fedora-libncursesw.patch + * gdb-glibc-strstr-workaround.patch + * gdb-rhbz1007614-memleak-infpy_read_memory-test.patch + +------------------------------------------------------------------- +Thu Jan 23 09:14:28 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ f379362. +- Patches modified: + * gdb-6.6-buildid-locate.patch + +------------------------------------------------------------------- +Thu Jan 23 09:07:47 UTC 2025 - Tom de Vries + +- Update to fedora rawhide @ e27fd6f. +- Patches modified: + * gdb-6.6-buildid-locate-rpm.patch + * gdb-6.6-buildid-locate.patch + +------------------------------------------------------------------- +Thu Jan 23 08:11:26 UTC 2025 - Tom de Vries + +- Add "BuildRequires: libgo23" to fix unresolved for factory. + +------------------------------------------------------------------- +Mon Jan 20 14:22:22 UTC 2025 - Andreas Schwab + +- riscv-lrsc.patch: Fix stepping over atomic sequences + +------------------------------------------------------------------- +Tue Dec 17 16:11:55 UTC 2024 - Tom de Vries + +- Maintenance script qa.sh: + * Add PR29770 xfail (glibc). + * Add PR31229 kfail. + ------------------------------------------------------------------- Wed Dec 11 18:13:33 UTC 2024 - Tom de Vries @@ -794,9 +1501,10 @@ Sun Oct 29 18:57:21 UTC 2023 - Tom de Vries * Update PR29781 kfail. - Maintenance script qa-local.sh: * Add "Verify quilt setup" step. -- Patches added (backport from master): +- Patches added (backport from master, bsc#1216488): * gdb-symtab-handle-self-reference-die.patch * gdb-symtab-handle-self-reference-in-inherit_abstract.patch +- Patches added (backport from master): * gdb-symtab-add-optimized-out-static-var-to-cooked-in.patch ------------------------------------------------------------------- diff --git a/gdb.spec b/gdb.spec index f61b998..a5dcdd4 100644 --- a/gdb.spec +++ b/gdb.spec @@ -1,7 +1,7 @@ # -# spec file +# spec file for package gdb # -# Copyright (c) 2024 SUSE LLC +# Copyright (c) 2025 SUSE LLC # Copyright (c) 2012 RedHat # # All modifications and additions to the file contributed by third parties @@ -69,7 +69,7 @@ Group: Development/Languages/C and C++ %endif Name: gdb%{name_suffix} -Version: 14.2 +Version: 15.2 Release: 0 # The release always contains a leading reserved number, start it at 1. @@ -171,69 +171,37 @@ NoSource: 20 #Fedora Packages begin Patch2: gdb-6.3-gstack-20050411.patch -Patch3: gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch -Patch4: gdb-6.5-bz218379-ppc-solib-trampoline-test.patch -Patch5: gdb-6.6-bz229517-gcore-without-terminal.patch -Patch6: gdb-6.6-testsuite-timeouts.patch -Patch7: gdb-6.6-bz237572-ppc-atomic-sequence-test.patch -Patch8: gdb-6.3-attach-see-vdso-test.patch -Patch9: gdb-6.5-bz243845-stale-testing-zombie-test.patch -Patch10: gdb-6.6-buildid-locate.patch -Patch11: gdb-6.6-buildid-locate-solib-missing-ids.patch -Patch12: gdb-6.6-buildid-locate-rpm.patch -Patch14: gdb-6.5-gcore-buffer-limit-test.patch -Patch15: gdb-6.3-mapping-zero-inode-test.patch -Patch16: gdb-6.5-section-num-fixup-test.patch -Patch18: gdb-simultaneous-step-resume-breakpoint-test.patch -Patch19: gdb-core-open-vdso-warning.patch -Patch20: gdb-archer-next-over-throw-cxx-exec.patch -Patch21: gdb-6.6-buildid-locate-rpm-librpm-workaround.patch -Patch22: gdb-test-bt-cfi-without-die.patch -Patch23: gdb-bz634108-solib_address.patch -Patch24: gdb-test-dw2-aranges.patch -Patch25: gdb-glibc-strstr-workaround.patch -Patch26: gdb-rhbz-818343-set-solib-absolute-prefix-testcase.patch -Patch27: gdb-rhbz947564-findvar-assertion-frame-failed-testcase.patch -Patch28: gdb-rhbz1007614-memleak-infpy_read_memory-test.patch -Patch31: gdb-rhbz1149205-catch-syscall-after-fork-test.patch -Patch32: gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-3of3.patch -Patch33: gdb-fedora-libncursesw.patch -Patch34: gdb-rhbz1261564-aarch64-hw-watchpoint-test.patch -Patch36: gdb-linux_perf-bundle.patch -Patch38: gdb-rhbz2232086-refactor-selftest-support.patch -Patch39: gdb-rhbz-2232086-reduce-size-of-gdb-index.patch -Patch40: gdb-rhbz-2232086-cpp-ify-mapped-symtab.patch -Patch41: gdb-rhbz-2232086-generate-gdb-index-consistently.patch -Patch42: gdb-rhbz-2232086-generate-dwarf-5-index-consistently.patch -Patch43: gdb-rhbz2250652-gdbpy_gil.patch -Patch44: gdb-rhbz2250652-avoid-PyOS_ReadlineTState.patch -Patch45: gdb-ftbs-swapped-calloc-args.patch -Patch46: gdb-rhbz2261580-intrusive_list-assertion-fix.patch +Patch3: gdb-6.5-bz218379-ppc-solib-trampoline-test.patch +Patch4: gdb-6.6-bz237572-ppc-atomic-sequence-test.patch +Patch5: gdb-6.5-gcore-buffer-limit-test.patch +Patch6: gdb-6.3-mapping-zero-inode-test.patch +Patch8: gdb-archer-next-over-throw-cxx-exec.patch +Patch10: gdb-rhbz-818343-set-solib-absolute-prefix-testcase.patch +Patch12: gdb-rhbz1149205-catch-syscall-after-fork-test.patch +Patch13: gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-3of3.patch +Patch16: gdb-remove-qnx-neutrino-support.patch +Patch17: gdb-backport-buildid-related-changes.patch +Patch18: gdb-add-rpm-suggestion-script.patch +Patch19: gdb-add-deprecated-settings-py-script.patch +Patch20: gdb-6.6-buildid-locate-tests.patch +Patch21: gdb-catchpoint-re-set.patch #Fedora Packages end # Fedora patches fixup # These need a number with at least four digits, otherwise patchlist.pl removes # them when upgrading. -Patch1000: fixup-gdb-linux_perf-bundle.patch -Patch1003: fixup-gdb-glibc-strstr-workaround.patch -Patch1004: fixup-gdb-6.5-bz243845-stale-testing-zombie-test.patch -Patch1005: fixup-gdb-test-bt-cfi-without-die.patch -Patch1007: fixup-gdb-test-dw2-aranges.patch -Patch1008: fixup-gdb-bz634108-solib_address.patch -Patch1009: fixup-gdb-6.3-gstack-20050411.patch -Patch1010: fixup-gdb-6.3-attach-see-vdso-test.patch -Patch1012: fixup-gdb-rhbz1261564-aarch64-hw-watchpoint-test.pat.patch -# Fixes up several patches, should be dropped when updating to -# rawhide @ 08bfd0a. -Patch1013: fixup-skip-tests.patch +Patch1000: fixup-gdb-6.5-gcore-buffer-limit-test.patch +Patch1001: fixup-gdb-add-rpm-suggestion-script.patch # openSUSE specific # Hardcodes /bin/bash, given that path is known. Patch1100: gdb-gcore-bash.patch # Make gdb emit zypper install hints, rather than debuginfo-install hints. -Patch1101: gdb-6.6-buildid-locate-rpm-suse.patch +Patch1101: gdb-add-rpm-suggestion-script-suse.patch +# Fixes testcase to not expect dnf message. +Patch1102: gdb-6.6-buildid-locate-tests-suse.patch # openSUSE specific -- testsuite @@ -255,164 +223,113 @@ Patch1503: gdb-add-index.sh-fix-bashism.patch # Fixes: # FAIL: gdb.mi/new-ui-mi-sync.exp: sync-command=run: add-inferior (timeout) Patch1504: fix-gdb.mi-new-ui-mi-sync.exp.patch -# Fixes: -# FAIL: gdb.base/step-over-syscall.exp: fork: displaced=off: \ -# pc after stepi matches insn addr after syscall -Patch1505: gdb-testsuite-fix-gdb.base-step-over-syscall.exp-with-m32-amd-case.patch +# https://sourceware.org/bugzilla/show_bug.cgi?id=32590 +Patch1506: gdb-cli-print-at_hwcap3-and-at_hwcap4.patch +# Work around SCM_UNPACK Werror=sequence-point in libguile v2.0.9 (SLE-12). +Patch1507: gdb-guile-use-scm_debug_typing_strictness-0.patch +# SLE-12 specific fix, hard to reproduce with trunk. +Patch1508: gdb-testsuite-fix-gdb_py_module_available-for-python.patch -# Backports from current release branch (GDB 14). +# Backports from master, available in GDB 16. -# +Patch2000: gdb-testsuite-fix-gdb.fortran-array-bounds.exp-on-ar.patch +Patch2001: gdb-symtab-return-correct-reader-for-top-level-cu-in.patch +Patch2002: gdb-tdep-s390-add-arch15-record-replay-support.patch +Patch2003: gdb-testsuite-avoid-intermittent-failures-on-a-debug.patch +Patch2005: gdb-testsuite-fix-gdb.threads-leader-exit-attach.exp.patch +Patch2006: gdb-testsuite-fix-gdb.python-py-format-string.exp-wi.patch +Patch2007: gdb-testsuite-fix-gdb.python-py-mi-cmd.exp-with-pyth.patch +Patch2008: gdb-testsuite-fix-gdb.ada-mi_task_arg.exp-on-arm-lin.patch +Patch2009: gdb-testsuite-fix-regexp-in-gdb.ada-mi_var_access.ex.patch +Patch2010: gdb-testsuite-fix-gdb.arch-arm-pseudo-unwind.exp-wit.patch +Patch2011: gdb-symtab-fix-target-type-of-complex-long-double-on.patch +Patch2012: gdb-testsuite-don-t-use-set-auto-solib-add-off.patch +Patch2013: gdb-tdep-fix-arm-thumb2-hw-breakpoint.patch +Patch2014: gdb-testsuite-fix-gdb.cp-m-static.exp-on-arm.patch +Patch2015: gdb-testsuite-fix-gdb.dwarf2-dw2-fixed-point.exp-on-.patch +Patch2016: gdb-testsuite-fix-gdb.dwarf2-dw2-lines.exp-on-arm-li.patch +Patch2017: gdb-exp-fix-gdb.fortran-intrinsics.exp-fail-on-arm.patch +Patch2018: gdb-tdep-handle-sycall-statx-for-arm-linux.patch +Patch2019: gdb-tdep-fix-recording-of-t1-push.patch +Patch2020: gdb-tdep-handle-syscall-clock_gettime64-for-arm-linu.patch +Patch2021: fix-gdb.dwarf2-shortpiece.exp-on-s390x.patch +Patch2022: handle-address-class-annotation-for-s390x-in-some-te.patch +Patch2023: fix-gdb.dap-step-out.exp-on-s390x.patch +Patch2024: use-setvariable-in-gdb.dap-scopes.exp.patch +Patch2025: gdb-testsuite-fix-regexp-in-gdb.arch-i386-disp-step-.patch +Patch2026: gdb-testsuite-fix-gdb.arch-arm-single-step-kernel-he.patch +Patch2027: gdb-testsuite-fix-gdb.python-py-format-address.exp-o.patch +Patch2028: gdb-testsuite-fix-gdb.arch-riscv-tdesc-regs.exp.patch +Patch2029: gdb-testsuite-fix-gdb.base-list-dot-nodebug-and-make.patch +Patch2030: gdb-testsuite-fix-gdb.base-empty-host-env-vars.exp.patch +Patch2031: gdb-prune-inferior-after-switching-inferior.patch +Patch2032: gdb-testsuite-fix-timeout-in-gdb.mi-mi-multi-command.patch +Patch2033: gdb-testsuite-fix-regexp-in-gdb.threads-stepi-over-c.patch +Patch2034: gdb-record-fix-out-of-bounds-write-in-aarch64_record.patch +Patch2035: gdb-build-fix-unused-var-in-corelow.c.patch -# Backports from master, available in next release (GDB 15). +# Backports from master, available in GDB 17. -Patch2000: gdb-symtab-work-around-pr-gas-29517.patch -Patch2001: gdb-symtab-add-producer_is_gas.patch -Patch2002: gdb-symtab-work-around-gas-pr28629.patch -Patch2003: gdb-tdep-fix-nr-array-elements-in-ppc64_aggregate_ca.patch -Patch2004: gdb-tui-fix-wmaybe-uninitialized-in-tui_find_disasse.patch -Patch2005: gdb-testsuite-add-missing-no-prompt-anchor-in-gdb.ba.patch -Patch2006: gdb-testsuite-remove-spurious-in-save_vars.patch -Patch2007: make-pascal_language-print_type-handle-varstring-nul.patch -Patch2008: gdb-symtab-work-around-pr-gas-29517-dwarf2-case.patch -Patch2010: fix-the-gdb.ada-inline-section-gc.exp-test.patch -Patch2011: gdb-testsuite-handle-pac-marker.patch -Patch2012: change-gdb.base-examine-backwards.exp-for-aix.patch -Patch2013: gdb-testsuite-fix-spurious-fails-with-examine-backwa.patch -Patch2014: gdb-testsuite-make-gdb.base-solib-search.exp-more-ro.patch -Patch2015: gdb-testsuite-fix-regexp-in-vgdb_start.patch -Patch2016: powerpc-and-aarch64-fix-reverse-stepping-failure.patch -Patch2017: gdb-tdep-fix-gdb.base-watch-bitfields.exp-on-aarch64.patch -Patch2018: gdb-tdep-fix-gdb.base-watchpoint-unaligned.exp-on-aa.patch -Patch2019: gdb-testsuite-add-pr-gdb-26967-kfail-in-two-more-tes.patch -Patch2020: gdb-testsuite-fix-gdb.base-eh_return.exp.patch -Patch2021: fixup-powerpc-and-aarch64-fix-reverse-stepping-failu.patch -Patch2022: gdb-exp-fix-printing-of-out-of-bounds-struct-members.patch -Patch2023: gdb-fix-heap-use-after-free-in-select_event_lwp.patch -Patch2024: fix-regression-on-aarch64-linux-gdbserver.patch -Patch2025: gdb-testsuite-factor-out-proc-get_portnum.patch -Patch2026: gdb-testsuite-make-portnum-a-persistent-global.patch -Patch2027: gdb-testsuite-factor-out-proc-with_lock.patch -Patch2028: gdb-testsuite-factor-out-proc-lock_dir.patch -Patch2029: gdb-testsuite-move-gpu-parallel.lock-to-cache-dir.patch -Patch2030: gdb-testsuite-use-unique-portnum-in-parallel-testing.patch -Patch2031: gdb-testsuite-use-unique-portnum-in-parallel-testing-check-slash-slash-case.patch -Patch2032: gdb-tdep-fix-reverse-execution-of-ldr-immediate-t4.patch -Patch2033: gdb-exp-fix-cast-handling-for-indirection.patch -Patch2034: gdb-remote-fix-abort-on-remote_close_error.patch -Patch2035: gdb-testsuite-use-find_gnatmake-instead-of-gdb_find_.patch -Patch2036: gdb-testsuite-simplify-gdb.server-server-kill-python.patch -Patch2037: gdb-testsuite-fix-gdbserver-pid-in-gdb.server-server.patch -Patch2038: gdb-testsuite-add-missing-include-in-gdb.base-ctf-pt.patch -Patch2039: gdb-testsuite-fix-gdb.ada-verylong.exp-on-32-bit-tar.patch -Patch2040: gdb-testsuite-add-missing-includes-in-gdb.trace-coll.patch -Patch2041: gdb-testsuite-fix-missing-return-type-in-gdb.linespe.patch -Patch2042: gdb-testsuite-fix-gdb.base-ending-run.exp-on-manjaro.patch -Patch2043: gdb-testsuite-fix-test-case-gdb.threads-attach-stopp.patch -Patch2044: gdb-testsuite-add-missing-include-in-gdb.base-rtld-s.patch -Patch2045: gdb-testsuite-fix-valgrind-tests-on-debian.patch -Patch2046: gdb-testsuite-fix-gdb.server-server-connect.exp-for-.patch -Patch2047: gdb-testsuite-handle-core-without-build-id-in-gdb.ba.patch -Patch2048: gdb-testsuite-fix-gdb.base-list-no-debug.exp-on-debi.patch -Patch2049: gdb-testsuite-reset-errcnt-and-warncnt-in-default_gd.patch -Patch2050: gdb-testsuite-fix-test-in-gdb.python-py-finish-break.patch -Patch2051: gdb-testsuite-further-handle-long-filenames-in-gdb.b.patch -Patch2052: gdb-testsuite-fix-license-text-in-gdb.reverse-map-to.patch -Patch2053: gdb-testsuite-call-ldd-version-in-gdb.testsuite-dump.patch -Patch2054: gdb-testsuite-fix-gdb.mi-mi-dprintf.exp-with-read1.patch -Patch2055: gdb-testsuite-fix-gdb.cp-namespace.exp-with-read1.patch -Patch2056: gdb-testsuite-fix-typo-in-gdb.base-catch-syscall.exp.patch -Patch2057: gdb-testsuite-use-more-progbits-for-arm.patch -Patch2058: gdb-testsuite-fix-gdb.dwarf2-dw2-gas-workaround.exp.patch -Patch2059: gdb-fix-segfault-in-for_each_block-part-1.patch -Patch2060: gdb-fix-segfault-in-for_each_block-part-2.patch -Patch2061: gdb-tui-allow-command-window-of-1-or-2-lines.patch -Patch2062: gdb-tui-fix-resizing-of-terminal-to-1-or-2-lines.patch -Patch2063: gdb-symtab-workaround-pr-gas-31115.patch -Patch2064: gdb-arm-remove-tpidruro-register-from-non-freebsd-ta.patch -Patch2065: gdb-tdep-fix-catching-syscall-execve-exit-for-arm.patch -Patch2066: gdb-arm-fix-epilogue-frame-id.patch -Patch2070: rs6000-unwind-on-each-instruction-fix.patch -Patch2071: gdb-python-make-gdb.unwindinfo.add_saved_register-mo.patch -Patch2072: gdb-arm-remove-thumb-bit-in-arm_adjust_breakpoint_ad.patch -Patch2073: gdb-build-fix-gdbserver-linux-aarch64-low.cc-build.patch -Patch2074: powerpc-fix-test-gdb.ada-finish-large.exp.patch -Patch2075: gdb-python-make-gdb.unwindinfo.add_saved_register-mo-fixup.patch -Patch2076: gdb-exp-redo-cast-handling-for-indirection.patch -Patch2077: s390-provide-ibm-z16-arch14-instruction-descriptions.patch -Patch2078: gdb-s390-add-arch14-record-replay-support.patch - -# Backports from master, not yet available in next release (GDB 16). - -Patch2090: gdb-python-fix-gdb.python-py-disasm.exp-on-arm-linux.patch -Patch2091: gdb-testsuite-fix-gdb.fortran-array-bounds.exp-on-ar.patch -Patch2092: gdb-symtab-return-correct-reader-for-top-level-cu-in.patch -Patch2093: gdb-tdep-s390-add-arch15-record-replay-support.patch -Patch2094: gdb-testsuite-avoid-intermittent-failures-on-a-debug.patch - -# +Patch2100: gdb-testsuite-record-less-in-gdb.reverse-time-revers.patch +Patch2101: gdb-doc-fix-gdb.unwinder-docs.patch +Patch2102: gdb-doc-fix-qisaddresstagged-anchor.patch +Patch2103: gdb-testsuite-fix-another-regexp-in-gdb.threads-step.patch +Patch2104: gdb-testsuite-fix-timeouts-in-gdb.threads-step-over-.patch +Patch2105: gdb-testsuite-handle-unordered-dict-in-gdb.python-py.patch +Patch2106: gdb-testsuite-check-gnatmake-version-in-gdb.ada-scal.patch +Patch2107: fix-gdb.base-finish-pretty.exp-on-s390x.patch +Patch2108: fix-gdb.base-readnever.exp-on-s390x.patch +Patch2109: add-dwarf_expr_piece.op.patch +Patch2110: add-gdbarch_dwarf2_reg_piece_offset-hook.patch +Patch2111: fix-gdb.base-store.exp-on-s390x.patch +Patch2112: fix-gdb.ada-o2_float_param.exp-on-s390x-linux.patch +Patch2113: gdb-testsuite-fix-gdb.base-branch-to-self.exp-on-arm.patch +Patch2114: gdb-tdep-fix-gdb.cp-non-trivial-retval.exp-on-riscv6.patch +Patch2115: gdb-testsuite-fix-gdb.cp-non-trivial-retval.exp-on-a.patch +Patch2116: gdb-testsuite-fix-gdb.rust-completion.exp-timeout-on.patch +Patch2117: gdb-testsuite-require-supports_process_record-in-gdb.patch +Patch2118: gdb-testsuite-fix-gdb.base-list-dot-nodebug.exp-on-o.patch +Patch2119: gdb-testsuite-use-nostdlib-in-gdb.base-list-dot-node.patch +Patch2120: gdb-testsuite-require-can_spawn_for_attach-in-gdb.ba.patch +Patch2121: gdb-testsuite-fix-gdb.ada-big_packed_array.exp-on-s3.patch +Patch2122: gdb-testsuite-fix-gdb.ada-convvar_comp.exp-on-s390x-.patch +Patch2123: gdb-testsuite-fix-gdb.base-step-over-syscall.exp-with-m32-for-amd.patch +Patch2124: gdb-testsuite-fix-gdb.base-step-over-syscall.exp-with-glibc-2-41.patch +Patch2125: gdb-tdep-backport-i386_canonicalize_syscall-rewrite-.patch +Patch2126: gdb-testsuite-fix-gdb.threads-access-mem-running-thr.patch # Backport from gdb-patches # https://sourceware.org/pipermail/gdb-patches/2021-September/182226.html -Patch2100: gdb-python-finishbreakpoint-update.patch +Patch3000: gdb-python-finishbreakpoint-update.patch # https://sourceware.org/pipermail/gdb-patches/2021-October/182444.html -Patch2101: gdb-testsuite-prevent-compilation-fails-with-unix-fpie-pie.patch +Patch3001: gdb-testsuite-prevent-compilation-fails-with-unix-fpie-pie.patch # https://sourceware.org/pipermail/gdb-patches/2021-May/178990.html -Patch2102: gdb-cli-add-ignore-errors-command.patch +Patch3002: gdb-cli-add-ignore-errors-command.patch # https://sourceware.org/pipermail/gdb-patches/2024-May/209469.html -Patch2103: gdb-testsuite-fix-error-in-gdb.server-server-kill-py.patch +Patch3003: gdb-testsuite-fix-error-in-gdb.server-server-kill-py.patch # https://sourceware.org/pipermail/gdb-patches/2024-May/209504.html -Patch2104: gdb-testsuite-fix-timeout-in-gdb.tui-resize-2.exp.patch -# https://sourceware.org/pipermail/gdb-patches/2024-June/209736.html -Patch2105: gdb-tdep-fix-gdb.base-watchpoint-running-on-arm-ppc6.patch -# https://sourceware.org/pipermail/gdb-patches/2025-March/216050.html -Patch2106: gdb-testsuite-add-gdb.arch-s390-disassemble.exp.patch - +Patch3004: gdb-testsuite-fix-timeout-in-gdb.tui-resize-2.exp.patch +# https://sourceware.org/pipermail/gdb-patches/2025-January/214982.html +Patch3005: gdb-doc-fix-standard-replies-xref.patch # https://sourceware.org/pipermail/gdb-patches/2023-December/205054.html -Patch2120: gdb-symtab-refactor-condition-in-scan_attributes.patch -Patch2121: gdb-symtab-factor-out-m_die_range_map-usage.patch -Patch2122: gdb-symtab-handle-nullptr-parent-in-parent_map-set_p.patch -Patch2123: gdb-symtab-factor-out-m_deferred_entries-usage.patch -Patch2124: gdb-symtab-resolve-deferred-entries-inter-shard-case.patch -Patch2125: gdb-testsuite-add-gdb.dwarf2-forward-spec-inter-cu.e.patch -Patch2126: gdb-testsuite-add-gdb.dwarf2-backward-spec-inter-cu..patch -Patch2127: gdb-symtab-keep-track-of-processed-dies-in-shard.patch -Patch2128: gdb-symtab-resolve-deferred-entries-intra-shard-case.patch -Patch2129: gdb-symtab-don-t-defer-backward-refs-inter-cu-intra-.patch -Patch2130: gdb-symtab-recurse-into-c-dw_tag_subprogram-dies-for.patch -Patch2131: gdb-symtab-keep-track-of-all-parents-for-cooked-inde.patch -Patch2132: gdb-symtab-fix-dw_tag_inlined_subroutine-entries-in-.patch +Patch3006: gdb-symtab-recurse-into-c-dw_tag_subprogram-dies-for.patch +# https://sourceware.org/bugzilla/show_bug.cgi?id=30380#c1 +Patch3007: gdb-testsuite-use-c-flag-in-c-test-cases.patch +# https://sourceware.org/pipermail/gdb-patches/2025-March/216050.html +Patch3008: gdb-testsuite-add-gdb.arch-s390-disassemble.exp.patch # s390x libopcodes backports, available in GDB 16. -Patch4000: s390-make-operand-table-indices-relative-to-each-oth.patch -Patch4001: s390-align-optional-operand-definition-to-specs.patch -Patch4002: s390-add-missing-extended-mnemonics.patch -Patch4003: s390-correct-prno-instruction-name.patch -Patch4004: fix-building-for-the-s390-target-with-clang.patch -Patch4005: s390-support-for-jump-visualization-in-disassembly.patch -Patch4006: s390-align-letter-case-of-instruction-descriptions.patch -Patch4007: s390-enhance-error-handling-in-s390-mkopc.patch -Patch4008: s390-use-safe-string-functions-and-length-macros-in-.patch -Patch4009: s390-optionally-print-instruction-description-in-dis.patch -Patch4010: s390-add-suffix-to-conditional-branch-instruction-de.patch -Patch4011: add-note-to-translators-not-to-translate-z-architect.patch -Patch4012: s390-whitespace-fixes-in-conditional-branch-flavor-d.patch -Patch4013: s390-use-proper-string-lengths-when-parsing-opcode-t.patch -Patch4014: s390-add-test-cases-for-base-index-register-0.patch -Patch4015: s390-warn-when-register-name-type-does-not-match-ope.patch -Patch4016: s390-print-base-register-0-as-0-in-disassembly.patch -Patch4017: s390-flag-conditional-branch-relative-insns-as-condj.patch -Patch4018: s390-align-opcodes-to-lower-case.patch -Patch4019: s390-simplify-dis-assembly-of-insn-operands-with-con.patch -Patch4020: s390-relax-risbg-n-z-risb-h-l-gz-rns-ros-rxs-bgt-ope.patch -Patch4021: s390-add-arch15-instructions.patch -Patch4022: opcodes-fix-std-gnu23-compatibility-wrt-static_asser.patch -Patch4023: s390-add-arch15-instruction-names.patch -Patch4024: s390-add-arch15-concurrent-functions-facility-insns.patch -Patch4025: s390-fix-disassembly-of-optional-addressing-operands.patch -Patch4026: s390-treat-addressing-operand-sequence-as-one-in-dis.patch +Patch4000: s390-align-opcodes-to-lower-case.patch +Patch4001: s390-simplify-dis-assembly-of-insn-operands-with-con.patch +Patch4002: s390-relax-risbg-n-z-risb-h-l-gz-rns-ros-rxs-bgt-ope.patch +Patch4003: s390-add-arch15-instructions.patch +Patch4004: opcodes-fix-std-gnu23-compatibility-wrt-static_asser.patch +Patch4005: s390-add-arch15-instruction-names.patch +Patch4006: s390-add-arch15-concurrent-functions-facility-insns.patch +Patch4007: s390-fix-disassembly-of-optional-addressing-operands.patch +Patch4008: s390-treat-addressing-operand-sequence-as-one-in-dis.patch # Debug patches. @@ -431,11 +348,12 @@ BuildRequires: aaa_base-yama-enable-ptrace BuildRequires: bison BuildRequires: flex -%if 0%{suse_version} > 1110 +%if 0%{suse_version} > 1315 BuildRequires: gcc-c++ %else -BuildRequires: gcc48 -BuildRequires: gcc48-c++ +# SLE-12. +BuildRequires: gcc11 +BuildRequires: gcc11-c++ %endif BuildRequires: gettext BuildRequires: glibc-devel @@ -458,7 +376,7 @@ BuildRequires: mpfr-devel BuildRequires: ncurses-devel BuildRequires: pkg-config BuildRequires: readline-devel -BuildRequires: rpm-devel + # SLE-10 doesn't have xz-devel. %if 0%{suse_version} >= 1110 BuildRequires: xz-devel @@ -468,8 +386,10 @@ BuildRequires: zlib-devel %if 0%{!?_without_python:1} %if %{build_testsuite} BuildRequires: %{python}-base +BuildRequires: python3-rpm %else Requires: %{python}-base +Requires: python3-rpm %endif BuildRequires: %{python}-devel %endif # 0%{!?_without_python:1} @@ -575,11 +495,11 @@ BuildRequires: gcc-ada-32bit %if 0%{suse_version} > 1110 BuildRequires: gcc-c++-32bit -%else -# Use system g++ for testing for SLE-11. -BuildRequires: gcc-c++ %endif +# Use system g++ for testing SLE-12. +BuildRequires: gcc-c++ + %if 0%{suse_version} >= 1210 && 0%{suse_version} != 1315 BuildRequires: glibc-devel-static-32bit %endif @@ -727,55 +647,24 @@ find -name "*.info*"|xargs rm -f %patch -P 4 -p1 %patch -P 5 -p1 %patch -P 6 -p1 -%patch -P 7 -p1 %patch -P 8 -p1 -%patch -P 9 -p1 %patch -P 10 -p1 -%patch -P 11 -p1 %patch -P 12 -p1 -%patch -P 14 -p1 -%patch -P 15 -p1 +%patch -P 13 -p1 %patch -P 16 -p1 +%patch -P 17 -p1 %patch -P 18 -p1 %patch -P 19 -p1 %patch -P 20 -p1 %patch -P 21 -p1 -%patch -P 22 -p1 -%patch -P 23 -p1 -%patch -P 24 -p1 -%patch -P 25 -p1 -%patch -P 26 -p1 -%patch -P 27 -p1 -%patch -P 28 -p1 -%patch -P 31 -p1 -%patch -P 32 -p1 -%patch -P 33 -p1 -%patch -P 34 -p1 -%patch -P 36 -p1 -%patch -P 38 -p1 -%patch -P 39 -p1 -%patch -P 40 -p1 -%patch -P 41 -p1 -%patch -P 42 -p1 -%patch -P 43 -p1 -%patch -P 44 -p1 -%patch -P 45 -p1 -%patch -P 46 -p1 #Fedora patching end %patch -P 1000 -p1 -%patch -P 1003 -p1 -%patch -P 1004 -p1 -%patch -P 1005 -p1 -%patch -P 1007 -p1 -%patch -P 1008 -p1 -%patch -P 1009 -p1 -%patch -P 1010 -p1 -%patch -P 1012 -p1 -%patch -P 1013 -p1 +%patch -P 1001 -p1 %patch -P 1100 -p1 %patch -P 1101 -p1 +%patch -P 1102 -p1 %patch -P 1200 -p1 %patch -P 1203 -p1 @@ -785,17 +674,19 @@ find -name "*.info*"|xargs rm -f %patch -P 1501 -p1 %patch -P 1503 -p1 %patch -P 1504 -p1 -%patch -P 1505 -p1 +%patch -P 1506 -p1 +%patch -P 1507 -p1 +%patch -P 1508 -p1 %patch -P 2000 -p1 %patch -P 2001 -p1 %patch -P 2002 -p1 %patch -P 2003 -p1 -%patch -P 2004 -p1 %patch -P 2005 -p1 %patch -P 2006 -p1 %patch -P 2007 -p1 %patch -P 2008 -p1 +%patch -P 2009 -p1 %patch -P 2010 -p1 %patch -P 2011 -p1 %patch -P 2012 -p1 @@ -822,52 +713,6 @@ find -name "*.info*"|xargs rm -f %patch -P 2033 -p1 %patch -P 2034 -p1 %patch -P 2035 -p1 -%patch -P 2036 -p1 -%patch -P 2037 -p1 -%patch -P 2038 -p1 -%patch -P 2039 -p1 -%patch -P 2040 -p1 -%patch -P 2041 -p1 -%patch -P 2042 -p1 -%patch -P 2043 -p1 -%patch -P 2044 -p1 -%patch -P 2045 -p1 -%patch -P 2046 -p1 -%patch -P 2047 -p1 -%patch -P 2048 -p1 -%patch -P 2049 -p1 -%patch -P 2050 -p1 -%patch -P 2051 -p1 -%patch -P 2052 -p1 -%patch -P 2053 -p1 -%patch -P 2054 -p1 -%patch -P 2055 -p1 -%patch -P 2056 -p1 -%patch -P 2057 -p1 -%patch -P 2058 -p1 -%patch -P 2059 -p1 -%patch -P 2060 -p1 -%patch -P 2061 -p1 -%patch -P 2062 -p1 -%patch -P 2063 -p1 -%patch -P 2064 -p1 -%patch -P 2065 -p1 -%patch -P 2066 -p1 -%patch -P 2070 -p1 -%patch -P 2071 -p1 -%patch -P 2072 -p1 -%patch -P 2073 -p1 -%patch -P 2074 -p1 -%patch -P 2075 -p1 -%patch -P 2076 -p1 -%patch -P 2077 -p1 -%patch -P 2078 -p1 - -%patch -P 2090 -p1 -%patch -P 2091 -p1 -%patch -P 2092 -p1 -%patch -P 2093 -p1 -%patch -P 2094 -p1 %patch -P 2100 -p1 %patch -P 2101 -p1 @@ -876,7 +721,19 @@ find -name "*.info*"|xargs rm -f %patch -P 2104 -p1 %patch -P 2105 -p1 %patch -P 2106 -p1 - +%patch -P 2107 -p1 +%patch -P 2108 -p1 +%patch -P 2109 -p1 +%patch -P 2110 -p1 +%patch -P 2111 -p1 +%patch -P 2112 -p1 +%patch -P 2113 -p1 +%patch -P 2114 -p1 +%patch -P 2115 -p1 +%patch -P 2116 -p1 +%patch -P 2117 -p1 +%patch -P 2118 -p1 +%patch -P 2119 -p1 %patch -P 2120 -p1 %patch -P 2121 -p1 %patch -P 2122 -p1 @@ -884,40 +741,26 @@ find -name "*.info*"|xargs rm -f %patch -P 2124 -p1 %patch -P 2125 -p1 %patch -P 2126 -p1 -%patch -P 2127 -p1 -%patch -P 2128 -p1 -%patch -P 2129 -p1 -%patch -P 2130 -p1 -%patch -P 2131 -p1 -%patch -P 2132 -p1 -%patch4000 -p1 -%patch4001 -p1 -%patch4002 -p1 -%patch4003 -p1 -%patch4004 -p1 -%patch4005 -p1 -%patch4006 -p1 -%patch4007 -p1 -%patch4008 -p1 -%patch4009 -p1 -%patch4010 -p1 -%patch4011 -p1 -%patch4012 -p1 -%patch4013 -p1 -%patch4014 -p1 -%patch4015 -p1 -%patch4016 -p1 -%patch4017 -p1 -%patch4018 -p1 -%patch4019 -p1 -%patch4020 -p1 -%patch4021 -p1 -%patch4022 -p1 -%patch4023 -p1 -%patch4024 -p1 -%patch4025 -p1 -%patch4026 -p1 +%patch -P 3000 -p1 +%patch -P 3001 -p1 +%patch -P 3002 -p1 +%patch -P 3003 -p1 +%patch -P 3004 -p1 +%patch -P 3005 -p1 +%patch -P 3006 -p1 +%patch -P 3007 -p1 +%patch -P 3008 -p1 + +%patch -P 4000 -p1 +%patch -P 4001 -p1 +%patch -P 4002 -p1 +%patch -P 4003 -p1 +%patch -P 4004 -p1 +%patch -P 4005 -p1 +%patch -P 4006 -p1 +%patch -P 4007 -p1 +%patch -P 4008 -p1 #unpack libipt %if 0%{have_libipt} @@ -955,12 +798,13 @@ do mkdir %{gdb_build}$fprofile cd %{gdb_build}$fprofile -%if 0%{suse_version} > 1110 +%if 0%{suse_version} > 1315 CC=gcc CXX=g++ %else -CC=gcc-4.8 -CXX=g++-4.8 +# SLE-12. +CC=gcc-11 +CXX=g++-11 %endif export CC export CXX @@ -1001,15 +845,6 @@ LDFLAGS="$LDFLAGS -L$PWD/processor-trace-%{libipt_version}-root%{_libdir}" export CXXFLAGS="$CFLAGS" -export LIBRPM=$(ldd /bin/rpm \ - | grep librpm.so \ - | awk '{print $3}') -if [ "$LIBRPM" != "" ]; then - [ -f "$LIBRPM" ] -else - export LIBRPM=no -fi - %ifarch %ix86 ia64 ppc ppc64 ppc64le s390 s390x x86_64 aarch64 riscv64 %define build_multitarget 1 %else @@ -1079,11 +914,6 @@ $(: ppc64 host build crashes on ppc variant of libexpat.so ) \ %else --without-python \ %endif -%if %{suse_version} >= 1130 - --with-rpm=$LIBRPM \ -%else - --without-rpm \ -%endif %ifarch ia64 --with-libunwind-ia64 \ %else diff --git a/handle-address-class-annotation-for-s390x-in-some-te.patch b/handle-address-class-annotation-for-s390x-in-some-te.patch new file mode 100644 index 0000000..4d96ba3 --- /dev/null +++ b/handle-address-class-annotation-for-s390x-in-some-te.patch @@ -0,0 +1,125 @@ +From f6d4de8ce34365107106c4af60a9a1fb86a9977d Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Wed, 24 Jul 2024 14:56:56 +0200 +Subject: [PATCH 18/46] Handle address class annotation for s390x in some + test-cases + +On s390x-linux, I ran into: +... +(gdb) ptype crash^M +type = class crash {^M +^M + public:^M + crash(int (class {...}::*)(class {...} * const @mode32));^M +}^M +(gdb) FAIL: gdb.dwarf2/dw2-anon-mptr.exp: ptype crash +... + +The problem is that the test-case doesn't expect the address class annotation +@mode32. + +The test-case uses a .S file, with the address size hard-coded to 4 bytes, and +that's something that is annotated with @mode32 on s390x (which uses 8 byte +addresses). + +Fix this by allowing the annotation in the regexp. + +Likewise in two other test-cases. + +Tested on s390-linux and x86_64-linux. +--- + gdb/testsuite/gdb.dwarf2/dw2-anon-mptr.exp | 16 +++++++++++++++- + gdb/testsuite/gdb.dwarf2/dw2-opt-structptr.exp | 17 ++++++++++++----- + .../gdb.dwarf2/member-ptr-forwardref.exp | 16 +++++++++++++++- + 3 files changed, 42 insertions(+), 7 deletions(-) + +diff --git a/gdb/testsuite/gdb.dwarf2/dw2-anon-mptr.exp b/gdb/testsuite/gdb.dwarf2/dw2-anon-mptr.exp +index 5935ba628b6..fa98e413ad8 100644 +--- a/gdb/testsuite/gdb.dwarf2/dw2-anon-mptr.exp ++++ b/gdb/testsuite/gdb.dwarf2/dw2-anon-mptr.exp +@@ -36,5 +36,19 @@ gdb_test "show cp-abi" {The currently selected C\+\+ ABI is "gnu-v3".*} + + gdb_load $binfile + ++set re_address_class "@\[^\r\n\]+" ++ ++set re_class_ptr_const \ ++ [string cat \ ++ [string_to_regexp "class {...} * const"] "( $re_address_class)?"] ++ + gdb_test "ptype crash" \ +- "type = class crash {\[\r\n \t\]*public:\[\r\n \t\]*crash\\(int \\(class {\\.\\.\\.}::\\*\\)\\(class {\\.\\.\\.} \\* const\\)\\);\[\r\n \t\]*}" ++ [multi_line \ ++ "type = class crash {" \ ++ "" \ ++ " public:" \ ++ [string cat \ ++ [string_to_regexp " crash(int (class {...}::*)("] \ ++ $re_class_ptr_const \ ++ [string_to_regexp "));"]] \ ++ "}"] +diff --git a/gdb/testsuite/gdb.dwarf2/dw2-opt-structptr.exp b/gdb/testsuite/gdb.dwarf2/dw2-opt-structptr.exp +index cebed1d292b..d73f4a892ba 100644 +--- a/gdb/testsuite/gdb.dwarf2/dw2-opt-structptr.exp ++++ b/gdb/testsuite/gdb.dwarf2/dw2-opt-structptr.exp +@@ -126,6 +126,8 @@ proc build_test_program {} { + } + } + ++set re_address_class "@\[^\r\n\]+" ++ + # Test access to an optimized-out pointer-to-struct using the + # console interpreter. + +@@ -210,13 +212,18 @@ proc do_mi_test {} { + + # Test that -var-create for 'ptr' is successful. + mi_create_varobj "var1" "ptr" "create varobj for ptr" ++ ++ set struct_foo_ptr \ ++ [string cat \ ++ [string_to_regexp "struct foo *"] "( $::re_address_class)?"] + + # Test that -var-list-children of 'ptr' is successful. +- mi_list_varobj_children "var1" { \ +- {var1.a a 0 integer} \ +- {var1.x x 128 foo__array_type} \ +- {var1.y y 3 "struct foo \\*"} \ +- } "get children of var1 (ptr)" ++ mi_list_varobj_children "var1" \ ++ [list \ ++ {var1.a a 0 integer} \ ++ {var1.x x 128 foo__array_type} \ ++ [list "var1.y" "y" "3" $struct_foo_ptr]] \ ++ "get children of var1 (ptr)" + + # Test that dereferencing 'ptr' will throw an error. + mi_gdb_test "-var-create var2 * &((ptr)->a)" \ +diff --git a/gdb/testsuite/gdb.dwarf2/member-ptr-forwardref.exp b/gdb/testsuite/gdb.dwarf2/member-ptr-forwardref.exp +index c97c887d5a1..21ad111c9ac 100644 +--- a/gdb/testsuite/gdb.dwarf2/member-ptr-forwardref.exp ++++ b/gdb/testsuite/gdb.dwarf2/member-ptr-forwardref.exp +@@ -34,5 +34,19 @@ gdb_test "show cp-abi" {The currently selected C\+\+ ABI is "gnu-v3".*} + + gdb_load ${binfile} + ++set re_address_class "@\[^\r\n\]+" ++ ++set re_C_ptr \ ++ [string cat \ ++ [string_to_regexp "C *"] "( const)?( $re_address_class)?"] ++ + gdb_test_no_output "set language c++" +-gdb_test "ptype c" "type = struct C {\[\r\n \t\]*private:\[\r\n \t\]*int \\(C::\\*fp\\)\\(C \\*( const)?\\);\[\r\n \t\]*}" ++gdb_test "ptype c" \ ++ [multi_line \ ++ "type = struct C {" \ ++ " private:" \ ++ [string cat \ ++ [string_to_regexp " int (C::*fp)("] \ ++ $re_C_ptr \ ++ [string_to_regexp ");"]] \ ++ "}"] +-- +2.43.0 + diff --git a/import-fedora.sh b/import-fedora.sh index abefcac..a184d4d 100644 --- a/import-fedora.sh +++ b/import-fedora.sh @@ -6,15 +6,12 @@ skip_patches=( # Not applicable for openSUSE. gdb-add-index.patch gdb-6.3-rh-testversion-20041202.patch - gdb-6.6-buildid-locate-misleading-warning-missing-debuginfo-rhbz981154.patch gdb-6.8-bz466901-backtrace-full-prelinked.patch - gdb-container-rh-pkg.patch - # Fragile test-case, requires glibc to fail in a certain way. + # Dropped by fedora. gdb-rhbz1156192-recursive-dlopen-test.patch - - # Obsolete. - gdb-6.7-ppc-clobbered-registers-O2-test.patch + gdb-rhbz1261564-aarch64-hw-watchpoint-test.patch + gdb-test-bt-cfi-without-die.patch ) usage () diff --git a/make-pascal_language-print_type-handle-varstring-nul.patch b/make-pascal_language-print_type-handle-varstring-nul.patch deleted file mode 100644 index c838c98..0000000 --- a/make-pascal_language-print_type-handle-varstring-nul.patch +++ /dev/null @@ -1,43 +0,0 @@ -From f27cc602d85c46b46f5b02d6f584a1d872e098e3 Mon Sep 17 00:00:00 2001 -From: Tom Tromey -Date: Wed, 27 Mar 2024 10:34:46 -0600 -Subject: [PATCH] Make pascal_language::print_type handle varstring==nullptr - -PR gdb/31524 points out a crash when pascal_language::print_type is -called with varstring==nullptr. This crash is a regression arising -from the printf/pager rewrite -- that indirectly removed a NULL check -from gdb's "puts". - -This patch instead fixes the problem by adding a check to print_type. -Passing nullptr here seems to be expected in other places (e.g., there -is a call to type_print like this in expprint.c), and other -implementations of this method (or related helpers) explicitly check -for NULL. - -I didn't write a test case for this because it seemed like overkill -for a Pascal bug that only occurs with -i=mi. However, if you want -one, let me know and I will do it. - -Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31524 -Approved-By: John Baldwin ---- - gdb/p-typeprint.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/gdb/p-typeprint.c b/gdb/p-typeprint.c -index e8542d6845a..68a94a65f64 100644 ---- a/gdb/p-typeprint.c -+++ b/gdb/p-typeprint.c -@@ -55,7 +55,8 @@ pascal_language::print_type (struct type *type, const char *varstring, - type_print_varspec_prefix (type, stream, show, 0, flags); - } - /* first the name */ -- gdb_puts (varstring, stream); -+ if (varstring != nullptr) -+ gdb_puts (varstring, stream); - - if ((varstring != NULL && *varstring != '\0') - && !(code == TYPE_CODE_FUNC --- -2.35.3 - diff --git a/opcodes-fix-std-gnu23-compatibility-wrt-static_asser.patch b/opcodes-fix-std-gnu23-compatibility-wrt-static_asser.patch index 9072849..7db4d6d 100644 --- a/opcodes-fix-std-gnu23-compatibility-wrt-static_asser.patch +++ b/opcodes-fix-std-gnu23-compatibility-wrt-static_asser.patch @@ -1,7 +1,7 @@ -From ae87a62843b5f01be392addf150cc844e42950f8 Mon Sep 17 00:00:00 2001 +From 899cec1550fa94e4644a3d5be4a229eb89b856d3 Mon Sep 17 00:00:00 2001 From: Sam James -Date: Thu, 13 Mar 2025 15:09:52 +0100 -Subject: [PATCH 23/28] opcodes: fix -std=gnu23 compatibility wrt static_assert +Date: Fri, 7 Mar 2025 13:06:52 +0100 +Subject: [PATCH 05/10] opcodes: fix -std=gnu23 compatibility wrt static_assert static_assert is declared in C23 so we can't reuse that identifier: * Define our own static_assert conditionally; @@ -26,7 +26,7 @@ ChangeLog: 1 file changed, 2 insertions(+) diff --git a/opcodes/s390-opc.c b/opcodes/s390-opc.c -index b46f5d1705a..bd10777b52d 100644 +index 9d9f0973e55..49efd714157 100644 --- a/opcodes/s390-opc.c +++ b/opcodes/s390-opc.c @@ -36,7 +36,9 @@ diff --git a/powerpc-and-aarch64-fix-reverse-stepping-failure.patch b/powerpc-and-aarch64-fix-reverse-stepping-failure.patch deleted file mode 100644 index b1d37b7..0000000 --- a/powerpc-and-aarch64-fix-reverse-stepping-failure.patch +++ /dev/null @@ -1,478 +0,0 @@ -From b826313e55938c8cf83b0889e2f6bdf8129bc004 Mon Sep 17 00:00:00 2001 -From: Carl Love -Date: Tue, 2 Jan 2024 17:46:02 -0500 -Subject: [PATCH 07/48] PowerPC and aarch64: Fix reverse stepping failure - -When running GDB's testsuite on aarch64-linux/Ubuntu 20.04 (also spotted on -the ppc backend), there are failures in gdb.reverse/solib-precsave.exp and -gdb.reverse/solib-reverse.exp. - -The failure happens around the following code: - -38 b[1] = shr2(17); /* middle part two */ -40 b[0] = 6; b[1] = 9; /* generic statement, end part two */ -42 shr1 ("message 1\n"); /* shr1 one */ - -Normal execution: - -- step from line 38 will land on line 40. -- step from line 40 will land on line 42. - -Reverse execution: -- step from line 42 will land on line 40. -- step from line 40 will land on line 40. -- step from line 40 will land on line 38. - -The problem here is that line 40 contains two contiguous but distinct -PC ranges in the line table, like so: - -Line 40 - [0x7ec ~ 0x7f4] -Line 40 - [0x7f4 ~ 0x7fc] - -The two distinct ranges are generated because GCC started outputting source -column information, which GDB doesn't take into account at the moment. - -When stepping forward from line 40, we skip both of these ranges and land on -line 42. When stepping backward from line 42, we stop at the start PC of the -second (or first, going backwards) range of line 40. - -Since we've reached ecs->event_thread->control.step_range_start, we stop -stepping backwards. - -The above issues were fixed by introducing a new function that looks for -adjacent PC ranges for the same line, until we notice a line change. Then -we take that as the start PC of the range. The new start PC for the range -is used for the control.step_range_start when setting up a step range. - -The test case gdb.reverse/map-to-same-line.exp is added to test the fix -for the above reverse step issues. - -Patch has been tested on PowerPC, X86 and AArch64 with no regressions. ---- - gdb/infrun.c | 57 +++++++ - gdb/symtab.c | 50 ++++++ - gdb/symtab.h | 17 ++ - gdb/testsuite/gdb.reverse/map-to-same-line.c | 58 +++++++ - .../gdb.reverse/map-to-same-line.exp | 153 ++++++++++++++++++ - 5 files changed, 335 insertions(+) - create mode 100644 gdb/testsuite/gdb.reverse/map-to-same-line.c - create mode 100644 gdb/testsuite/gdb.reverse/map-to-same-line.exp - -diff --git a/gdb/infrun.c b/gdb/infrun.c -index 4730d290442..069ef144a76 100644 ---- a/gdb/infrun.c -+++ b/gdb/infrun.c -@@ -114,6 +114,8 @@ static struct async_event_handler *infrun_async_inferior_event_token; - /* Stores whether infrun_async was previously enabled or disabled. - Starts off as -1, indicating "never enabled/disabled". */ - static int infrun_is_async = -1; -+static CORE_ADDR update_line_range_start (CORE_ADDR pc, -+ struct execution_control_state *ecs); - - /* See infrun.h. */ - -@@ -6886,6 +6888,27 @@ handle_signal_stop (struct execution_control_state *ecs) - process_event_stop_test (ecs); - } - -+/* Return the address for the beginning of the line. */ -+ -+CORE_ADDR -+update_line_range_start (CORE_ADDR pc, struct execution_control_state *ecs) -+{ -+ /* The line table may have multiple entries for the same source code line. -+ Given the PC, check the line table and return the PC that corresponds -+ to the line table entry for the source line that PC is in. */ -+ CORE_ADDR start_line_pc = ecs->event_thread->control.step_range_start; -+ std::optional real_range_start; -+ -+ /* Call find_line_range_start to get the smallest address in the -+ linetable for multiple Line X entries in the line table. */ -+ real_range_start = find_line_range_start (pc); -+ -+ if (real_range_start.has_value ()) -+ start_line_pc = *real_range_start; -+ -+ return start_line_pc; -+} -+ - /* Come here when we've got some debug event / signal we can explain - (IOW, not a random signal), and test whether it should cause a - stop, or whether we should resume the inferior (transparently). -@@ -7687,6 +7710,29 @@ process_event_stop_test (struct execution_control_state *ecs) - - if (stop_pc_sal.is_stmt) - { -+ if (execution_direction == EXEC_REVERSE) -+ { -+ /* We are stepping backwards make sure we have reached the -+ beginning of the line. */ -+ CORE_ADDR stop_pc = ecs->event_thread->stop_pc (); -+ CORE_ADDR start_line_pc -+ = update_line_range_start (stop_pc, ecs); -+ -+ if (stop_pc != start_line_pc) -+ { -+ /* Have not reached the beginning of the source code line. -+ Set a step range. Execution should stop in any function -+ calls we execute back into before reaching the beginning -+ of the line. */ -+ ecs->event_thread->control.step_range_start -+ = start_line_pc; -+ ecs->event_thread->control.step_range_end = stop_pc; -+ set_step_info (ecs->event_thread, frame, stop_pc_sal); -+ keep_going (ecs); -+ return; -+ } -+ } -+ - /* We are at the start of a statement. - - So stop. Note that we don't stop if we step into the middle of a -@@ -7749,6 +7795,17 @@ process_event_stop_test (struct execution_control_state *ecs) - set_step_info (ecs->event_thread, frame, stop_pc_sal); - - infrun_debug_printf ("keep going"); -+ -+ if (execution_direction == EXEC_REVERSE) -+ { -+ CORE_ADDR stop_pc = ecs->event_thread->stop_pc (); -+ -+ /* Make sure the stop_pc is set to the beginning of the line. */ -+ if (stop_pc != ecs->event_thread->control.step_range_start) -+ ecs->event_thread->control.step_range_start -+ = update_line_range_start (stop_pc, ecs); -+ } -+ - keep_going (ecs); - } - -diff --git a/gdb/symtab.c b/gdb/symtab.c -index e9bc7b2c933..ef63ec93c5a 100644 ---- a/gdb/symtab.c -+++ b/gdb/symtab.c -@@ -73,6 +73,7 @@ - #include "gdbsupport/gdb_string_view.h" - #include "gdbsupport/pathstuff.h" - #include "gdbsupport/common-utils.h" -+#include - - /* Forward declarations for local functions. */ - -@@ -3311,6 +3312,55 @@ find_pc_line (CORE_ADDR pc, int notcurrent) - return sal; - } - -+/* Compare two symtab_and_line entries. Return true if both have -+ the same line number and the same symtab pointer. That means we -+ are dealing with two entries from the same line and from the same -+ source file. -+ -+ Return false otherwise. */ -+ -+static bool -+sal_line_symtab_matches_p (const symtab_and_line &sal1, -+ const symtab_and_line &sal2) -+{ -+ return sal1.line == sal2.line && sal1.symtab == sal2.symtab; -+} -+ -+/* See symtah.h. */ -+ -+std::optional -+find_line_range_start (CORE_ADDR pc) -+{ -+ struct symtab_and_line current_sal = find_pc_line (pc, 0); -+ -+ if (current_sal.line == 0) -+ return {}; -+ -+ struct symtab_and_line prev_sal = find_pc_line (current_sal.pc - 1, 0); -+ -+ /* If the previous entry is for a different line, that means we are already -+ at the entry with the start PC for this line. */ -+ if (!sal_line_symtab_matches_p (prev_sal, current_sal)) -+ return current_sal.pc; -+ -+ /* Otherwise, keep looking for entries for the same line but with -+ smaller PC's. */ -+ bool done = false; -+ CORE_ADDR prev_pc; -+ while (!done) -+ { -+ prev_pc = prev_sal.pc; -+ -+ prev_sal = find_pc_line (prev_pc - 1, 0); -+ -+ /* Did we notice a line change? If so, we are done searching. */ -+ if (!sal_line_symtab_matches_p (prev_sal, current_sal)) -+ done = true; -+ } -+ -+ return prev_pc; -+} -+ - /* See symtab.h. */ - - struct symtab * -diff --git a/gdb/symtab.h b/gdb/symtab.h -index 365743384e1..e17d15c595b 100644 ---- a/gdb/symtab.h -+++ b/gdb/symtab.h -@@ -38,6 +38,7 @@ - #include "gdb-demangle.h" - #include "split-name.h" - #include "frame.h" -+#include - - /* Opaque declarations. */ - struct ui_file; -@@ -2362,6 +2363,22 @@ extern struct symtab_and_line find_pc_line (CORE_ADDR, int); - extern struct symtab_and_line find_pc_sect_line (CORE_ADDR, - struct obj_section *, int); - -+/* Given PC, and assuming it is part of a range of addresses that is part of -+ a line, go back through the linetable and find the starting PC of that -+ line. -+ -+ For example, suppose we have 3 PC ranges for line X: -+ -+ Line X - [0x0 - 0x8] -+ Line X - [0x8 - 0x10] -+ Line X - [0x10 - 0x18] -+ -+ If we call the function with PC == 0x14, we want to return 0x0, as that is -+ the starting PC of line X, and the ranges are contiguous. -+*/ -+ -+extern std::optional find_line_range_start (CORE_ADDR pc); -+ - /* Wrapper around find_pc_line to just return the symtab. */ - - extern struct symtab *find_pc_line_symtab (CORE_ADDR); -diff --git a/gdb/testsuite/gdb.reverse/map-to-same-line.c b/gdb/testsuite/gdb.reverse/map-to-same-line.c -new file mode 100644 -index 00000000000..3086e849231 ---- /dev/null -+++ b/gdb/testsuite/gdb.reverse/map-to-same-line.c -@@ -0,0 +1,58 @@ -+/* Copyright 2023 Free Software Foundation, Inc. -+ -+ 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 . */ -+ -+/* The purpose of this test is to create a DWARF line table that contains two -+ or more entries for the same line. When stepping (forwards or backwards), -+ GDB should step over the entire line and not just a particular entry in -+ the line table. */ -+ -+int -+main (void) -+{ /* TAG: main prologue */ -+ asm ("main_label: .globl main_label"); -+ int i = 1, j = 2, k; -+ float f1 = 2.0, f2 = 4.1, f3; -+ const char *str_1 = "foo", *str_2 = "bar", *str_3; -+ -+ asm ("line1: .globl line1"); -+ k = i; f3 = f1; str_3 = str_1; /* TAG: line 1 */ -+ -+ asm ("line2: .globl line2"); -+ k = j; f3 = f2; str_3 = str_2; /* TAG: line 2 */ -+ -+ asm ("line3: .globl line3"); -+ k = i; f3 = f1; str_3 = str_1; /* TAG: line 3 */ -+ -+ asm ("line4: .globl line4"); -+ k = j; f3 = f2; str_3 = str_2; /* TAG: line 4 */ -+ -+ asm ("line5: .globl line5"); -+ k = i; f3 = f1; str_3 = str_1; /* TAG: line 5 */ -+ -+ asm ("line6: .globl line6"); -+ k = j; f3 = f2; str_3 = str_2; /* TAG: line 6 */ -+ -+ asm ("line7: .globl line7"); -+ k = i; f3 = f1; str_3 = str_1; /* TAG: line 7 */ -+ -+ asm ("line8: .globl line8"); -+ k = j; f3 = f2; str_3 = str_2; /* TAG: line 8 */ -+ -+ asm ("main_return: .globl main_return"); -+ k = j; f3 = f2; str_3 = str_2; /* TAG: main return */ -+ -+ asm ("end_of_sequence: .globl end_of_sequence"); -+ return 0; /* TAG: main return */ -+} -diff --git a/gdb/testsuite/gdb.reverse/map-to-same-line.exp b/gdb/testsuite/gdb.reverse/map-to-same-line.exp -new file mode 100644 -index 00000000000..63f8c9c76b3 ---- /dev/null -+++ b/gdb/testsuite/gdb.reverse/map-to-same-line.exp -@@ -0,0 +1,153 @@ -+# Copyright 2023 Free Software Foundation, Inc. -+ -+# 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 . -+ -+# When stepping (forwards or backwards), GDB should step over the entire line -+# and not just a particular entry in the line table. This test was added to -+# verify the find_line_range_start function properly sets the step range for a -+# line that consists of multiple statements, i.e. multiple entries in the line -+# table. This test creates a DWARF line table that contains two entries for -+# the same line to do the needed testing. -+ -+# This test can only be run on targets which support DWARF-2 and use gas. -+load_lib dwarf.exp -+require dwarf2_support -+ -+# The DWARF assembler requires the gcc compiler. -+require is_c_compiler_gcc -+ -+# This test suitable only for process that can do reverse execution -+require supports_reverse -+ -+standard_testfile .c .S -+ -+if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { -+ return -1 -+} -+ -+set asm_file [standard_output_file $srcfile2] -+Dwarf::assemble $asm_file { -+ global srcdir subdir srcfile -+ declare_labels integer_label L -+ -+ # Find start address and length of program -+ lassign [function_range main [list ${srcdir}/${subdir}/$srcfile]] \ -+ main_start main_len -+ set main_end "$main_start + $main_len" -+ -+ cu {} { -+ compile_unit { -+ {language @DW_LANG_C} -+ {name map-to-same-line.c} -+ {stmt_list $L DW_FORM_sec_offset} -+ {low_pc 0 addr} -+ } { -+ subprogram { -+ {external 1 flag} -+ {name main} -+ {low_pc $main_start addr} -+ {high_pc $main_len DW_FORM_data4} -+ } -+ } -+ } -+ -+ lines {version 2 default_is_stmt 1} L { -+ include_dir "${srcdir}/${subdir}" -+ file_name "$srcfile" 1 -+ -+ # Generate the line table program with distinct source lines being -+ # mapped to the same line entry. Line 1, 5 and 8 contain 1 statement -+ # each. Line 2 contains 2 statements. Line 3 contains 3 statements. -+ program { -+ DW_LNE_set_address $main_start -+ line [gdb_get_line_number "TAG: main prologue"] -+ DW_LNS_copy -+ DW_LNE_set_address line1 -+ line [gdb_get_line_number "TAG: line 1" ] -+ DW_LNS_copy -+ DW_LNE_set_address line2 -+ line [gdb_get_line_number "TAG: line 2" ] -+ DW_LNS_copy -+ DW_LNE_set_address line3 -+ line [gdb_get_line_number "TAG: line 2" ] -+ DW_LNS_copy -+ DW_LNE_set_address line4 -+ line [gdb_get_line_number "TAG: line 3" ] -+ DW_LNS_copy -+ DW_LNE_set_address line5 -+ line [gdb_get_line_number "TAG: line 3" ] -+ DW_LNS_copy -+ DW_LNE_set_address line6 -+ line [gdb_get_line_number "TAG: line 3" ] -+ DW_LNS_copy -+ DW_LNE_set_address line7 -+ line [gdb_get_line_number "TAG: line 5" ] -+ DW_LNS_copy -+ DW_LNE_set_address line8 -+ line [gdb_get_line_number "TAG: line 8" ] -+ DW_LNS_copy -+ DW_LNE_set_address main_return -+ line [gdb_get_line_number "TAG: main return"] -+ DW_LNS_copy -+ DW_LNE_set_address end_of_sequence -+ DW_LNE_end_sequence -+ } -+ } -+} -+ -+if { [prepare_for_testing "failed to prepare" ${testfile} \ -+ [list $srcfile $asm_file] {nodebug} ] } { -+ return -1 -+} -+ -+if { ![runto_main] } { -+ return -+} -+ -+# Print the line table -+gdb_test_multiple "maint info line-table ${testfile}" "" { -+ -re "\r\n$decimal\[ \t\]+$decimal\[ \t\]+($hex)\[ \t\]+Y\[^\r\n\]*" { -+ lappend is_stmt $expect_out(1,string) -+ exp_continue -+ } -+ -re -wrap "" { -+ } -+} -+ -+# Do the reverse-step and reverse-next tests -+foreach_with_prefix cmd {step next} { -+ gdb_test_no_output "record" "turn on process record, test $cmd" -+ -+ set bp_main_return [gdb_get_line_number "TAG: main return" $srcfile] -+ gdb_breakpoint $srcfile:$bp_main_return -+ gdb_continue_to_breakpoint "run to end of main, reverse-$cmd test" ".*$srcfile:$bp_main_return.*" -+ gdb_test "display \$pc" ".*pc =.*" "display pc, reverse-$cmd test" -+ -+ # At this point, GDB has already recorded the execution up until the return -+ # statement. Reverse and test if GDB transitions between lines in the -+ # expected order. It should reverse-step or reverse-next across lines 8, -+ # 5, 3, 2 and 1. -+ foreach line {8 5 3 2 1} { -+ gdb_test "reverse-$cmd" ".*TAG: line $line.*" "reverse $cmd to line $line" -+ } -+ -+ if {$cmd =="step"} { -+ ## Clean restart, test reverse-next command -+ clean_restart ${testfile} -+ -+ if { ![runto_main] } { -+ return -+ } -+ } -+} --- -2.35.3 - diff --git a/powerpc-fix-test-gdb.ada-finish-large.exp.patch b/powerpc-fix-test-gdb.ada-finish-large.exp.patch deleted file mode 100644 index ef9899b..0000000 --- a/powerpc-fix-test-gdb.ada-finish-large.exp.patch +++ /dev/null @@ -1,49 +0,0 @@ -From d95be7a5210b69ad879c86d23efaa2cd7dcda94a Mon Sep 17 00:00:00 2001 -From: Carl Love -Date: Mon, 20 Nov 2023 11:13:22 -0500 -Subject: [PATCH] PowerPC: Fix test gdb.ada/finish-large.exp - -Function Create_large returns a large data structure. On PowerPC, register -r3 contains the address of where the data structure to be returned is to -be stored. However, on exit the ABI does not guarantee that r3 has not -been changed. The GDB finish command prints the return value of the -function at the end of the function. GDB needs to use the -DW_TAG_call_site information to determine the value of r3 on entry to -the function to correctly print the return value at the end of the -function. The test must be compiled with -fvar-tracking for the -DW_TAG_call_site information to be included in the executable file. - -This patch adds the -fvar-tracking option to the compile line if the -option is supported. - -The patch fixes the one regression error for the test on PowerPC. - -The patch has been tested on Power 10 and X86-64 with no regressions. ---- - gdb/testsuite/gdb.ada/finish-large.exp | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/gdb/testsuite/gdb.ada/finish-large.exp b/gdb/testsuite/gdb.ada/finish-large.exp -index 5661d132a18..6c8b1b2648d 100644 ---- a/gdb/testsuite/gdb.ada/finish-large.exp -+++ b/gdb/testsuite/gdb.ada/finish-large.exp -@@ -19,7 +19,13 @@ require allow_ada_tests - - standard_ada_testfile p - --if {[gdb_compile_ada "${srcfile}" "${binfile}" executable debug] != ""} { -+set flags {debug} -+ -+if {[have_fvar_tracking]} { -+ lappend flags "additional_flags=-fvar-tracking" -+} -+ -+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable $flags] != ""} { - return -1 - } - - -base-commit: 0397481ff25b76d43b123f3d51828982ceb92834 --- -2.35.3 - diff --git a/qa-local.sh b/qa-local.sh index a41d7ea..d845054 100644 --- a/qa-local.sh +++ b/qa-local.sh @@ -10,17 +10,17 @@ pkgs=$root/pkgs configs=" openSUSE_Leap_15.6 -openSUSE_Leap_15.5 openSUSE_Factory openSUSE_Factory_LegacyX86 SLE-15 SLE-12 +16.0 SLFO " archs="x86_64 i586" -version=14.2 +version=15.2 usage () { @@ -83,7 +83,7 @@ have_combo () if [ "$arch" = "i586" ]; then case " $c " in - " openSUSE_Factory "|" SLFO ") + " openSUSE_Factory "|" SLFO "|" 16.0 ") # Doesn't have i586. return 1 ;; @@ -227,7 +227,7 @@ case "$n" in fi echo "CONFIG: $c $arch" case $c in - openSUSE_Factory|openSUSE_Factory_LegacyX86|SLFO) + openSUSE_Factory|openSUSE_Factory_LegacyX86|SLFO|16.0) bash qa.sh -local -$arch -factory $pkgs/gdb-testresults.$c.$arch ;; SLE-12) diff --git a/qa.sh b/qa.sh index 14b2145..292db8b 100644 --- a/qa.sh +++ b/qa.sh @@ -139,13 +139,20 @@ report_sum () kfail=( + # https://sourceware.org/bugzilla/show_bug.cgi?id=32608 + "FAIL: gdb.threads/step-over-thread-exit-while-stop-all-threads.exp: displaced-stepping=auto: target-non-stop=on: iter .*: continue" + + # https://sourceware.org/bugzilla/show_bug.cgi?id=31721 + "FAIL: gdb.base/list-dot-nodebug.exp: debug=none: print before start" + "FAIL: gdb.base/list-dot-nodebug.exp: debug=some: print before start" + # https://sourceware.org/bugzilla/show_bug.cgi?id=26971 "FAIL: gdb.arch/amd64-init-x87-values.exp: check_x87_regs_around_init: check post FLD1 value of .fop" "FAIL: gdb.arch/amd64-init-x87-values.exp: check_x87_regs_around_init: check post FLD1 value of .fioff" # https://sourceware.org/bugzilla/show_bug.cgi?id=24845 - "FAIL: gdb.base/step-over-syscall.exp: clone: displaced=off: single step over clone" - "FAIL: gdb.base/step-over-syscall.exp: clone: displaced=off: continue to marker \(clone\)" + "FAIL: gdb.base/step-over-syscall.exp: clone: displaced=(off|on): single step over clone" + "FAIL: gdb.base/step-over-syscall.exp: clone: displaced=(off|on): continue to marker \(clone\)" # https://sourceware.org/bugzilla/show_bug.cgi?id=19436#c1 "FAIL: gdb.cp/no-dmgl-verbose.exp: setting breakpoint at 'f\(std::string\)'" @@ -351,6 +358,15 @@ kfail=( # https://sourceware.org/bugzilla/show_bug.cgi?id=32439 "FAIL: gdb.base/step-over-syscall.exp: (fork|vfork): displaced=on: check_pc_after_cross_syscall: single step over (fork|vfork) final pc" + # https://sourceware.org/bugzilla/show_bug.cgi?id=32619 + "FAIL: gdb.dap/eof.exp: exceptions in log file" + + # https://sourceware.org/bugzilla/show_bug.cgi?id=32167 + "FAIL: gdb.base/bp-cmds-continue-ctrl-c.exp: (attach|run): stop with control-c" + + # https://sourceware.org/bugzilla/show_bug.cgi?id=32688 + "FAIL: gdb.threads/thread-specific-bp.exp: non_stop=on: continue to end" + ) # kfail kfail_sle12=( @@ -420,6 +436,7 @@ kfail_sle12=( "FAIL: gdb.dwarf2/frame-inlined-in-outer-frame.exp: step back into foo" "FAIL: gdb.dwarf2/frame-inlined-in-outer-frame.exp: step into bar" "FAIL: gdb.dwarf2/frame-inlined-in-outer-frame.exp: step into foo" + "FAIL: gdb.base/list-dot-nodebug.exp: debug=none: runto: run to bar" # Fails on both i586 and s390x/-m31 for SLE-12-SP3, but does not reproduce # on s390x/-m31 for SLE-12-SP5 with trunk. @@ -434,6 +451,13 @@ kfail_sle12=( "FAIL: gdb.threads/clone-thread_db.exp: continue to clone_fn \(the program exited\)" "FAIL: gdb.threads/clone-thread_db.exp: continue to end \(the program is no longer running\)" + # FAILs due to gcc 4.8.5 DW_TAG_lexical_block oddity. + "FAIL: gdb.python/py-type.exp: lang_cpp: test_fields: python print \(gdb.lookup_type \('main\(\)::IntType'\)\)" + "FAIL: gdb.python/py-type.exp: lang_cpp: test_fields: python print \(gdb.lookup_type \('main\(\)::IntType'\).target \(\)\)" + + # SLE-12, aarch64, ppc64le, g++ missing. + "FAIL: gdb.dwarf2/missing-type-name-for-templates.exp:" + ) # kfail_sle12 kfail_sle11=( @@ -523,13 +547,16 @@ kfail_factory=( # https://sourceware.org/bugzilla/show_bug.cgi?id=31564 "FAIL: gdb.base/rtld-step.exp: runto: run to main" + # https://sourceware.org/bugzilla/show_bug.cgi?id=32678 + "FAIL: gdb.reverse/time-reverse.exp: mode=c:" + ) # kfail_factory kfail_aarch64=( # https://sourceware.org/bugzilla/show_bug.cgi?id=29405 - "FAIL: gdb.base/step-over-syscall.exp: (fork|vfork): displaced=(on|off): pc after stepi matches insn addr after syscall" - "FAIL: gdb.base/step-over-syscall.exp: (fork|vfork): displaced=(on|off): check_pc_after_cross_syscall: single step over fork final pc" + "FAIL: gdb.base/step-over-syscall.exp: (clone|fork|vfork): displaced=(on|off): pc after stepi matches insn addr after syscall" + "FAIL: gdb.base/step-over-syscall.exp: (clone|fork|vfork): displaced=(on|off): check_pc_after_cross_syscall: single step over (clone|fork|vfork) final pc" # https://sourceware.org/bugzilla/show_bug.cgi?id=29423 "FAIL: gdb.base/watchpoint-unaligned.exp: continue \(timeout\)" @@ -630,6 +657,11 @@ kfail_powerpc64le=( "FAIL: gdb.python/py-breakpoint.exp: test_watchpoints: Test watchpoint write \(the program exited\)" "FAIL: gdb.python/py-breakpoint.exp: test_bkpt_internal: Test watchpoint write \(the program exited\)" "FAIL: gdb.python/py-breakpoint.exp: test_bkpt_eval_funcs: Test watchpoint write \(the program exited\)" + "FAIL: gdb.base/memops-watchpoint.exp: continue until memcpy watchpoint hits" + "FAIL: gdb.base/memops-watchpoint.exp: continue until memmove watchpoint hits" + "FAIL: gdb.base/memops-watchpoint.exp: continue until memset watchpoint hits" + "FAIL: gdb.base/watchpoint-running.exp: all-stop: hardware: watchpoint hit" + "FAIL: gdb.base/watchpoint-running.exp: non-stop: hardware: watchpoint hit" # https://sourceware.org/bugzilla/show_bug.cgi?id=31004 "FAIL: gdb.base/run-control-while-bg-execution.exp: action1=.*: action2=run: run" @@ -644,8 +676,12 @@ kfail_powerpc64le=( # https://sourceware.org/bugzilla/show_bug.cgi?id=31827 "FAIL: gdb.base/gnu_vector.exp: call add_structvecs" - # Failures on opensuse Leap 15.6. To be reproduced and investigated. + # GLIBC problem with prctl on ppc64le. Fixed in 2.40. + # https://sourceware.org/bugzilla/show_bug.cgi?id=29770 + # https://bugzilla.suse.com/show_bug.cgi?id=1234665 "FAIL: gdb.ada/tasks.exp: info threads" + + # https://sourceware.org/bugzilla/show_bug.cgi?id=31229 "FAIL: gdb.linespec/explicit.exp: complete after -qualified -source: cmd complete .b -qualified -source thr." "FAIL: gdb.linespec/explicit.exp: complete after -qualified -source: tab complete .b -qualified -source thr." "FAIL: gdb.linespec/explicit.exp: complete after -source: cmd complete .b -source thr." @@ -737,6 +773,7 @@ kfail_i586=( "FAIL: gdb.base/valgrind-disp-step.exp:" "FAIL: gdb.base/valgrind-infcall-2.exp:" "FAIL: gdb.base/valgrind-infcall.exp:" + ) kfail_arm=( @@ -854,6 +891,8 @@ case $n in # https://sourceware.org/bugzilla/show_bug.cgi?id=32446 "linux-nat.c:[0-9]*: internal-error: mark_lwp_dead: Assertion .lp->status == 0. failed\." + # https://sourceware.org/bugzilla/show_bug.cgi?id=32712 + "thread\.c:[0-9]*: internal-error: set_thread_options: Assertion .!this->executing \(\). failed\." ) kfail_re=$(join "|" "${kfail[@]}") @@ -865,8 +904,8 @@ case $n in 4) for id in SLE-12 \ SLE-15 \ + 16.0 \ SLFO \ - openSUSE_Leap_15.5 \ openSUSE_Leap_15.6 \ openSUSE_Factory; \ do @@ -879,11 +918,11 @@ case $n in config=$id.$arch case $config in - SLE-15.i586|SLE-12.i586|SLFO.i586) + SLE-15.i586|SLE-12.i586|SLFO.i586|16.0.i586) # No such config. continue ;; - SLFO.ppc64le|openSUSE_Factory.ppc64le|*.s390x) + SLFO.ppc64le|16.0.ppc64le|openSUSE_Factory.ppc64le|*.s390x) # Not cleaned up yet. continue ;; @@ -982,7 +1021,7 @@ case $n in SLE-12) kfail+=("${kfail_sle12[@]}") ;; - SLFO|openSUSE_Factory) + SLFO|openSUSE_Factory|16.0) kfail+=("${kfail_factory[@]}") ;; *) diff --git a/rs6000-unwind-on-each-instruction-fix.patch b/rs6000-unwind-on-each-instruction-fix.patch deleted file mode 100644 index 75d1ff3..0000000 --- a/rs6000-unwind-on-each-instruction-fix.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 6d21f33bb8f63d1d9aeda88ca815e442da0dc160 Mon Sep 17 00:00:00 2001 -From: Carl Love -Date: Tue, 23 Jan 2024 17:12:34 -0500 -Subject: [PATCH 1/2] rs6000, unwind-on-each-instruction fix. - -The function rs6000_epilogue_frame_cache assumes the LR and gprs have been -restored. In fact register r31 and the link register, lr, may not have -been restored yet. This patch adds support to store the lr and gpr -register unrolling rules in the cache. The LR and GPR values can now be -unrolled correctly. - -Patch fixes all 10 regresion test failures for the unwind-on-each-insn.exp. ---- - gdb/rs6000-tdep.c | 53 +++++++++++++++++++++++++++++++++++++++++------ - 1 file changed, 47 insertions(+), 6 deletions(-) - -diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c -index 23397d037ae..ecc8766d319 100644 ---- a/gdb/rs6000-tdep.c -+++ b/gdb/rs6000-tdep.c -@@ -3805,6 +3805,8 @@ rs6000_epilogue_frame_cache (frame_info_ptr this_frame, void **this_cache) - struct rs6000_frame_cache *cache; - struct gdbarch *gdbarch = get_frame_arch (this_frame); - ppc_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); -+ struct rs6000_framedata fdata; -+ int wordsize = tdep->wordsize; - - if (*this_cache) - return (struct rs6000_frame_cache *) *this_cache; -@@ -3815,17 +3817,56 @@ rs6000_epilogue_frame_cache (frame_info_ptr this_frame, void **this_cache) - - try - { -- /* At this point the stack looks as if we just entered the -- function, and the return address is stored in LR. */ -- CORE_ADDR sp, lr; -+ /* At this point the stack looks as if we just entered the function. -+ The SP (r1) has been restored but the LR and r31 may not have been -+ restored yet. Need to update the register unrolling information in -+ the cache for the LR and the saved gprs. */ -+ CORE_ADDR sp; -+ CORE_ADDR func = 0, pc = 0; - -- sp = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch)); -- lr = get_frame_register_unsigned (this_frame, tdep->ppc_lr_regnum); -+ func = get_frame_func (this_frame); -+ cache->pc = func; -+ pc = get_frame_pc (this_frame); -+ skip_prologue (gdbarch, func, pc, &fdata); -+ -+ /* SP is in r1 and it has been restored. Get the current value. */ -+ sp = get_frame_register_unsigned (this_frame, -+ gdbarch_sp_regnum (gdbarch)); - - cache->base = sp; - cache->initial_sp = sp; - -- cache->saved_regs[gdbarch_pc_regnum (gdbarch)].set_value (lr); -+ /* Store the unwinding rules for the gpr registers that have not been -+ restored yet, specifically r31. -+ -+ if != -1, fdata.saved_gpr is the smallest number of saved_gpr. -+ All gpr's from saved_gpr to gpr31 are saved (except during the -+ prologue). */ -+ -+ if (fdata.saved_gpr >= 0) -+ { -+ int i; -+ CORE_ADDR gpr_addr = cache->base + fdata.gpr_offset; -+ -+ for(i = fdata.saved_gpr; i < ppc_num_gprs; i++) -+ { -+ if (fdata.gpr_mask & (1U << i)) -+ cache->saved_regs[tdep->ppc_gp0_regnum + i].set_addr (gpr_addr); -+ gpr_addr += wordsize; -+ } -+ } -+ -+ /* Store the lr unwinding rules. */ -+ if (fdata.lr_offset != 0) -+ cache->saved_regs[tdep->ppc_lr_regnum].set_addr (cache->base -+ + fdata.lr_offset); -+ -+ else if (fdata.lr_register != -1) -+ cache->saved_regs[tdep->ppc_lr_regnum].set_realreg (fdata.lr_register); -+ -+ /* The PC is found in the link register. */ -+ cache->saved_regs[gdbarch_pc_regnum (gdbarch)] -+ = cache->saved_regs[tdep->ppc_lr_regnum]; - } - catch (const gdb_exception_error &ex) - { - -base-commit: 800e56a120419b457ebda18c5478ebfea99f9b3a --- -2.35.3 - diff --git a/s390-add-arch15-concurrent-functions-facility-insns.patch b/s390-add-arch15-concurrent-functions-facility-insns.patch index ad276f7..2b61cd3 100644 --- a/s390-add-arch15-concurrent-functions-facility-insns.patch +++ b/s390-add-arch15-concurrent-functions-facility-insns.patch @@ -1,7 +1,7 @@ -From 8b0a978d269682ce46bd2be6ae1c8f4240ff6b50 Mon Sep 17 00:00:00 2001 +From e709a3a30769a61def5e0995e8b4b0d94815e6ea Mon Sep 17 00:00:00 2001 From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:52 +0100 -Subject: [PATCH 25/28] s390: Add arch15 Concurrent-Functions Facility insns +Date: Fri, 7 Mar 2025 13:06:53 +0100 +Subject: [PATCH 07/10] s390: Add arch15 Concurrent-Functions Facility insns opcodes/ * s390-opc.txt: Add arch15 Concurrent-Functions Facility @@ -25,7 +25,7 @@ Signed-off-by: Jens Remus 2 files changed, 10 insertions(+) diff --git a/opcodes/s390-opc.c b/opcodes/s390-opc.c -index bd10777b52d..4729da2ee20 100644 +index 49efd714157..23c1c3a24e5 100644 --- a/opcodes/s390-opc.c +++ b/opcodes/s390-opc.c @@ -468,6 +468,7 @@ unused_s390_operands_static_asserts (void) @@ -45,7 +45,7 @@ index bd10777b52d..4729da2ee20 100644 #define MASK_S_00 { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } #define MASK_S_RD { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } diff --git a/opcodes/s390-opc.txt b/opcodes/s390-opc.txt -index dfdf695d44e..ec8ddb06f5a 100644 +index 82d6f06a992..68d8896bf4e 100644 --- a/opcodes/s390-opc.txt +++ b/opcodes/s390-opc.txt @@ -2190,3 +2190,11 @@ e6000000004a vcvdq VRI_VV0UU "vector convert to decimal 128 bit" arch15 zarch diff --git a/s390-add-arch15-instruction-names.patch b/s390-add-arch15-instruction-names.patch index c5904a6..131abe1 100644 --- a/s390-add-arch15-instruction-names.patch +++ b/s390-add-arch15-instruction-names.patch @@ -1,7 +1,7 @@ -From fc1b27e77b0ee875bfd9f0d57558a0a6883bd318 Mon Sep 17 00:00:00 2001 +From b813112665aa35b5d5f7f76f26b0f3035bc5a98b Mon Sep 17 00:00:00 2001 From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:52 +0100 -Subject: [PATCH 24/28] s390: Add arch15 instruction names +Date: Fri, 7 Mar 2025 13:06:52 +0100 +Subject: [PATCH 06/10] s390: Add arch15 instruction names opcodes/ * s390-opc.txt: Add arch15 instruction names. @@ -14,7 +14,7 @@ Signed-off-by: Jens Remus 1 file changed, 114 insertions(+), 106 deletions(-) diff --git a/opcodes/s390-opc.txt b/opcodes/s390-opc.txt -index f42d1861267..dfdf695d44e 100644 +index bbc00b10355..82d6f06a992 100644 --- a/opcodes/s390-opc.txt +++ b/opcodes/s390-opc.txt @@ -2076,109 +2076,117 @@ b28f qpaci S_RD "query processor activity counter information" arch14 zarch diff --git a/s390-add-arch15-instructions.patch b/s390-add-arch15-instructions.patch index 6de183e..8f56af5 100644 --- a/s390-add-arch15-instructions.patch +++ b/s390-add-arch15-instructions.patch @@ -1,7 +1,7 @@ -From ae4e8d3809f391d10631a0b00d92b60531cea5fe Mon Sep 17 00:00:00 2001 +From e6ae6b0fa91079a90643c04a57a9efdb2b97644c Mon Sep 17 00:00:00 2001 From: Andreas Krebbel -Date: Thu, 13 Mar 2025 15:09:52 +0100 -Subject: [PATCH 22/28] s390: Add arch15 instructions +Date: Fri, 7 Mar 2025 13:06:52 +0100 +Subject: [PATCH 04/10] s390: Add arch15 instructions opcodes/ * s390-mkopc.c (main) Accept arch15 as CPU string. @@ -38,7 +38,7 @@ Reviewed-by: Jens Remus 4 files changed, 128 insertions(+), 3 deletions(-) diff --git a/include/opcode/s390.h b/include/opcode/s390.h -index 19f973a7306..b1d5be374a3 100644 +index 8de03701172..8322882410e 100644 --- a/include/opcode/s390.h +++ b/include/opcode/s390.h @@ -45,6 +45,7 @@ enum s390_opcode_cpu_val @@ -50,7 +50,7 @@ index 19f973a7306..b1d5be374a3 100644 }; diff --git a/opcodes/s390-mkopc.c b/opcodes/s390-mkopc.c -index 4bab358378d..a0ac29eb273 100644 +index 1f5729a3db0..825188407ee 100644 --- a/opcodes/s390-mkopc.c +++ b/opcodes/s390-mkopc.c @@ -443,6 +443,8 @@ main (void) @@ -63,7 +63,7 @@ index 4bab358378d..a0ac29eb273 100644 print_error ("Mnemonic \"%s\": Couldn't parse CPU string: %s\n", mnemonic, cpu_string); diff --git a/opcodes/s390-opc.c b/opcodes/s390-opc.c -index 4fd0065a058..b46f5d1705a 100644 +index fe0299aa4e5..9d9f0973e55 100644 --- a/opcodes/s390-opc.c +++ b/opcodes/s390-opc.c @@ -228,7 +228,9 @@ const struct s390_operand s390_operands[] = @@ -140,7 +140,7 @@ index 4fd0065a058..b46f5d1705a 100644 #define MASK_VRR_RV0U { 0xff, 0x00, 0xff, 0x0f, 0xf0, 0xff } #define MASK_VRR_RV0UU { 0xff, 0x00, 0xff, 0x00, 0xf0, 0xff } diff --git a/opcodes/s390-opc.txt b/opcodes/s390-opc.txt -index 39a296e948f..f42d1861267 100644 +index 4610a8fddd7..bbc00b10355 100644 --- a/opcodes/s390-opc.txt +++ b/opcodes/s390-opc.txt @@ -2072,3 +2072,113 @@ b201 stbear S_RD "store bear" arch14 zarch diff --git a/s390-add-missing-extended-mnemonics.patch b/s390-add-missing-extended-mnemonics.patch deleted file mode 100644 index 66b3348..0000000 --- a/s390-add-missing-extended-mnemonics.patch +++ /dev/null @@ -1,265 +0,0 @@ -From 336eb31782dab43835d02969ecc8f5c1bfd84a16 Mon Sep 17 00:00:00 2001 -From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:45 +0100 -Subject: [PATCH 03/28] s390: Add missing extended mnemonics - -Add extended mnemonics specified in the z/Architecture Principles of -Operation [1] and z/Architecture Reference Summary [2], that were -previously missing from the opcode table. - -The following added extended mnemonics are synonyms to a base mnemonic -and therefore disassemble into their base mnemonic: -jc, jcth, lfi, llgfi, llghi - -The following added extended mnemonics are more specific than their base -mnemonic and therefore disassemble into the added extended mnemonic: -risbhgz, risblgz, rnsbgt, rosbgt, rxsbgt - -The following added extended mnemonics are more specific than their base -mnemonic, but disassemble into their base mnemonic due to design -constraints: -notr, notgr - -The missing extended mnemonic jl* conditional jump long flavors cannot -be added, as they would clash with the existing non-standard extended -mnemonic j* conditional jump flavors jle and jlh. The missing extended -mnemonic jlc jump long conditional is not added, as the related jl* -flavors cannot be added. -Note that these missing jl* conditional jump long flavors are already -defined as non-standard jg* flavors instead. While the related missing -extended mnemonic jlc could be added as non-standard jgc instead it is -forgone in favor of not adding further non-standard mnemonics. - -The missing extended mnemonics sllhh, sllhl, slllh, srlhh, srlhl, and -srllh cannot be implemented using the current design, as they require -computed operands. For that reason the following missing extended -mnemonics are not added as well, as they fall into the same category of -instructions that operate on high and low words of registers. They -should better be added together, not to confuse the user, which of those -instructions are currently implemented or not. -lhhr, lhlr, llhfr, llchhr, llchlr, llclhr, llhhhr, llhhlr, llhlhr, -nhhr, nhlr, nlhr, ohhr, ohlr, olhr, xhhr, xhlr, xlhr - -[1] IBM z/Architecture Principles of Operation, SA22-7832-13, IBM z16, - https://publibfp.dhe.ibm.com/epubs/pdf/a227832d.pdf -[2] IBM z/Architecture Reference Summary, SA22-7871-11, - https://www.ibm.com/support/pages/sites/default/files/2022-09/SA22-7871-11.pdf - -opcodes/ - * s390-opc.c: Define operand formats R_CP16_28, U6_18, and - U5_27. Define instruction formats RIE_RRUUU3, RIE_RRUUU4, - and RRF_R0RR4. - * s390-opc.txt: Add extended mnemonics jc, jcth, lfi, llgfi, - llghi, notgr, notr, risbhgz, risblgz, rnsbgt, rosbgt, and - rxsbgt. - -gas/ - * config/tc-s390.c: Add support to insert operand for format - R_CP16_28, reusing existing logic for format V_CP16_12. - * testsuite/gas/s390/esa-g5.s: Add test for extended mnemonic - jc. - * testsuite/gas/s390/esa-g5.d: Likewise. - * testsuite/gas/s390/zarch-z900.s: Add test for extended - mnemonic llghi. - * testsuite/gas/s390/zarch-z900.d: Likewise. - * testsuite/gas/s390/zarch-z9-109.s: Add tests for extended - mnemonics lfi and llgfi. - * testsuite/gas/s390/zarch-z9-109.d: Likewise. - * testsuite/gas/s390/zarch-z10.s: Add tests for extended - mnemonics rnsbgt, rosbgt, and rxsbgt. - * testsuite/gas/s390/zarch-z10.d: Likewise. - * testsuite/gas/s390/zarch-z196.s: Add tests for extended - mnemonics jcth, risbhgz, and risblgz. - * testsuite/gas/s390/zarch-z196.d: Likewise. - * testsuite/gas/s390/zarch-arch13.s: Add tests for extended - mnemonics notr and notgr. - * testsuite/gas/s390/zarch-arch13.d: Likewise. - -Signed-off-by: Jens Remus -Reviewed-by: Andreas Krebbel - -(cherry picked from commit 2bf1f788bd7) -(cherry pick dropped: gas/config/tc-s390.c) -(cherry pick dropped: gas/testsuite/gas/s390/esa-g5.d) -(cherry pick dropped: gas/testsuite/gas/s390/esa-g5.s) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-arch13.d) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-arch13.s) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-z10.d) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-z10.s) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-z196.d) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-z196.s) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-z9-109.d) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-z9-109.s) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-z900.d) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-z900.s) ---- - opcodes/s390-opc.c | 22 +++++++++++++++++----- - opcodes/s390-opc.txt | 14 ++++++++++++++ - 2 files changed, 31 insertions(+), 5 deletions(-) - -diff --git a/opcodes/s390-opc.c b/opcodes/s390-opc.c -index b52fc8c3b62..0427bd8b2e0 100644 ---- a/opcodes/s390-opc.c -+++ b/opcodes/s390-opc.c -@@ -62,7 +62,9 @@ const struct s390_operand s390_operands[] = - { 4, 24, S390_OPERAND_GPR }, - #define R_28 (R_24 + 1) /* GPR starting at position 28 */ - { 4, 28, S390_OPERAND_GPR }, --#define R_32 (R_28 + 1) /* GPR starting at position 32 */ -+#define R_CP16_28 (R_28 + 1) /* GPR starting at position 28 */ -+ { 4, 28, S390_OPERAND_GPR | S390_OPERAND_CP16 }, /* with a copy at pos 16 */ -+#define R_32 (R_CP16_28+1) /* GPR starting at position 32 */ - { 4, 32, S390_OPERAND_GPR }, - - /* General purpose register pair operands. */ -@@ -222,9 +224,13 @@ const struct s390_operand s390_operands[] = - { 4, 36, 0 }, - #define U8_8 (U4_36 + 1) /* 8 bit unsigned value starting at 8 */ - { 8, 8, 0 }, --#define U8_16 (U8_8 + 1) /* 8 bit unsigned value starting at 16 */ -+#define U6_18 (U8_8 + 1) /* 6 bit unsigned value starting at 18 */ -+ { 6, 18, 0 }, -+#define U8_16 (U6_18 + 1) /* 8 bit unsigned value starting at 16 */ - { 8, 16, 0 }, --#define U6_26 (U8_16 + 1) /* 6 bit unsigned value starting at 26 */ -+#define U5_27 (U8_16 + 1) /* 5 bit unsigned value starting at 27 */ -+ { 5, 27, 0 }, -+#define U6_26 (U5_27 + 1) /* 6 bit unsigned value starting at 26 */ - { 6, 26, 0 }, - #define U8_24 (U6_26 + 1) /* 8 bit unsigned value starting at 24 */ - { 8, 24, 0 }, -@@ -289,7 +295,7 @@ static inline void unused_s390_operands_static_asserts(void) - p - pc relative - r - general purpose register - re - gpr extended operand, a valid general purpose register pair -- u - unsigned integer, 4, 8, 16 or 32 bit -+ u - unsigned integer, 4, 6, 8, 16 or 32 bit - m - mode field, 4 bit - 0 - operand skipped. - The order of the letters reflects the layout of the format in -@@ -325,7 +331,9 @@ static inline void unused_s390_operands_static_asserts(void) - #define INSTR_RIE_R0U0 6, { R_8,U16_16,0,0,0,0 } /* e.g. clfitne */ - #define INSTR_RIE_RUI0 6, { R_8,I16_16,U4_12,0,0,0 } /* e.g. lochi */ - #define INSTR_RIE_RRUUU 6, { R_8,R_12,U8_16,U8_24,U8_32,0 } /* e.g. rnsbg */ --#define INSTR_RIE_RRUUU2 6, { R_8,R_12,U8_16,U6_26,U8_32,0 } /* e.g. rnsbg */ -+#define INSTR_RIE_RRUUU2 6, { R_8,R_12,U8_16,U6_26,U8_32,0 } /* e.g. risbgz */ -+#define INSTR_RIE_RRUUU3 6, { R_8,R_12,U8_16,U5_27,U8_32,0 } /* e.g. risbhg */ -+#define INSTR_RIE_RRUUU4 6, { R_8,R_12,U6_18,U8_24,U8_32,0 } /* e.g. rnsbgt */ - #define INSTR_RIL_0P 6, { J32_16,0,0,0,0 } /* e.g. jg */ - #define INSTR_RIL_RP 6, { R_8,J32_16,0,0,0,0 } /* e.g. brasl */ - #define INSTR_RIL_UP 6, { U4_8,J32_16,0,0,0,0 } /* e.g. brcl */ -@@ -374,6 +382,7 @@ static inline void unused_s390_operands_static_asserts(void) - #define INSTR_RRF_R0RR2 4, { R_24,R_28,R_16,0,0,0 } /* e.g. ark */ - #define INSTR_RRF_R0RER 4, { RE_24,R_28,R_16,0,0,0 } /* e.g. mgrk */ - #define INSTR_RRF_R0RR3 4, { R_24,R_28,R_16,0,0,0 } /* e.g. selrz */ -+#define INSTR_RRF_R0RR4 4, { R_24,R_CP16_28,0,0,0,0 } /* e.g. notr */ - #define INSTR_RRF_U0FF 4, { F_24,U4_16,F_28,0,0,0 } /* e.g. fidbr */ - #define INSTR_RRF_U0FEFE 4, { FE_24,U4_16,FE_28,0,0,0 } /* e.g. fixbr */ - #define INSTR_RRF_U0RF 4, { R_24,U4_16,F_28,0,0,0 } /* e.g. cfebr */ -@@ -550,6 +559,8 @@ static inline void unused_s390_operands_static_asserts(void) - #define MASK_RIE_RUI0 { 0xff, 0x00, 0x00, 0x00, 0xff, 0xff } - #define MASK_RIE_RRUUU { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } - #define MASK_RIE_RRUUU2 { 0xff, 0x00, 0x00, 0xc0, 0x00, 0xff } -+#define MASK_RIE_RRUUU3 { 0xff, 0x00, 0x00, 0xe0, 0x00, 0xff } -+#define MASK_RIE_RRUUU4 { 0xff, 0x00, 0xc0, 0x00, 0x00, 0xff } - #define MASK_RIL_0P { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } - #define MASK_RIL_RP { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } - #define MASK_RIL_UP { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } -@@ -598,6 +609,7 @@ static inline void unused_s390_operands_static_asserts(void) - #define MASK_RRF_R0RR2 { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } - #define MASK_RRF_R0RER { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } - #define MASK_RRF_R0RR3 { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } -+#define MASK_RRF_R0RR4 { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } - #define MASK_RRF_U0FF { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } - #define MASK_RRF_U0FEFE { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } - #define MASK_RRF_U0RF { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } -diff --git a/opcodes/s390-opc.txt b/opcodes/s390-opc.txt -index 584e49d39f6..bcc2b7e4876 100644 ---- a/opcodes/s390-opc.txt -+++ b/opcodes/s390-opc.txt -@@ -272,6 +272,7 @@ a701 tml RI_RU "test under mask low" g5 esa,zarch - 4700 nop RX_0RRD "no operation" g5 esa,zarch optparm - 4700 b*8 RX_0RRD "conditional branch" g5 esa,zarch - 47f0 b RX_0RRD "unconditional branch" g5 esa,zarch -+a704 jc RI_UP "conditional jump" g5 esa,zarch - a704 jnop RI_0P "nop jump" g5 esa,zarch - a704 j*8 RI_0P "conditional jump" g5 esa,zarch - a704 br*8 RI_0P "conditional jump" g5 esa,zarch -@@ -473,8 +474,10 @@ eb0000000080 icmh RSE_RURD "insert characters under mask high" z900 zarch - a702 tmhh RI_RU "test under mask high high" z900 zarch - a703 tmhl RI_RU "test under mask high low" z900 zarch - c004 brcl RIL_UP "branch relative on condition long" z900 esa,zarch -+# jlc omitted due to missing jl* (see jl*8) and not added as non-standard jgc - c004 jgnop RIL_0P "nop jump long" z900 esa,zarch - c004 jg*8 RIL_0P "conditional jump long" z900 esa,zarch -+# jl*8 omitted due to clash with non-standard j*8 flavors jle and jlh; exists as non-standard jg*8 instead - c004 br*8l RIL_0P "conditional jump long" z900 esa,zarch - c0f4 jg RIL_0P "unconditional jump long" z900 esa,zarch - c0f4 brul RIL_0P "unconditional jump long" z900 esa,zarch -@@ -523,6 +526,7 @@ a50c llihh RI_RU "load logical immediate high high" z900 zarch - a50d llihl RI_RU "load logical immediate high low" z900 zarch - a50e llilh RI_RU "load logical immediate low high" z900 zarch - a50f llill RI_RU "load logical immediate low low" z900 zarch -+a50f llghi RI_RU "load logical immediate" z900 zarch - b2b1 stfl S_RD "store facility list" z900 esa,zarch - b2b2 lpswe S_RD "load psw extended" z900 zarch - b90d dsgr RRE_RER "divide single 64" z900 zarch -@@ -750,6 +754,7 @@ c006 xihf RIL_RU "exclusive or immediate high" z9-109 zarch - c007 xilf RIL_RU "exclusive or immediate low" z9-109 zarch - c008 iihf RIL_RU "insert immediate high" z9-109 zarch - c009 iilf RIL_RU "insert immediate low" z9-109 zarch -+c009 lfi RIL_RU "insert immediate 32" z9-109 zarch - # z9-109 misc instruction - b983 flogr RRE_RER "find leftmost one" z9-109 zarch - e30000000012 lt RXY_RRRD "load and test 32" z9-109 zarch -@@ -767,6 +772,7 @@ b995 llhr RRE_RR "load logical halfword 32" z9-109 zarch - b985 llghr RRE_RR "load logical halfword 64" z9-109 zarch - c00e llihf RIL_RU "load logical immediate high" z9-109 zarch - c00f llilf RIL_RU "load logical immediate low" z9-109 zarch -+c00f llgfi RIL_RU "load logical immediate" z9-109 zarch - c00c oihf RIL_RU "or immediate high" z9-109 zarch - c00d oilf RIL_RU "or immediate low" z9-109 zarch - c205 slfi RIL_RU "subtract logical immediate 32" z9-109 zarch -@@ -969,8 +975,11 @@ c200 msgfi RIL_RI "multiply single immediate (64)" z10 zarch - e30000000036 pfd RXY_URRD "prefetch data" z10 zarch - c602 pfdrl RIL_UP "prefetch data relative long" z10 zarch - ec0000000054 rnsbg RIE_RRUUU "rotate then and selected bits" z10 zarch optparm -+ec0080000054 rnsbgt RIE_RRUUU4 "rotate then and selected bits and test results" z10 zarch optparm - ec0000000057 rxsbg RIE_RRUUU "rotate then exclusive or selected bits" z10 zarch optparm -+ec0080000057 rxsbgt RIE_RRUUU4 "rotate then exclusive or selected bits and test results" z10 zarch optparm - ec0000000056 rosbg RIE_RRUUU "rotate then or selected bits" z10 zarch optparm -+ec0080000056 rosbgt RIE_RRUUU4 "rotate then or selected bits and test results" z10 zarch optparm - ec0000000055 risbg RIE_RRUUU "rotate then insert selected bits" z10 zarch optparm - ec0000800055 risbgz RIE_RRUUU2 "rotate then insert selected bits and zero remaining bits" z10 zarch optparm - c40f strl RIL_RP "store relative long (32)" z10 zarch -@@ -1003,6 +1012,7 @@ b9da alhhlr RRF_R0RR2 "add logical high low" z196 zarch - cc0a alsih RIL_RI "add logical with signed immediate high with cc" z196 zarch - cc0b alsihn RIL_RI "add logical with signed immediate high no cc" z196 zarch - cc06 brcth RIL_RP "branch relative on count high" z196 zarch -+cc06 jcth RIL_RP "jump on count high" z196 zarch - b9cd chhr RRE_RR "compare high high" z196 zarch - b9dd chlr RRE_RR "compare high low" z196 zarch - e300000000cd chf RXY_RRRD "compare high" z196 zarch -@@ -1017,7 +1027,9 @@ e300000000ca lfh RXY_RRRD "load high" z196 zarch - e300000000c2 llch RXY_RRRD "load logical character high" z196 zarch - e300000000c6 llhh RXY_RRRD "load logical halfword high" z196 zarch - ec000000005d risbhg RIE_RRUUU "rotate then insert selected bits high" z196 zarch optparm -+ec000080005d risbhgz RIE_RRUUU3 "rotate then insert selected bits high and zero remaining bits" z196 zarch optparm - ec0000000051 risblg RIE_RRUUU "rotate then insert selected bits low" z196 zarch optparm -+ec0000800051 risblgz RIE_RRUUU3 "rotate then insert selected bits low and zero remaining bits" z196 zarch optparm - e300000000c3 stch RXY_RRRD "store character high" z196 zarch - e300000000c7 sthh RXY_RRRD "store halfword high" z196 zarch - e300000000cb stfh RXY_RRRD "store high" z196 zarch -@@ -1913,7 +1925,9 @@ e50a mvcrl SSE_RDRD "move right to left" arch13 zarch - b974 nnrk RRF_R0RR2 "nand 32 bit" arch13 zarch - b964 nngrk RRF_R0RR2 "nand 64 bit" arch13 zarch - b976 nork RRF_R0RR2 "nor 32 bit" arch13 zarch -+b976 notr RRF_R0RR4 "not 32 bit" arch13 zarch - b966 nogrk RRF_R0RR2 "nor 64 bit" arch13 zarch -+b966 notgr RRF_R0RR4 "not 64 bit" arch13 zarch - b977 nxrk RRF_R0RR2 "not exclusive or 32 bit" arch13 zarch - b967 nxgrk RRF_R0RR2 "not exclusive or 64 bit" arch13 zarch - b975 ocrk RRF_R0RR2 "or with complement 32 bit" arch13 zarch --- -2.43.0 - diff --git a/s390-add-suffix-to-conditional-branch-instruction-de.patch b/s390-add-suffix-to-conditional-branch-instruction-de.patch deleted file mode 100644 index 19519ae..0000000 --- a/s390-add-suffix-to-conditional-branch-instruction-de.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 2c5de93b010ce39182b1feb08ab15a7ba8904794 Mon Sep 17 00:00:00 2001 -From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:48 +0100 -Subject: [PATCH 11/28] s390: Add suffix to conditional branch instruction - descriptions - -Suffix the instruction description of conditional branch extended -mnemonics with their condition (e.g. "on A high"). This complements -the optional printing of instruction descriptions as comments in the -disassembly. - -Due to the added text the maximum description length is increased from -80 to 128 characters (including the trailing '\0' character). - -opcodes/ - * s390-mkopc.c: Add suffix to conditional branch extended - mnemonic instruction descriptions. - -gas/ - * testsuite/gas/s390/zarch-insndesc.s: Add test cases for - printing of suffixed instruction description of conditional - branch extended mnemonics. - * testsuite/gas/s390/zarch-insndesc.d: Likewise. - -Signed-off-by: Jens Remus -Reviewed-by: Andreas Krebbel - -(cherry picked from commit 1c354ebcbac) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-insndesc.d) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-insndesc.s) ---- - opcodes/s390-mkopc.c | 78 +++++++++++++++++++++++++------------------- - 1 file changed, 44 insertions(+), 34 deletions(-) - -diff --git a/opcodes/s390-mkopc.c b/opcodes/s390-mkopc.c -index c6930a3e9b5..025dbdb037f 100644 ---- a/opcodes/s390-mkopc.c -+++ b/opcodes/s390-mkopc.c -@@ -32,7 +32,7 @@ - #define MAX_OPCODE_LEN 15 - #define MAX_MNEMONIC_LEN 15 - #define MAX_FORMAT_LEN 15 --#define MAX_DESCRIPTION_LEN 79 -+#define MAX_DESCRIPTION_LEN 127 - - #define MAX_CPU_LEN 15 - #define MAX_MODES_LEN 15 -@@ -142,50 +142,52 @@ struct s390_cond_ext_format - { - char nibble; - char extension[4]; -+ char *description_suffix; -+ - }; - - /* The mnemonic extensions for conditional jumps used to replace - the '*' tag. */ - #define NUM_COND_EXTENSIONS 20 - const struct s390_cond_ext_format s390_cond_extensions[NUM_COND_EXTENSIONS] = --{ { '1', "o" }, /* jump on overflow / if ones */ -- { '2', "h" }, /* jump on A high */ -- { '2', "p" }, /* jump on plus */ -- { '3', "nle" }, /* jump on not low or equal */ -- { '4', "l" }, /* jump on A low */ -- { '4', "m" }, /* jump on minus / if mixed */ -- { '5', "nhe" }, /* jump on not high or equal */ -- { '6', "lh" }, /* jump on low or high */ -- { '7', "ne" }, /* jump on A not equal B */ -- { '7', "nz" }, /* jump on not zero / if not zeros */ -- { '8', "e" }, /* jump on A equal B */ -- { '8', "z" }, /* jump on zero / if zeros */ -- { '9', "nlh" }, /* jump on not low or high */ -- { 'a', "he" }, /* jump on high or equal */ -- { 'b', "nl" }, /* jump on A not low */ -- { 'b', "nm" }, /* jump on not minus / if not mixed */ -- { 'c', "le" }, /* jump on low or equal */ -- { 'd', "nh" }, /* jump on A not high */ -- { 'd', "np" }, /* jump on not plus */ -- { 'e', "no" }, /* jump on not overflow / if not ones */ -+{ { '1', "o", "on overflow / if ones"}, /* jump on overflow / if ones */ -+ { '2', "h", "on A high"}, /* jump on A high */ -+ { '2', "p", "on plus" }, /* jump on plus */ -+ { '3', "nle", "on not low or equal" }, /* jump on not low or equal */ -+ { '4', "l", "on A low" }, /* jump on A low */ -+ { '4', "m", "on minus / if mixed" }, /* jump on minus / if mixed */ -+ { '5', "nhe", "on not high or equal" }, /* jump on not high or equal */ -+ { '6', "lh", "on low or high" }, /* jump on low or high */ -+ { '7', "ne", "on A not equal B" }, /* jump on A not equal B */ -+ { '7', "nz", "on not zero / if not zeros" }, /* jump on not zero / if not zeros */ -+ { '8', "e", "on A equal B" }, /* jump on A equal B */ -+ { '8', "z", "on zero / if zeros" }, /* jump on zero / if zeros */ -+ { '9', "nlh", "on not low or high " }, /* jump on not low or high */ -+ { 'a', "he", "on high or equal" }, /* jump on high or equal */ -+ { 'b', "nl", "on A not low" }, /* jump on A not low */ -+ { 'b', "nm", "on not minus / if not mixed" }, /* jump on not minus / if not mixed */ -+ { 'c', "le", "on low or equal" }, /* jump on low or equal */ -+ { 'd', "nh", "on A not high" }, /* jump on A not high */ -+ { 'd', "np", "on not plus" }, /* jump on not plus */ -+ { 'e', "no", "on not overflow / if not ones" },/* jump on not overflow / if not ones */ - }; - - /* The mnemonic extensions for conditional branches used to replace - the '$' tag. */ - #define NUM_CRB_EXTENSIONS 12 - const struct s390_cond_ext_format s390_crb_extensions[NUM_CRB_EXTENSIONS] = --{ { '2', "h" }, /* jump on A high */ -- { '2', "nle" }, /* jump on not low or equal */ -- { '4', "l" }, /* jump on A low */ -- { '4', "nhe" }, /* jump on not high or equal */ -- { '6', "ne" }, /* jump on A not equal B */ -- { '6', "lh" }, /* jump on low or high */ -- { '8', "e" }, /* jump on A equal B */ -- { '8', "nlh" }, /* jump on not low or high */ -- { 'a', "nl" }, /* jump on A not low */ -- { 'a', "he" }, /* jump on high or equal */ -- { 'c', "nh" }, /* jump on A not high */ -- { 'c', "le" }, /* jump on low or equal */ -+{ { '2', "h", "on A high" }, /* jump on A high */ -+ { '2', "nle", "on not low or equal" }, /* jump on not low or equal */ -+ { '4', "l", "on A low" }, /* jump on A low */ -+ { '4', "nhe", "on not high or equal" }, /* jump on not high or equal */ -+ { '6', "ne", "on A not equal B" }, /* jump on A not equal B */ -+ { '6', "lh", "on low or high" }, /* jump on low or high */ -+ { '8', "e", "on A equal B" }, /* jump on A equal B */ -+ { '8', "nlh", "on not low or high" }, /* jump on not low or high */ -+ { 'a', "nl", "on A not low" }, /* jump on A not low */ -+ { 'a', "he", "on high or equal" }, /* jump on high or equal */ -+ { 'c', "nh", "on A not high" }, /* jump on A not high */ -+ { 'c', "le", "on low or equal" }, /* jump on low or equal */ - }; - - /* As with insertOpcode instructions are added to the sorted opcode -@@ -283,6 +285,7 @@ insertExpandedMnemonic (char *opcode, char *mnemonic, char *format, - for (i = 0; i < ext_table_length; i++) - { - char new_mnemonic[MAX_MNEMONIC_LEN + 1]; -+ char new_description[MAX_DESCRIPTION_LEN + 1]; - - opcode[mask_start] = ext_table[i].nibble; - -@@ -293,7 +296,14 @@ insertExpandedMnemonic (char *opcode, char *mnemonic, char *format, - return; - } - -- insertOpcode (opcode, new_mnemonic, format, min_cpu, mode_bits, flags, description); -+ if (snprintf (new_description, sizeof (new_description), "%s %s", description, -+ ext_table[i].description_suffix) >= sizeof (new_description)) -+ { -+ print_error ("Mnemonic \"%s\": Concatenated description exceeds max. length\n", mnemonic); -+ return; -+ } -+ -+ insertOpcode (opcode, new_mnemonic, format, min_cpu, mode_bits, flags, new_description); - } - return; - --- -2.43.0 - diff --git a/s390-add-test-cases-for-base-index-register-0.patch b/s390-add-test-cases-for-base-index-register-0.patch deleted file mode 100644 index 2162f94..0000000 --- a/s390-add-test-cases-for-base-index-register-0.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 9f8dfa4754831b4653004afed62434abc3a44651 Mon Sep 17 00:00:00 2001 -From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:50 +0100 -Subject: [PATCH 15/28] s390: Add test cases for base/index register 0 - -While at it add comments to logic to omit base and/or index register 0 -in s390 disassembly. - -opcodes/ - * s390-dis.c: Add comments related to omitting base and/or index - register 0 in disassembly. -gas/ - * testsuite/gas/s390/s390.exp: Add test cases for base and/or - index register 0. - * testsuite/gas/s390/zarch-base-index-0.s: Add test cases for - base and/or index register 0. - * testsuite/gas/s390/zarch-base-index-0.d: Likewise. - * testsuite/gas/s390/zarch-base-index-0-err.s: Add error test - cases for base and/or index register 0. - -Reviewed-by: Andreas Krebbel -Signed-off-by: Jens Remus - -(cherry picked from commit bd0ee1ee410) -(cherry pick dropped: gas/testsuite/gas/s390/s390.exp) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-base-index-0-err.l) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-base-index-0-err.s) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-base-index-0.d) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-base-index-0.s) ---- - opcodes/s390-dis.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/opcodes/s390-dis.c b/opcodes/s390-dis.c -index ebf56c1c7e4..b1ff1a862a2 100644 ---- a/opcodes/s390-dis.c -+++ b/opcodes/s390-dis.c -@@ -204,10 +204,11 @@ s390_print_insn_with_opcode (bfd_vma memaddr, - union operand_value val = s390_extract_operand (buffer, operand); - unsigned long flags = operand->flags; - -+ /* Omit index register 0. */ - if ((flags & S390_OPERAND_INDEX) && val.u == 0) - continue; -- if ((flags & S390_OPERAND_BASE) && -- val.u == 0 && separator == '(') -+ /* Omit base register 0, if no or omitted index register 0. */ -+ if ((flags & S390_OPERAND_BASE) && val.u == 0 && separator == '(') - { - separator = ','; - continue; --- -2.43.0 - diff --git a/s390-align-letter-case-of-instruction-descriptions.patch b/s390-align-letter-case-of-instruction-descriptions.patch deleted file mode 100644 index c875d23..0000000 --- a/s390-align-letter-case-of-instruction-descriptions.patch +++ /dev/null @@ -1,103 +0,0 @@ -From c027f16344a11838a9f5f61c5d7e781fbb52b16c Mon Sep 17 00:00:00 2001 -From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:47 +0100 -Subject: [PATCH 07/28] s390: Align letter case of instruction descriptions - -Change the bitwise operations names "and" and "or" to lower case. Change -the register name abbreviations "FPR", "GR", and "VR" to upper case. - -opcodes/ - * s390-opc.txt: Align letter case of instruction descriptions. - -Signed-off-by: Jens Remus -Reviewed-by: Andreas Krebbel - -(cherry picked from commit 8e194ff8cce) ---- - opcodes/s390-opc.txt | 42 +++++++++++++++++++++--------------------- - 1 file changed, 21 insertions(+), 21 deletions(-) - -diff --git a/opcodes/s390-opc.txt b/opcodes/s390-opc.txt -index 78b9678cc7f..a3117eeebc5 100644 ---- a/opcodes/s390-opc.txt -+++ b/opcodes/s390-opc.txt -@@ -144,14 +144,14 @@ d3 mvz SS_L0RDRD "move zones" g5 esa,zarch - 67 mxd RX_FERRD "multiply (long to ext.)" g5 esa,zarch - 27 mxdr RR_FEF "multiply (long to ext.)" g5 esa,zarch - 26 mxr RR_FEFE "multiply (ext.)" g5 esa,zarch --54 n RX_RRRD "AND" g5 esa,zarch --d4 nc SS_L0RDRD "AND" g5 esa,zarch --94 ni SI_URD "AND" g5 esa,zarch --14 nr RR_RR "AND" g5 esa,zarch --56 o RX_RRRD "OR" g5 esa,zarch --d6 oc SS_L0RDRD "OR" g5 esa,zarch --96 oi SI_URD "OR" g5 esa,zarch --16 or RR_RR "OR" g5 esa,zarch -+54 n RX_RRRD "and" g5 esa,zarch -+d4 nc SS_L0RDRD "and" g5 esa,zarch -+94 ni SI_URD "and" g5 esa,zarch -+14 nr RR_RR "and" g5 esa,zarch -+56 o RX_RRRD "or" g5 esa,zarch -+d6 oc SS_L0RDRD "or" g5 esa,zarch -+96 oi SI_URD "or" g5 esa,zarch -+16 or RR_RR "or" g5 esa,zarch - f2 pack SS_LLRDRD "pack" g5 esa,zarch - b248 palb RRE_00 "purge ALB" g5 esa,zarch - b218 pc S_RD "program call" g5 esa,zarch -@@ -215,8 +215,8 @@ b6 stctl RS_CCRD "store control" g5 esa,zarch - 40 sth RX_RRRD "store halfword" g5 esa,zarch - b202 stidp S_RD "store CPU id" g5 esa,zarch - 90 stm RS_RRRD "store multiple" g5 esa,zarch --ac stnsm SI_URD "store then AND system mask" g5 esa,zarch --ad stosm SI_URD "store then OR system mask" g5 esa,zarch -+ac stnsm SI_URD "store then and system mask" g5 esa,zarch -+ad stosm SI_URD "store then or system mask" g5 esa,zarch - b209 stpt S_RD "store CPU timer" g5 esa,zarch - b211 stpx S_RD "store prefix" g5 esa,zarch - b234 stsch S_RD "store subchannel" g5 esa,zarch -@@ -239,10 +239,10 @@ dd trt SS_L0RDRD "translate and test" g5 esa,zarch - b235 tsch S_RD "test subchannel" g5 esa,zarch - f3 unpk SS_LLRDRD "unpack" g5 esa,zarch - 0102 upt E "update tree" g5 esa,zarch --57 x RX_RRRD "exclusive OR" g5 esa,zarch --d7 xc SS_L0RDRD "exclusive OR" g5 esa,zarch --97 xi SI_URD "exclusive OR" g5 esa,zarch --17 xr RR_RR "exclusive OR" g5 esa,zarch -+57 x RX_RRRD "exclusive or" g5 esa,zarch -+d7 xc SS_L0RDRD "exclusive or" g5 esa,zarch -+97 xi SI_URD "exclusive or" g5 esa,zarch -+17 xr RR_RR "exclusive or" g5 esa,zarch - f8 zap SS_LLRDRD "zero and add" g5 esa,zarch - a70a ahi RI_RI "add halfword immediate" g5 esa,zarch - 84 brxh RSI_RRP "branch relative on index high" g5 esa,zarch condjump -@@ -821,8 +821,8 @@ b370 lpdfr RRE_FF "load positive no cc" z9-ec zarch - b371 lndfr RRE_FF "load negative no cc" z9-ec zarch - b372 cpsdr RRF_F0FF2 "copy sign" z9-ec zarch - b373 lcdfr RRE_FF "load complement no cc" z9-ec zarch --b3c1 ldgr RRE_FR "load fpr from gr" z9-ec zarch --b3cd lgdr RRE_RF "load gr from fpr" z9-ec zarch -+b3c1 ldgr RRE_FR "load FPR from GR" z9-ec zarch -+b3cd lgdr RRE_RF "load GR from FPR" z9-ec zarch - b3d2 adtr RRR_F0FF "add long dfp" z9-ec zarch - b3da axtr RRR_FE0FEFE "add extended dfp" z9-ec zarch - b3e4 cdtr RRE_FF "compare long dfp" z9-ec zarch -@@ -1203,11 +1203,11 @@ e70000000040 vleib VRI_V0IU "vector load byte element immediate" z13 zarch vx - e70000000041 vleih VRI_V0IU "vector load halfword element immediate" z13 zarch vx - e70000000043 vleif VRI_V0IU "vector load word element immediate" z13 zarch vx - e70000000042 vleig VRI_V0IU "vector load double word element immediate" z13 zarch vx --e70000000021 vlgv VRS_RVRDU "vector load gr from vr element" z13 zarch vx --e70000000021 vlgvb VRS_RVRD "vector load gr from vr byte element" z13 zarch vx --e70000001021 vlgvh VRS_RVRD "vector load gr from vr halfword element" z13 zarch vx --e70000002021 vlgvf VRS_RVRD "vector load gr from vr word element" z13 zarch vx --e70000003021 vlgvg VRS_RVRD "vector load gr from vr double word element" z13 zarch vx -+e70000000021 vlgv VRS_RVRDU "vector load GR from VR element" z13 zarch vx -+e70000000021 vlgvb VRS_RVRD "vector load GR from VR byte element" z13 zarch vx -+e70000001021 vlgvh VRS_RVRD "vector load GR from VR halfword element" z13 zarch vx -+e70000002021 vlgvf VRS_RVRD "vector load GR from VR word element" z13 zarch vx -+e70000003021 vlgvg VRS_RVRD "vector load GR from VR double word element" z13 zarch vx - e70000000004 vllez VRX_VRRDU "vector load logical element and zero" z13 zarch vx - e70000000004 vllezb VRX_VRRD "vector load logical byte element and zero" z13 zarch vx - e70000001004 vllezh VRX_VRRD "vector load logical halfword element and zero" z13 zarch vx --- -2.43.0 - diff --git a/s390-align-opcodes-to-lower-case.patch b/s390-align-opcodes-to-lower-case.patch index 6b68c63..13ea247 100644 --- a/s390-align-opcodes-to-lower-case.patch +++ b/s390-align-opcodes-to-lower-case.patch @@ -1,7 +1,7 @@ -From 0be75252a57fea99e48f58cbe849bf5dc3128f26 Mon Sep 17 00:00:00 2001 +From 1e4d5d4928d64022b8e17e20ffa8a7b2134842e1 Mon Sep 17 00:00:00 2001 From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:51 +0100 -Subject: [PATCH 19/28] s390: Align opcodes to lower-case +Date: Fri, 7 Mar 2025 13:06:51 +0100 +Subject: [PATCH 01/10] s390: Align opcodes to lower-case opcodes/ * s390-opc.txt (rdp): Change opcode to lower-case. @@ -14,7 +14,7 @@ Signed-off-by: Jens Remus 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opcodes/s390-opc.txt b/opcodes/s390-opc.txt -index fb9babf6dcd..39a296e948f 100644 +index 1182e196059..4610a8fddd7 100644 --- a/opcodes/s390-opc.txt +++ b/opcodes/s390-opc.txt @@ -2061,7 +2061,7 @@ e60000000055 vcnf VRR_VV0UU2 "vector fp convert to nnp" arch14 zarch @@ -26,6 +26,8 @@ index fb9babf6dcd..39a296e948f 100644 # BEAR-Enhancement Facility + +base-commit: 31276843acc9aac2e5ce4a9181eecd33b0e0a6cc -- 2.43.0 diff --git a/s390-align-optional-operand-definition-to-specs.patch b/s390-align-optional-operand-definition-to-specs.patch deleted file mode 100644 index af8ebd7..0000000 --- a/s390-align-optional-operand-definition-to-specs.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 36f2e4e877d8c36c9dcbac6cbb6778a8edd1ee03 Mon Sep 17 00:00:00 2001 -From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:45 +0100 -Subject: [PATCH 02/28] s390: Align optional operand definition to specs - -The IBM z/Architecture Principle of Operation [1] specifies the last -operand(s) of some (extended) mnemonics to be optional. Align the -mnemonic definitions in the opcode table according to specification. - -This changes the last operand of the following (extended) mnemonics to -be optional: -risbg, risbgz, risbgn, risbgnz, risbhg, risblg, rnsbg, rosbg, rxsbg - -Note that efpc and sfpc actually have only one operand, but had -erroneously been defined to have two. For backwards compatibility the -wrong RR register format must be retained. Since the superfluous second -operand is defined as optional the instruction can still be coded as -specified. - -[1]: IBM z/Architecture Principles of Operation, SA22-7832-13, IBM z16, - https://publibfp.dhe.ibm.com/epubs/pdf/a227832d.pdf - -opcodes/ - * s390-opc.txt: Align optional operand definition to - specification. - -testsuite/ - * zarch-z10.s: Add test cases for risbg, risbgz, rnsbg, rosbg, - and rxsbg. - * zarch-z10.d: Likewise. - * zarch-z196.s: Add test cases for risbhg and risblg. - * zarch-z196.d: Likewise. - * zarch-zEC12.s: Add test cases for risbgn and risbgnz. - * zarch-zEC12.d: Likewise. - -Signed-off-by: Jens Remus -Reviewed-by: Andreas Krebbel - -(cherry picked from commit fca086d928a) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-z10.d) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-z10.s) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-z196.d) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-z196.s) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-zEC12.d) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-zEC12.s) ---- - opcodes/s390-opc.txt | 20 +++++++++++--------- - 1 file changed, 11 insertions(+), 9 deletions(-) - -diff --git a/opcodes/s390-opc.txt b/opcodes/s390-opc.txt -index b33ee34ea8f..584e49d39f6 100644 ---- a/opcodes/s390-opc.txt -+++ b/opcodes/s390-opc.txt -@@ -305,6 +305,7 @@ b30d debr RRE_FF "divide short bfp" g5 esa,zarch - ed000000000d deb RXE_FRRD "divide short bfp" g5 esa,zarch - b35b didbr RRF_FUFF "divide to integer long bfp" g5 esa,zarch - b353 diebr RRF_FUFF "divide to integer short bfp" g5 esa,zarch -+# efpc and sfpc have only one operand; retain RR register format for compatibility - b38c efpc RRE_RR "extract fpc" g5 esa,zarch optparm - b342 ltxbr RRE_FEFE "load and test extended bfp" g5 esa,zarch - b312 ltdbr RRE_FF "load and test long bfp" g5 esa,zarch -@@ -348,6 +349,7 @@ b31f msdbr RRF_F0FF "multiply and subtract long bfp" g5 esa,zarch - ed000000001f msdb RXF_FRRDF "multiply and subtract long bfp" g5 esa,zarch - b30f msebr RRF_F0FF "multiply and subtract short bfp" g5 esa,zarch - ed000000000f mseb RXF_FRRDF "multiply and subtract short bfp" g5 esa,zarch -+# efpc and sfpc have only one operand; retain RR register format for compatibility - b384 sfpc RRE_RR "set fpc" g5 esa,zarch optparm - b299 srnm S_RD "set rounding mode" g5 esa,zarch - b316 sqxbr RRE_FEFE "square root extended bfp" g5 esa,zarch -@@ -966,11 +968,11 @@ c201 msfi RIL_RI "multiply single immediate (32)" z10 zarch - c200 msgfi RIL_RI "multiply single immediate (64)" z10 zarch - e30000000036 pfd RXY_URRD "prefetch data" z10 zarch - c602 pfdrl RIL_UP "prefetch data relative long" z10 zarch --ec0000000054 rnsbg RIE_RRUUU "rotate then and selected bits" z10 zarch --ec0000000057 rxsbg RIE_RRUUU "rotate then exclusive or selected bits" z10 zarch --ec0000000056 rosbg RIE_RRUUU "rotate then or selected bits" z10 zarch --ec0000000055 risbg RIE_RRUUU "rotate then insert selected bits" z10 zarch --ec0000800055 risbgz RIE_RRUUU2 "rotate then insert selected bits and zero remaining bits" z10 zarch -+ec0000000054 rnsbg RIE_RRUUU "rotate then and selected bits" z10 zarch optparm -+ec0000000057 rxsbg RIE_RRUUU "rotate then exclusive or selected bits" z10 zarch optparm -+ec0000000056 rosbg RIE_RRUUU "rotate then or selected bits" z10 zarch optparm -+ec0000000055 risbg RIE_RRUUU "rotate then insert selected bits" z10 zarch optparm -+ec0000800055 risbgz RIE_RRUUU2 "rotate then insert selected bits and zero remaining bits" z10 zarch optparm - c40f strl RIL_RP "store relative long (32)" z10 zarch - c40b stgrl RIL_RP "store relative long (64)" z10 zarch - c407 sthrl RIL_RP "store halfword relative long" z10 zarch -@@ -1014,8 +1016,8 @@ e300000000c4 lhh RXY_RRRD "load halfword high" z196 zarch - e300000000ca lfh RXY_RRRD "load high" z196 zarch - e300000000c2 llch RXY_RRRD "load logical character high" z196 zarch - e300000000c6 llhh RXY_RRRD "load logical halfword high" z196 zarch --ec000000005d risbhg RIE_RRUUU "rotate then insert selected bits high" z196 zarch --ec0000000051 risblg RIE_RRUUU "rotate then insert selected bits low" z196 zarch -+ec000000005d risbhg RIE_RRUUU "rotate then insert selected bits high" z196 zarch optparm -+ec0000000051 risblg RIE_RRUUU "rotate then insert selected bits low" z196 zarch optparm - e300000000c3 stch RXY_RRRD "store character high" z196 zarch - e300000000c7 sthh RXY_RRRD "store halfword high" z196 zarch - e300000000cb stfh RXY_RRRD "store high" z196 zarch -@@ -1153,8 +1155,8 @@ eb0000000023 clt RSY_RURD "compare logical and trap 32 bit reg-mem" zEC12 zarch - eb0000000023 clt$12 RSY_R0RD "compare logical and trap 32 bit reg-mem" zEC12 zarch - eb000000002b clgt RSY_RURD "compare logical and trap 64 bit reg-mem" zEC12 zarch - eb000000002b clgt$12 RSY_R0RD "compare logical and trap 64 bit reg-mem" zEC12 zarch --ec0000000059 risbgn RIE_RRUUU "rotate then insert selected bits nocc" zEC12 zarch --ec0000800059 risbgnz RIE_RRUUU2 "rotate then insert selected bits and zero remaining bits nocc" zEC12 zarch -+ec0000000059 risbgn RIE_RRUUU "rotate then insert selected bits nocc" zEC12 zarch optparm -+ec0000800059 risbgnz RIE_RRUUU2 "rotate then insert selected bits and zero remaining bits nocc" zEC12 zarch optparm - ed00000000aa cdzt RSL_LRDFU "convert from zoned long" zEC12 zarch - ed00000000ab cxzt RSL_LRDFEU "convert from zoned extended" zEC12 zarch - ed00000000a8 czdt RSL_LRDFU "convert to zoned long" zEC12 zarch --- -2.43.0 - diff --git a/s390-correct-prno-instruction-name.patch b/s390-correct-prno-instruction-name.patch deleted file mode 100644 index cae1e05..0000000 --- a/s390-correct-prno-instruction-name.patch +++ /dev/null @@ -1,36 +0,0 @@ -From e50937a6e0bd1a76902336dfee85819188801bfa Mon Sep 17 00:00:00 2001 -From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:46 +0100 -Subject: [PATCH 04/28] s390: Correct prno instruction name - -IBM z13 (arch11) introduced ppno (Perform Pseudorandom Number Operation). -IBM z14 (arch12) introduced prno (Perform Random Number Operation) and -deprecated ppno. - -opcodes/ - * s390-opc.txt: Correct prno instruction name. - -Signed-off-by: Jens Remus -Reviewed-by: Andreas Krebbel - -(cherry picked from commit 6e1d1b2e7b2) ---- - opcodes/s390-opc.txt | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/opcodes/s390-opc.txt b/opcodes/s390-opc.txt -index bcc2b7e4876..59c43060ab4 100644 ---- a/opcodes/s390-opc.txt -+++ b/opcodes/s390-opc.txt -@@ -1910,7 +1910,7 @@ e30000000049 stgsc RXY_RRRD "store guarded storage controls" arch12 zarch - - b929 kma RRF_R0RR "cipher message with galois counter mode" arch12 zarch - --b93c prno RRE_RR "perform pseudorandom number operation" arch12 zarch -+b93c prno RRE_RR "perform random number operation" arch12 zarch - b9a1 tpei RRE_RR "test pending external interruption" arch12 zarch - b9ac irbm RRE_RR "insert reference bits multiple" arch12 zarch - --- -2.43.0 - diff --git a/s390-enhance-error-handling-in-s390-mkopc.patch b/s390-enhance-error-handling-in-s390-mkopc.patch deleted file mode 100644 index ad0ec2a..0000000 --- a/s390-enhance-error-handling-in-s390-mkopc.patch +++ /dev/null @@ -1,147 +0,0 @@ -From 1dd4db5f3e88c14311ecdfb80c668833d7578b3b Mon Sep 17 00:00:00 2001 -From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:47 +0100 -Subject: [PATCH 08/28] s390: Enhance error handling in s390-mkopc - -When the s390-mkopc utility detects an error it prints an error message -to strerr and either continues processing or exists with a non-zero -return code. If it continues without detecting any further error the -final return code was zero, potentially hiding the detected error. - -Introduce a global variable to hold the final return code and initialize -it to EXIT_SUCCESS. Introduce a helper function print_error() that -prints an error message to stderr and sets the final return code to -EXIT_FAILURE. Use it to print all error messages. Return the final -return code at the end of the processing. - -While at it enhance error messages to state more clearly which mnemonic -an error was detected for. Also continue processing for cases where -subsequent mnemonics can be processed. - -opcodes/ - * s390-mkopc.c: Enhance error handling. Return EXIT_FAILURE - in case of an error, otherwise EXIT_SUCCESS. - -Signed-off-by: Jens Remus -Reviewed-by: Andreas Krebbel - -(cherry picked from commit 730e7ddc243) ---- - opcodes/s390-mkopc.c | 49 +++++++++++++++++++++++++++++++------------- - 1 file changed, 35 insertions(+), 14 deletions(-) - -diff --git a/opcodes/s390-mkopc.c b/opcodes/s390-mkopc.c -index 5f921ee0628..aad093f18ff 100644 ---- a/opcodes/s390-mkopc.c -+++ b/opcodes/s390-mkopc.c -@@ -21,9 +21,27 @@ - - #include - #include -+#include - #include - #include "opcode/s390.h" - -+/* Return code. */ -+int return_code = EXIT_SUCCESS; -+ -+/* Helper to print an error message and set the return code. */ -+static void __attribute__ ((format (printf, 1, 2))) -+print_error (const char *fmt, ...) -+{ -+ va_list ap; -+ -+ va_start(ap, fmt); -+ fprintf(stderr, "Error: "); -+ vfprintf(stderr, fmt, ap); -+ va_end(ap); -+ -+ return_code = EXIT_FAILURE; -+} -+ - struct op_struct - { - char opcode[16]; -@@ -223,8 +241,7 @@ insertExpandedMnemonic (char *opcode, char *mnemonic, char *format, - - if (mask_start & 3) - { -- fprintf (stderr, "Conditional mask not at nibble boundary in: %s\n", -- mnemonic); -+ print_error ("Mnemonic \"%s\": Conditional mask not at nibble boundary\n", mnemonic); - return; - } - -@@ -257,7 +274,7 @@ insertExpandedMnemonic (char *opcode, char *mnemonic, char *format, - return; - - malformed_mnemonic: -- fprintf (stderr, "Malformed mnemonic: %s\n", mnemonic); -+ print_error ("Malformed mnemonic: %s\n", mnemonic); - } - - static const char file_header[] = -@@ -343,8 +360,8 @@ main (void) - cpu_string, modes_string, flags_string); - if (num_matched != 6 && num_matched != 7) - { -- fprintf (stderr, "Couldn't scan line %s\n", currentLine); -- exit (1); -+ print_error ("Couldn't scan line %s\n", currentLine); -+ exit (EXIT_FAILURE); - } - - if (strcmp (cpu_string, "g5") == 0 -@@ -385,8 +402,9 @@ main (void) - || strcmp (cpu_string, "arch14") == 0) - min_cpu = S390_OPCODE_ARCH14; - else { -- fprintf (stderr, "Couldn't parse cpu string %s\n", cpu_string); -- exit (1); -+ print_error ("Mnemonic \"%s\": Couldn't parse CPU string: %s\n", -+ mnemonic, cpu_string); -+ goto continue_loop; - } - - str = modes_string; -@@ -401,9 +419,9 @@ main (void) - mode_bits |= 1 << S390_OPCODE_ZARCH; - str += 5; - } else { -- fprintf (stderr, "Couldn't parse modes string %s\n", -- modes_string); -- exit (1); -+ print_error ("Mnemonic \"%s\": Couldn't parse modes string: %s\n", -+ mnemonic, modes_string); -+ goto continue_loop; - } - if (*str == ',') - str++; -@@ -444,17 +462,20 @@ main (void) - flag_bits |= S390_INSTR_FLAGS_CLASS_JUMPSR; - str += 6; - } else { -- fprintf (stderr, "Couldn't parse flags string %s\n", -- flags_string); -- exit (1); -+ print_error ("Mnemonic \"%s\": Couldn't parse flags string: %s\n", -+ mnemonic, flags_string); -+ goto continue_loop; - } - if (*str == ',') - str++; - } while (*str != 0); - } - insertExpandedMnemonic (opcode, mnemonic, format, min_cpu, mode_bits, flag_bits); -+ -+ continue_loop: -+ ; - } - - dumpTable (); -- return 0; -+ return return_code; - } --- -2.43.0 - diff --git a/s390-fix-disassembly-of-optional-addressing-operands.patch b/s390-fix-disassembly-of-optional-addressing-operands.patch index 975e7a7..1c698f9 100644 --- a/s390-fix-disassembly-of-optional-addressing-operands.patch +++ b/s390-fix-disassembly-of-optional-addressing-operands.patch @@ -1,7 +1,7 @@ -From c7fcaaeabd78de5ad1762797a4c54244d7579ccd Mon Sep 17 00:00:00 2001 +From 708495beae38a6b5c265a3865f38d2be79414a63 Mon Sep 17 00:00:00 2001 From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:53 +0100 -Subject: [PATCH 26/28] s390: Fix disassembly of optional addressing operands +Date: Fri, 7 Mar 2025 13:06:53 +0100 +Subject: [PATCH 08/10] s390: Fix disassembly of optional addressing operands "nop D1(B1)" erroneously disassembled into "nop D1(B1" (missing closing parenthesis). "nop D1(X1,0)" and "nop D1(X1,)" erroneously @@ -41,7 +41,7 @@ Signed-off-by: Jens Remus 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/opcodes/s390-dis.c b/opcodes/s390-dis.c -index 2050d8b13a1..4724610e778 100644 +index 852d2f6ebb9..1a23afc8f40 100644 --- a/opcodes/s390-dis.c +++ b/opcodes/s390-dis.c @@ -214,20 +214,29 @@ s390_print_insn_with_opcode (bfd_vma memaddr, diff --git a/s390-flag-conditional-branch-relative-insns-as-condj.patch b/s390-flag-conditional-branch-relative-insns-as-condj.patch deleted file mode 100644 index 80bae72..0000000 --- a/s390-flag-conditional-branch-relative-insns-as-condj.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 289245f291a5431580c5840676112d0d93292eb0 Mon Sep 17 00:00:00 2001 -From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:50 +0100 -Subject: [PATCH 18/28] s390: Flag conditional branch relative insns as - condjump - -Flag conditional branch relative (extended) mnemonics clij* and clgij* -as "condjump" for jump visualization in disassembly. They were missed -to be flagged as such in commit c5306fed7d40 ("s390: Support for jump -visualization in disassembly"). - -opcodes/ - * s390-opc.txt: Flag conditional branch relative instructions - clij* and clgij* as condjump for jump visualization in - disassembly. - -Signed-off-by: Jens Remus -Acked-by: Nick Clifton - -(cherry picked from commit 676b98078f9) ---- - opcodes/s390-opc.txt | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/opcodes/s390-opc.txt b/opcodes/s390-opc.txt -index a3117eeebc5..fb9babf6dcd 100644 ---- a/opcodes/s390-opc.txt -+++ b/opcodes/s390-opc.txt -@@ -942,10 +942,10 @@ ec00000000ff clib$12 RIS_R0RDU "compare logical immediate and branch (32<8)" z10 - ec00000000ff clib RIS_RURDU "compare logical immediate and branch (32<8)" z10 zarch - ec00000000fd clgib$12 RIS_R0RDU "compare logical immediate and branch (64<8)" z10 zarch - ec00000000fd clgib RIS_RURDU "compare logical immediate and branch (64<8)" z10 zarch --ec000000007f clij$12 RIE_R0PU "compare logical immediate and branch relative (32<8)" z10 zarch --ec000000007f clij RIE_RUPU "compare logical immediate and branch relative (32<8)" z10 zarch --ec000000007d clgij$12 RIE_R0PU "compare logical immediate and branch relative (64<8)" z10 zarch --ec000000007d clgij RIE_RUPU "compare logical immediate and branch relative (64<8)" z10 zarch -+ec000000007f clij$12 RIE_R0PU "compare logical immediate and branch relative (32<8)" z10 zarch condjump -+ec000000007f clij RIE_RUPU "compare logical immediate and branch relative (32<8)" z10 zarch condjump -+ec000000007d clgij$12 RIE_R0PU "compare logical immediate and branch relative (64<8)" z10 zarch condjump -+ec000000007d clgij RIE_RUPU "compare logical immediate and branch relative (64<8)" z10 zarch condjump - b9730000 clrt$16 RRF_00RR "compare logical and trap (32)" z10 zarch - b973 clrt RRF_U0RR "compare logical and trap (32)" z10 zarch - b9610000 clgrt$16 RRF_00RR "compare logical and trap (64)" z10 zarch --- -2.43.0 - diff --git a/s390-make-operand-table-indices-relative-to-each-oth.patch b/s390-make-operand-table-indices-relative-to-each-oth.patch deleted file mode 100644 index f2c672d..0000000 --- a/s390-make-operand-table-indices-relative-to-each-oth.patch +++ /dev/null @@ -1,351 +0,0 @@ -From c73a7cf4c74b6475e40fd672a523bfc31a67edaf Mon Sep 17 00:00:00 2001 -From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:45 +0100 -Subject: [PATCH 01/28] s390: Make operand table indices relative to each other - -This is a purely mechanical change. It allows subsequent insertions into -the operands table without having to renumber all operand indices. - -The only differences in the resulting ELF object are in the .debug_info -section. This has been confirmed by diffing the following xxd and readelf -output: - -xxd s390-opc.o -readelf -aW -x .text -x .data -x .bss -x .rodata -x .debug_info \ - -x .symtab -x .strtab -x .shstrtab --debug-dump s390-opc.o - -opcodes/ - * s390-opc.c: Make operand table indices relative to each other. - -Signed-off-by: Jens Remus -Reviewed-by: Andreas Krebbel - -(cherry picked from commit eeafc61979c) ---- - opcodes/s390-opc.c | 174 ++++++++++++++++++++++++--------------------- - 1 file changed, 92 insertions(+), 82 deletions(-) - -diff --git a/opcodes/s390-opc.c b/opcodes/s390-opc.c -index 1910431ab89..b52fc8c3b62 100644 ---- a/opcodes/s390-opc.c -+++ b/opcodes/s390-opc.c -@@ -34,76 +34,82 @@ - inserting operands into instructions and vice-versa is kept in this - file. */ - -+/* Build-time checks are preferrable over runtime ones. Use this construct -+ in preference where possible. */ -+#define static_assert(e) ((void)sizeof (struct { int _:1 - 2 * !(e); })) -+ -+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) -+ - /* The operands table. - The fields are bits, shift, insert, extract, flags. */ - - const struct s390_operand s390_operands[] = - { --#define UNUSED 0 -+#define UNUSED 0 - { 0, 0, 0 }, /* Indicates the end of the operand list */ - - /* General purpose register operands. */ - --#define R_8 1 /* GPR starting at position 8 */ -+#define R_8 (UNUSED + 1) /* GPR starting at position 8 */ - { 4, 8, S390_OPERAND_GPR }, --#define R_12 2 /* GPR starting at position 12 */ -+#define R_12 (R_8 + 1) /* GPR starting at position 12 */ - { 4, 12, S390_OPERAND_GPR }, --#define R_16 3 /* GPR starting at position 16 */ -+#define R_16 (R_12 + 1) /* GPR starting at position 16 */ - { 4, 16, S390_OPERAND_GPR }, --#define R_20 4 /* GPR starting at position 20 */ -+#define R_20 (R_16 + 1) /* GPR starting at position 20 */ - { 4, 20, S390_OPERAND_GPR }, --#define R_24 5 /* GPR starting at position 24 */ -+#define R_24 (R_20 + 1) /* GPR starting at position 24 */ - { 4, 24, S390_OPERAND_GPR }, --#define R_28 6 /* GPR starting at position 28 */ -+#define R_28 (R_24 + 1) /* GPR starting at position 28 */ - { 4, 28, S390_OPERAND_GPR }, --#define R_32 7 /* GPR starting at position 32 */ -+#define R_32 (R_28 + 1) /* GPR starting at position 32 */ - { 4, 32, S390_OPERAND_GPR }, - - /* General purpose register pair operands. */ - --#define RE_8 8 /* GPR starting at position 8 */ -+#define RE_8 (R_32 + 1) /* GPR starting at position 8 */ - { 4, 8, S390_OPERAND_GPR | S390_OPERAND_REG_PAIR }, --#define RE_12 9 /* GPR starting at position 12 */ -+#define RE_12 (RE_8 + 1) /* GPR starting at position 12 */ - { 4, 12, S390_OPERAND_GPR | S390_OPERAND_REG_PAIR }, --#define RE_16 10 /* GPR starting at position 16 */ -+#define RE_16 (RE_12 + 1) /* GPR starting at position 16 */ - { 4, 16, S390_OPERAND_GPR | S390_OPERAND_REG_PAIR }, --#define RE_20 11 /* GPR starting at position 20 */ -+#define RE_20 (RE_16 + 1) /* GPR starting at position 20 */ - { 4, 20, S390_OPERAND_GPR | S390_OPERAND_REG_PAIR }, --#define RE_24 12 /* GPR starting at position 24 */ -+#define RE_24 (RE_20 + 1) /* GPR starting at position 24 */ - { 4, 24, S390_OPERAND_GPR | S390_OPERAND_REG_PAIR }, --#define RE_28 13 /* GPR starting at position 28 */ -+#define RE_28 (RE_24 + 1) /* GPR starting at position 28 */ - { 4, 28, S390_OPERAND_GPR | S390_OPERAND_REG_PAIR }, --#define RE_32 14 /* GPR starting at position 32 */ -+#define RE_32 (RE_28 + 1) /* GPR starting at position 32 */ - { 4, 32, S390_OPERAND_GPR | S390_OPERAND_REG_PAIR }, - - /* Floating point register operands. */ - --#define F_8 15 /* FPR starting at position 8 */ -+#define F_8 (RE_32 + 1) /* FPR starting at position 8 */ - { 4, 8, S390_OPERAND_FPR }, --#define F_12 16 /* FPR starting at position 12 */ -+#define F_12 (F_8 + 1) /* FPR starting at position 12 */ - { 4, 12, S390_OPERAND_FPR }, --#define F_16 17 /* FPR starting at position 16 */ -+#define F_16 (F_12 + 1) /* FPR starting at position 16 */ - { 4, 16, S390_OPERAND_FPR }, --#define F_24 18 /* FPR starting at position 24 */ -+#define F_24 (F_16 + 1) /* FPR starting at position 24 */ - { 4, 24, S390_OPERAND_FPR }, --#define F_28 19 /* FPR starting at position 28 */ -+#define F_28 (F_24 + 1) /* FPR starting at position 28 */ - { 4, 28, S390_OPERAND_FPR }, --#define F_32 20 /* FPR starting at position 32 */ -+#define F_32 (F_28 + 1) /* FPR starting at position 32 */ - { 4, 32, S390_OPERAND_FPR }, - - /* Floating point register pair operands. */ - --#define FE_8 21 /* FPR starting at position 8 */ -+#define FE_8 (F_32 + 1) /* FPR starting at position 8 */ - { 4, 8, S390_OPERAND_FPR | S390_OPERAND_REG_PAIR }, --#define FE_12 22 /* FPR starting at position 12 */ -+#define FE_12 (FE_8 + 1) /* FPR starting at position 12 */ - { 4, 12, S390_OPERAND_FPR | S390_OPERAND_REG_PAIR }, --#define FE_16 23 /* FPR starting at position 16 */ -+#define FE_16 (FE_12 + 1) /* FPR starting at position 16 */ - { 4, 16, S390_OPERAND_FPR | S390_OPERAND_REG_PAIR }, --#define FE_24 24 /* FPR starting at position 24 */ -+#define FE_24 (FE_16 + 1) /* FPR starting at position 24 */ - { 4, 24, S390_OPERAND_FPR | S390_OPERAND_REG_PAIR }, --#define FE_28 25 /* FPR starting at position 28 */ -+#define FE_28 (FE_24 + 1) /* FPR starting at position 28 */ - { 4, 28, S390_OPERAND_FPR | S390_OPERAND_REG_PAIR }, --#define FE_32 26 /* FPR starting at position 32 */ -+#define FE_32 (FE_28 + 1) /* FPR starting at position 32 */ - { 4, 32, S390_OPERAND_FPR | S390_OPERAND_REG_PAIR }, - - /* Vector register operands. */ -@@ -111,145 +117,149 @@ const struct s390_operand s390_operands[] = - /* For each of these operands and additional bit in the RXB operand is - needed. */ - --#define V_8 27 /* Vector reg. starting at position 8 */ -+#define V_8 (FE_32 + 1) /* Vector reg. starting at position 8 */ - { 4, 8, S390_OPERAND_VR }, --#define V_12 28 /* Vector reg. starting at position 12 */ -+#define V_12 (V_8 + 1) /* Vector reg. starting at position 12 */ - { 4, 12, S390_OPERAND_VR }, --#define V_CP16_12 29 /* Vector reg. starting at position 12 */ -+#define V_CP16_12 (V_12 + 1) /* Vector reg. starting at position 12 */ - { 4, 12, S390_OPERAND_VR | S390_OPERAND_CP16 }, /* with a copy at pos 16 */ --#define V_16 30 /* Vector reg. starting at position 16 */ -+#define V_16 (V_CP16_12+1) /* Vector reg. starting at position 16 */ - { 4, 16, S390_OPERAND_VR }, --#define V_32 31 /* Vector reg. starting at position 32 */ -+#define V_32 (V_16 + 1) /* Vector reg. starting at position 32 */ - { 4, 32, S390_OPERAND_VR }, - - /* Access register operands. */ - --#define A_8 32 /* Access reg. starting at position 8 */ -+#define A_8 (V_32 + 1) /* Access reg. starting at position 8 */ - { 4, 8, S390_OPERAND_AR }, --#define A_12 33 /* Access reg. starting at position 12 */ -+#define A_12 (A_8 + 1) /* Access reg. starting at position 12 */ - { 4, 12, S390_OPERAND_AR }, --#define A_24 34 /* Access reg. starting at position 24 */ -+#define A_24 (A_12 + 1) /* Access reg. starting at position 24 */ - { 4, 24, S390_OPERAND_AR }, --#define A_28 35 /* Access reg. starting at position 28 */ -+#define A_28 (A_24 + 1) /* Access reg. starting at position 28 */ - { 4, 28, S390_OPERAND_AR }, - - /* Control register operands. */ - --#define C_8 36 /* Control reg. starting at position 8 */ -+#define C_8 (A_28 + 1) /* Control reg. starting at position 8 */ - { 4, 8, S390_OPERAND_CR }, --#define C_12 37 /* Control reg. starting at position 12 */ -+#define C_12 (C_8 + 1) /* Control reg. starting at position 12 */ - { 4, 12, S390_OPERAND_CR }, - - /* Base register operands. */ - --#define B_16 38 /* Base register starting at position 16 */ -+#define B_16 (C_12 + 1) /* Base register starting at position 16 */ - { 4, 16, S390_OPERAND_BASE | S390_OPERAND_GPR }, --#define B_32 39 /* Base register starting at position 32 */ -+#define B_32 (B_16 + 1) /* Base register starting at position 32 */ - { 4, 32, S390_OPERAND_BASE | S390_OPERAND_GPR }, - --#define X_12 40 /* Index register starting at position 12 */ -+#define X_12 (B_32 + 1) /* Index register starting at position 12 */ - { 4, 12, S390_OPERAND_INDEX | S390_OPERAND_GPR }, - --#define VX_12 41 /* Vector index register starting at position 12 */ -+#define VX_12 (X_12+1) /* Vector index register starting at position 12 */ - { 4, 12, S390_OPERAND_INDEX | S390_OPERAND_VR }, - - /* Address displacement operands. */ - --#define D_20 42 /* Displacement starting at position 20 */ -+#define D_20 (VX_12 + 1) /* Displacement starting at position 20 */ - { 12, 20, S390_OPERAND_DISP }, --#define D_36 43 /* Displacement starting at position 36 */ -+#define D_36 (D_20 + 1) /* Displacement starting at position 36 */ - { 12, 36, S390_OPERAND_DISP }, --#define D20_20 44 /* 20 bit displacement starting at 20 */ -+#define D20_20 (D_36 + 1) /* 20 bit displacement starting at 20 */ - { 20, 20, S390_OPERAND_DISP | S390_OPERAND_SIGNED }, - - /* Length operands. */ - --#define L4_8 45 /* 4 bit length starting at position 8 */ -+#define L4_8 (D20_20 + 1) /* 4 bit length starting at position 8 */ - { 4, 8, S390_OPERAND_LENGTH }, --#define L4_12 46 /* 4 bit length starting at position 12 */ -+#define L4_12 (L4_8 + 1) /* 4 bit length starting at position 12 */ - { 4, 12, S390_OPERAND_LENGTH }, --#define L8_8 47 /* 8 bit length starting at position 8 */ -+#define L8_8 (L4_12 + 1) /* 8 bit length starting at position 8 */ - { 8, 8, S390_OPERAND_LENGTH }, - - /* Signed immediate operands. */ - --#define I8_8 48 /* 8 bit signed value starting at 8 */ -+#define I8_8 (L8_8 + 1) /* 8 bit signed value starting at 8 */ - { 8, 8, S390_OPERAND_SIGNED }, --#define I8_32 49 /* 8 bit signed value starting at 32 */ -+#define I8_32 (I8_8 + 1) /* 8 bit signed value starting at 32 */ - { 8, 32, S390_OPERAND_SIGNED }, --#define I12_12 50 /* 12 bit signed value starting at 12 */ -+#define I12_12 (I8_32 + 1) /* 12 bit signed value starting at 12 */ - { 12, 12, S390_OPERAND_SIGNED }, --#define I16_16 51 /* 16 bit signed value starting at 16 */ -+#define I16_16 (I12_12 + 1) /* 16 bit signed value starting at 16 */ - { 16, 16, S390_OPERAND_SIGNED }, --#define I16_32 52 /* 16 bit signed value starting at 32 */ -+#define I16_32 (I16_16 + 1) /* 16 bit signed value starting at 32 */ - { 16, 32, S390_OPERAND_SIGNED }, --#define I24_24 53 /* 24 bit signed value starting at 24 */ -+#define I24_24 (I16_32 + 1) /* 24 bit signed value starting at 24 */ - { 24, 24, S390_OPERAND_SIGNED }, --#define I32_16 54 /* 32 bit signed value starting at 16 */ -+#define I32_16 (I24_24 + 1) /* 32 bit signed value starting at 16 */ - { 32, 16, S390_OPERAND_SIGNED }, - - /* Unsigned immediate operands. */ - --#define U4_8 55 /* 4 bit unsigned value starting at 8 */ -+#define U4_8 (I32_16 + 1) /* 4 bit unsigned value starting at 8 */ - { 4, 8, 0 }, --#define U4_12 56 /* 4 bit unsigned value starting at 12 */ -+#define U4_12 (U4_8 + 1) /* 4 bit unsigned value starting at 12 */ - { 4, 12, 0 }, --#define U4_16 57 /* 4 bit unsigned value starting at 16 */ -+#define U4_16 (U4_12 + 1) /* 4 bit unsigned value starting at 16 */ - { 4, 16, 0 }, --#define U4_20 58 /* 4 bit unsigned value starting at 20 */ -+#define U4_20 (U4_16 + 1) /* 4 bit unsigned value starting at 20 */ - { 4, 20, 0 }, --#define U4_24 59 /* 4 bit unsigned value starting at 24 */ -+#define U4_24 (U4_20 + 1) /* 4 bit unsigned value starting at 24 */ - { 4, 24, 0 }, --#define U4_OR1_24 60 /* 4 bit unsigned value ORed with 1 */ -+#define U4_OR1_24 (U4_24 + 1) /* 4 bit unsigned value ORed with 1 */ - { 4, 24, S390_OPERAND_OR1 }, /* starting at 24 */ --#define U4_OR2_24 61 /* 4 bit unsigned value ORed with 2 */ -+#define U4_OR2_24 (U4_OR1_24+1) /* 4 bit unsigned value ORed with 2 */ - { 4, 24, S390_OPERAND_OR2 }, /* starting at 24 */ --#define U4_OR3_24 62 /* 4 bit unsigned value ORed with 3 */ -+#define U4_OR3_24 (U4_OR2_24+1) /* 4 bit unsigned value ORed with 3 */ - { 4, 24, S390_OPERAND_OR1 | S390_OPERAND_OR2 }, /* starting at 24 */ --#define U4_28 63 /* 4 bit unsigned value starting at 28 */ -+#define U4_28 (U4_OR3_24+1) /* 4 bit unsigned value starting at 28 */ - { 4, 28, 0 }, --#define U4_OR8_28 64 /* 4 bit unsigned value ORed with 8 */ -+#define U4_OR8_28 (U4_28 + 1) /* 4 bit unsigned value ORed with 8 */ - { 4, 28, S390_OPERAND_OR8 }, /* starting at 28 */ --#define U4_32 65 /* 4 bit unsigned value starting at 32 */ -+#define U4_32 (U4_OR8_28+1) /* 4 bit unsigned value starting at 32 */ - { 4, 32, 0 }, --#define U4_36 66 /* 4 bit unsigned value starting at 36 */ -+#define U4_36 (U4_32 + 1) /* 4 bit unsigned value starting at 36 */ - { 4, 36, 0 }, --#define U8_8 67 /* 8 bit unsigned value starting at 8 */ -+#define U8_8 (U4_36 + 1) /* 8 bit unsigned value starting at 8 */ - { 8, 8, 0 }, --#define U8_16 68 /* 8 bit unsigned value starting at 16 */ -+#define U8_16 (U8_8 + 1) /* 8 bit unsigned value starting at 16 */ - { 8, 16, 0 }, --#define U6_26 69 /* 6 bit unsigned value starting at 26 */ -+#define U6_26 (U8_16 + 1) /* 6 bit unsigned value starting at 26 */ - { 6, 26, 0 }, --#define U8_24 70 /* 8 bit unsigned value starting at 24 */ -+#define U8_24 (U6_26 + 1) /* 8 bit unsigned value starting at 24 */ - { 8, 24, 0 }, --#define U8_28 71 /* 8 bit unsigned value starting at 28 */ -+#define U8_28 (U8_24 + 1) /* 8 bit unsigned value starting at 28 */ - { 8, 28, 0 }, --#define U8_32 72 /* 8 bit unsigned value starting at 32 */ -+#define U8_32 (U8_28 + 1) /* 8 bit unsigned value starting at 32 */ - { 8, 32, 0 }, --#define U12_16 73 /* 12 bit unsigned value starting at 16 */ -+#define U12_16 (U8_32 + 1) /* 12 bit unsigned value starting at 16 */ - { 12, 16, 0 }, --#define U16_16 74 /* 16 bit unsigned value starting at 16 */ -+#define U16_16 (U12_16 + 1) /* 16 bit unsigned value starting at 16 */ - { 16, 16, 0 }, --#define U16_32 75 /* 16 bit unsigned value starting at 32 */ -+#define U16_32 (U16_16 + 1) /* 16 bit unsigned value starting at 32 */ - { 16, 32, 0 }, --#define U32_16 76 /* 32 bit unsigned value starting at 16 */ -+#define U32_16 (U16_32 + 1) /* 32 bit unsigned value starting at 16 */ - { 32, 16, 0 }, - - /* PC-relative address operands. */ - --#define J12_12 77 /* 12 bit PC relative offset at 12 */ -+#define J12_12 (U32_16 + 1) /* 12 bit PC relative offset at 12 */ - { 12, 12, S390_OPERAND_PCREL }, --#define J16_16 78 /* 16 bit PC relative offset at 16 */ -+#define J16_16 (J12_12 + 1) /* 16 bit PC relative offset at 16 */ - { 16, 16, S390_OPERAND_PCREL }, --#define J16_32 79 /* 16 bit PC relative offset at 32 */ -+#define J16_32 (J16_16 + 1) /* 16 bit PC relative offset at 32 */ - { 16, 32, S390_OPERAND_PCREL }, --#define J24_24 80 /* 24 bit PC relative offset at 24 */ -+#define J24_24 (J16_32 + 1) /* 24 bit PC relative offset at 24 */ - { 24, 24, S390_OPERAND_PCREL }, --#define J32_16 81 /* 32 bit PC relative offset at 16 */ -+#define J32_16 (J24_24 + 1) /* 32 bit PC relative offset at 16 */ - { 32, 16, S390_OPERAND_PCREL }, - - }; - -+static inline void unused_s390_operands_static_asserts(void) -+{ -+ static_assert(ARRAY_SIZE(s390_operands) - 1 == J32_16); -+} - - /* Macros used to form opcodes. */ - - -base-commit: 2c6833c34f65125bde92903e8d59cde5880cbcfe --- -2.43.0 - diff --git a/s390-optionally-print-instruction-description-in-dis.patch b/s390-optionally-print-instruction-description-in-dis.patch deleted file mode 100644 index bb73c23..0000000 --- a/s390-optionally-print-instruction-description-in-dis.patch +++ /dev/null @@ -1,302 +0,0 @@ -From d4f0bee2d3d8ce1477319d3a35d92671812cb26e Mon Sep 17 00:00:00 2001 -From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:48 +0100 -Subject: [PATCH 10/28] s390: Optionally print instruction description in - disassembly - -Print instruction description as comment in disassembly with s390 -architecture specific option "insndesc": - -- For objdump it can be enabled with option "-M insndesc" -- In gdb it can be enabled with "set disassembler-options insndesc" - -Since comments are not column aligned the output can enhanced for -readability by postprocessing using a filter such as "expand": - -... | expand -t 8,16,24,32,40,80 - -Or when using in combination with objdump option --visualize-jumps: - -... | expand | sed -e 's/ *#/\t#/' | expand -t 1,80 - -Note that the instruction descriptions add about 128 KB to s390-opc.o: - -s390-opc.o without instruction descriptions: 216368 bytes -s390-opc.o with instruction descriptions : 348432 bytes - -binutils/ - * NEWS: Mention new s390-specific disassembler option - "insndesc". - -include/ - * opcode/s390.h (struct s390_opcode): Add field to hold - instruction description. - -opcodes/ - * s390-mkopc.c: Copy instruction description from s390-opc.txt - into generated operation code table s390-opc.tab. - * s390-opc.c (s390_opformats): Provide NULL as description in - .insn pseudo-mnemonics opcode table. - * s390-dis.c: Add s390-specific disassembler option "insndesc" - and optionally print the instruction description as comment in - the disassembly when it is specified. - -gas/ - * testsuite/gas/s390/s390.exp: Add new test disassembly test - case "zarch-insndesc". - * testsuite/gas/s390/zarch-insndesc.s: New test case for s390- - specific disassembler option "insndesc". - * testsuite/gas/s390/zarch-insndesc.d: Likewise. - -Signed-off-by: Jens Remus -Reviewed-by: Andreas Krebbel - -(cherry picked from commit f96fe7f454b) -(cherry pick dropped: binutils/NEWS) -(cherry pick dropped: gas/testsuite/gas/s390/s390.exp) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-insndesc.d) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-insndesc.s) ---- - include/opcode/s390.h | 5 +++- - opcodes/s390-dis.c | 13 ++++++++- - opcodes/s390-mkopc.c | 19 ++++++++----- - opcodes/s390-opc.c | 62 +++++++++++++++++++++---------------------- - 4 files changed, 59 insertions(+), 40 deletions(-) - -diff --git a/include/opcode/s390.h b/include/opcode/s390.h -index d540e1dfd00..319bfe2d629 100644 ---- a/include/opcode/s390.h -+++ b/include/opcode/s390.h -@@ -81,7 +81,7 @@ enum s390_opcode_cpu_val - - struct s390_opcode - { -- /* The opcode name. */ -+ /* The opcode name (mnemonic). */ - const char * name; - - /* The opcode itself. Those bits which will be filled in with -@@ -110,6 +110,9 @@ struct s390_opcode - - /* Instruction specific flags. */ - unsigned int flags; -+ -+ /* Instruction description. */ -+ const char * description; - }; - - /* The table itself is sorted by major opcode number, and is otherwise -diff --git a/opcodes/s390-dis.c b/opcodes/s390-dis.c -index 8c8a98c4e24..fca965fbb5d 100644 ---- a/opcodes/s390-dis.c -+++ b/opcodes/s390-dis.c -@@ -31,6 +31,7 @@ - static int opc_index[256]; - static int current_arch_mask = 0; - static int option_use_insn_len_bits_p = 0; -+static int option_print_insn_desc = 0; - - typedef struct - { -@@ -43,7 +44,8 @@ static const s390_options_t options[] = - { "esa" , N_("Disassemble in ESA architecture mode") }, - { "zarch", N_("Disassemble in z/Architecture mode") }, - { "insnlength", N_("Print unknown instructions according to " -- "length from first two bits") } -+ "length from first two bits") }, -+ { "insndesc", N_("Print instruction description as comment") }, - }; - - /* Set up index table for first opcode byte. */ -@@ -63,6 +65,7 @@ disassemble_init_s390 (struct disassemble_info *info) - - current_arch_mask = 1 << S390_OPCODE_ZARCH; - option_use_insn_len_bits_p = 0; -+ option_print_insn_desc = 0; - - for (p = info->disassembler_options; p != NULL; ) - { -@@ -72,6 +75,8 @@ disassemble_init_s390 (struct disassemble_info *info) - current_arch_mask = 1 << S390_OPCODE_ZARCH; - else if (startswith (p, "insnlength")) - option_use_insn_len_bits_p = 1; -+ else if (startswith (p, "insndesc")) -+ option_print_insn_desc = 1; - else - /* xgettext:c-format */ - opcodes_error_handler (_("unknown S/390 disassembler option: %s"), p); -@@ -311,6 +316,12 @@ s390_print_insn_with_opcode (bfd_vma memaddr, - else - separator = ','; - } -+ -+ /* Optional: instruction name. */ -+ if (option_print_insn_desc && opcode->description -+ && opcode->description[0] != '\0') -+ info->fprintf_styled_func (info->stream, dis_style_comment_start, "\t# %s", -+ opcode->description); - } - - /* Check whether opcode A's mask is more specific than that of B. */ -diff --git a/opcodes/s390-mkopc.c b/opcodes/s390-mkopc.c -index eae0397d497..c6930a3e9b5 100644 ---- a/opcodes/s390-mkopc.c -+++ b/opcodes/s390-mkopc.c -@@ -63,6 +63,7 @@ struct op_struct - int mode_bits; - int min_cpu; - int flags; -+ char description[MAX_DESCRIPTION_LEN + 1]; - - unsigned long long sort_value; - int no_nibbles; -@@ -84,7 +85,7 @@ createTable (void) - - static void - insertOpcode (char *opcode, char *mnemonic, char *format, -- int min_cpu, int mode_bits, int flags) -+ int min_cpu, int mode_bits, int flags, char* description) - { - char *str; - unsigned long long sort_value; -@@ -132,6 +133,8 @@ insertOpcode (char *opcode, char *mnemonic, char *format, - op_array[ix].min_cpu = min_cpu; - op_array[ix].mode_bits = mode_bits; - op_array[ix].flags = flags; -+ strncpy (op_array[ix].description, description, MAX_DESCRIPTION_LEN); -+ op_array[ix].description[MAX_DESCRIPTION_LEN] = '\0'; - no_ops++; - } - -@@ -193,7 +196,7 @@ const struct s390_cond_ext_format s390_crb_extensions[NUM_CRB_EXTENSIONS] = - - static void - insertExpandedMnemonic (char *opcode, char *mnemonic, char *format, -- int min_cpu, int mode_bits, int flags) -+ int min_cpu, int mode_bits, int flags, char *description) - { - char *tag; - char prefix[MAX_MNEMONIC_LEN + 1]; -@@ -206,7 +209,7 @@ insertExpandedMnemonic (char *opcode, char *mnemonic, char *format, - - if (!(tag = strpbrk (mnemonic, "*$"))) - { -- insertOpcode (opcode, mnemonic, format, min_cpu, mode_bits, flags); -+ insertOpcode (opcode, mnemonic, format, min_cpu, mode_bits, flags, description); - return; - } - -@@ -290,7 +293,7 @@ insertExpandedMnemonic (char *opcode, char *mnemonic, char *format, - return; - } - -- insertOpcode (opcode, new_mnemonic, format, min_cpu, mode_bits, flags); -+ insertOpcode (opcode, new_mnemonic, format, min_cpu, mode_bits, flags, description); - } - return; - -@@ -311,7 +314,8 @@ static const char file_header[] = - " instruction which matches.\n" - " MODE_BITS - zarch or esa\n" - " MIN_CPU - number of the min cpu level required\n" -- " FLAGS - instruction flags. */\n\n" -+ " FLAGS - instruction flags.\n" -+ " DESCRIPTION - description of the instruction. */\n\n" - "const struct s390_opcode s390_opcodes[] =\n {\n"; - - /* `dumpTable': write opcode table. */ -@@ -337,7 +341,8 @@ dumpTable (void) - op_array[ix].format, op_array[ix].format); - printf ("%i, ", op_array[ix].mode_bits); - printf ("%i, ", op_array[ix].min_cpu); -- printf ("%i}", op_array[ix].flags); -+ printf ("%i, ", op_array[ix].flags); -+ printf ("\"%s\" }", op_array[ix].description); - if (ix < no_ops-1) - printf (",\n"); - else -@@ -497,7 +502,7 @@ main (void) - str++; - } while (*str != 0); - } -- insertExpandedMnemonic (opcode, mnemonic, format, min_cpu, mode_bits, flag_bits); -+ insertExpandedMnemonic (opcode, mnemonic, format, min_cpu, mode_bits, flag_bits, description); - - continue_loop: - ; -diff --git a/opcodes/s390-opc.c b/opcodes/s390-opc.c -index cbfdb3df0b7..e44621a7479 100644 ---- a/opcodes/s390-opc.c -+++ b/opcodes/s390-opc.c -@@ -774,37 +774,37 @@ unused_s390_operands_static_asserts (void) - - const struct s390_opcode s390_opformats[] = - { -- { "e", OP8(0x00LL), MASK_E, INSTR_E, 3, 0 ,0 }, -- { "ri", OP8(0x00LL), MASK_RI_RI, INSTR_RI_RI, 3, 0 ,0 }, -- { "rie", OP8(0x00LL), MASK_RIE_RRP, INSTR_RIE_RRP, 3, 0 ,0 }, -- { "ril", OP8(0x00LL), MASK_RIL_RP, INSTR_RIL_RP, 3, 0 ,0 }, -- { "rilu", OP8(0x00LL), MASK_RIL_RU, INSTR_RIL_RU, 3, 0 ,0 }, -- { "ris", OP8(0x00LL), MASK_RIS_RURDI, INSTR_RIS_RURDI, 3, 6 ,0 }, -- { "rr", OP8(0x00LL), MASK_RR_RR, INSTR_RR_RR, 3, 0 ,0 }, -- { "rre", OP8(0x00LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0 ,0 }, -- { "rrf", OP8(0x00LL), MASK_RRF_RURR, INSTR_RRF_RURR, 3, 0 ,0 }, -- { "rrs", OP8(0x00LL), MASK_RRS_RRRDU, INSTR_RRS_RRRDU, 3, 6 ,0 }, -- { "rs", OP8(0x00LL), MASK_RS_RRRD, INSTR_RS_RRRD, 3, 0 ,0 }, -- { "rse", OP8(0x00LL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 3, 0 ,0 }, -- { "rsi", OP8(0x00LL), MASK_RSI_RRP, INSTR_RSI_RRP, 3, 0 ,0 }, -- { "rsy", OP8(0x00LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 3, 3 ,0 }, -- { "rx", OP8(0x00LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0 ,0 }, -- { "rxe", OP8(0x00LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 3, 0 ,0 }, -- { "rxf", OP8(0x00LL), MASK_RXF_RRRDR, INSTR_RXF_RRRDR, 3, 0 ,0 }, -- { "rxy", OP8(0x00LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 3, 3 ,0 }, -- { "s", OP8(0x00LL), MASK_S_RD, INSTR_S_RD, 3, 0 ,0 }, -- { "si", OP8(0x00LL), MASK_SI_URD, INSTR_SI_URD, 3, 0 ,0 }, -- { "siy", OP8(0x00LL), MASK_SIY_URD, INSTR_SIY_URD, 3, 3 ,0 }, -- { "sil", OP8(0x00LL), MASK_SIL_RDI, INSTR_SIL_RDI, 3, 6 ,0 }, -- { "ss", OP8(0x00LL), MASK_SS_RRRDRD, INSTR_SS_RRRDRD, 3, 0 ,0 }, -- { "sse", OP8(0x00LL), MASK_SSE_RDRD, INSTR_SSE_RDRD, 3, 0 ,0 }, -- { "ssf", OP8(0x00LL), MASK_SSF_RRDRD, INSTR_SSF_RRDRD, 3, 0 ,0 }, -- { "vrv", OP8(0x00LL), MASK_VRV_VVXRDU, INSTR_VRV_VVXRDU, 3, 9 ,0 }, -- { "vri", OP8(0x00LL), MASK_VRI_VVUUU, INSTR_VRI_VVUUU, 3, 9 ,0 }, -- { "vrx", OP8(0x00LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 3, 9 ,0 }, -- { "vrs", OP8(0x00LL), MASK_VRS_RVRDU, INSTR_VRS_RVRDU, 3, 9 ,0 }, -- { "vrr", OP8(0x00LL), MASK_VRR_VVV0UUU, INSTR_VRR_VVV0UUU, 3, 9 ,0 }, -- { "vsi", OP8(0x00LL), MASK_VSI_URDV, INSTR_VSI_URDV, 3, 10 ,0 }, -+ { "e", OP8(0x00LL), MASK_E, INSTR_E, 3, 0, 0, NULL }, -+ { "ri", OP8(0x00LL), MASK_RI_RI, INSTR_RI_RI, 3, 0, 0, NULL }, -+ { "rie", OP8(0x00LL), MASK_RIE_RRP, INSTR_RIE_RRP, 3, 0, 0, NULL }, -+ { "ril", OP8(0x00LL), MASK_RIL_RP, INSTR_RIL_RP, 3, 0, 0, NULL }, -+ { "rilu", OP8(0x00LL), MASK_RIL_RU, INSTR_RIL_RU, 3, 0, 0, NULL }, -+ { "ris", OP8(0x00LL), MASK_RIS_RURDI, INSTR_RIS_RURDI, 3, 6, 0, NULL }, -+ { "rr", OP8(0x00LL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, NULL }, -+ { "rre", OP8(0x00LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, NULL }, -+ { "rrf", OP8(0x00LL), MASK_RRF_RURR, INSTR_RRF_RURR, 3, 0, 0, NULL }, -+ { "rrs", OP8(0x00LL), MASK_RRS_RRRDU, INSTR_RRS_RRRDU, 3, 6, 0, NULL }, -+ { "rs", OP8(0x00LL), MASK_RS_RRRD, INSTR_RS_RRRD, 3, 0, 0, NULL }, -+ { "rse", OP8(0x00LL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 3, 0, 0, NULL }, -+ { "rsi", OP8(0x00LL), MASK_RSI_RRP, INSTR_RSI_RRP, 3, 0, 0, NULL }, -+ { "rsy", OP8(0x00LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 3, 3, 0, NULL }, -+ { "rx", OP8(0x00LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, NULL }, -+ { "rxe", OP8(0x00LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 3, 0, 0, NULL }, -+ { "rxf", OP8(0x00LL), MASK_RXF_RRRDR, INSTR_RXF_RRRDR, 3, 0, 0, NULL }, -+ { "rxy", OP8(0x00LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 3, 3, 0, NULL }, -+ { "s", OP8(0x00LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, NULL }, -+ { "si", OP8(0x00LL), MASK_SI_URD, INSTR_SI_URD, 3, 0, 0, NULL }, -+ { "siy", OP8(0x00LL), MASK_SIY_URD, INSTR_SIY_URD, 3, 3, 0, NULL }, -+ { "sil", OP8(0x00LL), MASK_SIL_RDI, INSTR_SIL_RDI, 3, 6, 0, NULL }, -+ { "ss", OP8(0x00LL), MASK_SS_RRRDRD, INSTR_SS_RRRDRD, 3, 0, 0, NULL }, -+ { "sse", OP8(0x00LL), MASK_SSE_RDRD, INSTR_SSE_RDRD, 3, 0, 0, NULL }, -+ { "ssf", OP8(0x00LL), MASK_SSF_RRDRD, INSTR_SSF_RRDRD, 3, 0, 0, NULL }, -+ { "vrv", OP8(0x00LL), MASK_VRV_VVXRDU, INSTR_VRV_VVXRDU, 3, 9, 0, NULL }, -+ { "vri", OP8(0x00LL), MASK_VRI_VVUUU, INSTR_VRI_VVUUU, 3, 9, 0, NULL }, -+ { "vrx", OP8(0x00LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 3, 9, 0, NULL }, -+ { "vrs", OP8(0x00LL), MASK_VRS_RVRDU, INSTR_VRS_RVRDU, 3, 9, 0, NULL }, -+ { "vrr", OP8(0x00LL), MASK_VRR_VVV0UUU, INSTR_VRR_VVV0UUU, 3, 9, 0, NULL }, -+ { "vsi", OP8(0x00LL), MASK_VSI_URDV, INSTR_VSI_URDV, 3, 10, 0, NULL }, - }; - - const int s390_num_opformats = --- -2.43.0 - diff --git a/s390-print-base-register-0-as-0-in-disassembly.patch b/s390-print-base-register-0-as-0-in-disassembly.patch deleted file mode 100644 index 876698a..0000000 --- a/s390-print-base-register-0-as-0-in-disassembly.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 1a7f5c1ceb3b72a84c4f60a32b79216f58c77bd9 Mon Sep 17 00:00:00 2001 -From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:50 +0100 -Subject: [PATCH 17/28] s390: Print base register 0 as "0" in disassembly - -Base and index register 0 have no effect in address computation: - -"A value of zero in the B [base] or X [index] field specifies that no -base or index is to be applied, and, thus, general register 0 cannot be -designated as containing a base address or index." -IBM z/Architecture Principles of Operation [1], chapter "Organization", -section "General Registers". - -Index register 0 is omitted in the s390 disassembly. Base register 0 is -omitted in D(B), D(L,B) and D(X,B) - the latter only if the index -register is zero. - -To make it more apparent print base register 0 as "0" instead of "%r0", -whenever it would still be printed in the disassembly. - -[1]: IBM z/Architecture Principles of Operation, SA22-7832-13, - https://publibfp.dhe.ibm.com/epubs/pdf/a227832d.pdf - -opcodes/ - * s390-dis.c: Print base register 0 as "0" in disassembly. - -binutils/ - * NEWS: Mention base register 0 now being printed as "0" in s390 - disassembly. - -gas/ - * testsuite/gas/s390/zarch-base-index-0.d: Update test case - output verification patterns to accept "0" as base base - register due to disassembler output format change. - * gas/testsuite/gas/s390/zarch-omitted-base-index.d: Likewise. - -Reviewed-by: Andreas Krebbel -Signed-off-by: Jens Remus - -(cherry picked from commit 75a28d1a97a) -(cherry pick dropped: binutils/NEWS) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-base-index-0.d) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-omitted-base-index.d) ---- - opcodes/s390-dis.c | 17 +++++++++++++---- - 1 file changed, 13 insertions(+), 4 deletions(-) - -diff --git a/opcodes/s390-dis.c b/opcodes/s390-dis.c -index b1ff1a862a2..d88e82bc4a1 100644 ---- a/opcodes/s390-dis.c -+++ b/opcodes/s390-dis.c -@@ -234,8 +234,13 @@ s390_print_insn_with_opcode (bfd_vma memaddr, - { - info->fprintf_styled_func (info->stream, dis_style_text, - "%c", separator); -- info->fprintf_styled_func (info->stream, dis_style_register, -- "%%r%u", val.u); -+ if ((flags & (S390_OPERAND_BASE | S390_OPERAND_INDEX)) -+ && val.u == 0) -+ info->fprintf_styled_func (info->stream, dis_style_register, -+ "%u", val.u); -+ else -+ info->fprintf_styled_func (info->stream, dis_style_register, -+ "%%r%u", val.u); - } - else if (flags & S390_OPERAND_FPR) - { -@@ -248,8 +253,12 @@ s390_print_insn_with_opcode (bfd_vma memaddr, - { - info->fprintf_styled_func (info->stream, dis_style_text, - "%c", separator); -- info->fprintf_styled_func (info->stream, dis_style_register, -- "%%v%i", val.u); -+ if ((flags & S390_OPERAND_INDEX) && val.u == 0) -+ info->fprintf_styled_func (info->stream, dis_style_register, -+ "%u", val.u); -+ else -+ info->fprintf_styled_func (info->stream, dis_style_register, -+ "%%v%i", val.u); - } - else if (flags & S390_OPERAND_AR) - { --- -2.43.0 - diff --git a/s390-provide-ibm-z16-arch14-instruction-descriptions.patch b/s390-provide-ibm-z16-arch14-instruction-descriptions.patch deleted file mode 100644 index e4307e7..0000000 --- a/s390-provide-ibm-z16-arch14-instruction-descriptions.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 789e5514da246a792a78ce5f61a6c286f874b03c Mon Sep 17 00:00:00 2001 -From: Jens Remus -Date: Wed, 20 Dec 2023 11:16:38 +0100 -Subject: [PATCH 1/2] s390: Provide IBM z16 (arch14) instruction descriptions - -Provide descriptions for instructions introduced with commit ba2b480f103 -("IBM Z: Implement instruction set extensions"). This complements commit -69341966def ("IBM zSystems: Add support for z16 as CPU name."). Use -instruction names from IBM z/Architecture Principles of Operation [1] as -instruction description. - -[1]: IBM z/Architecture Principles of Operation, SA22-7832-13, IBM z16, - https://publibfp.dhe.ibm.com/epubs/pdf/a227832d.pdf - -opcodes/ - * s390-opc.txt: Add descriptions for IBM z16 (arch14) - instructions. - -Signed-off-by: Jens Remus -Reviewed-by: Andreas Krebbel ---- - opcodes/s390-opc.txt | 66 +++++++++++++++++++++++++------------------- - 1 file changed, 38 insertions(+), 28 deletions(-) - -diff --git a/opcodes/s390-opc.txt b/opcodes/s390-opc.txt -index b7efa813e47..b33ee34ea8f 100644 ---- a/opcodes/s390-opc.txt -+++ b/opcodes/s390-opc.txt -@@ -2018,31 +2018,41 @@ e60000000052 vcvbg VRR_RV0UU "vector convert to binary 64 bit" arch13 zarch optp - b93a kdsa RRE_RR "compute digital signature authentication" arch13 zarch - - --# arch14 instructions -- --e60000000074 vschp VRR_VVV0U0U " " arch14 zarch --e60000002074 vschsp VRR_VVV0U0 " " arch14 zarch --e60000003074 vschdp VRR_VVV0U0 " " arch14 zarch --e60000004074 vschxp VRR_VVV0U0 " " arch14 zarch --e6000000007c vscshp VRR_VVV " " arch14 zarch --e6000000007d vcsph VRR_VVV0U0 " " arch14 zarch --e60000000051 vclzdp VRR_VV0U2 " " arch14 zarch --e60000000070 vpkzr VRI_VVV0UU2 " " arch14 zarch --e60000000072 vsrpr VRI_VVV0UU2 " " arch14 zarch --e60000000054 vupkzh VRR_VV0U2 " " arch14 zarch --e6000000005c vupkzl VRR_VV0U2 " " arch14 zarch -- --b93b nnpa RRE_00 " " arch14 zarch --e60000000056 vclfnh VRR_VV0UU2 " " arch14 zarch --e6000000005e vclfnl VRR_VV0UU2 " " arch14 zarch --e60000000075 vcrnf VRR_VVV0UU " " arch14 zarch --e6000000005d vcfn VRR_VV0UU2 " " arch14 zarch --e60000000055 vcnf VRR_VV0UU2 " " arch14 zarch -- --b98B rdp RRF_RURR2 " " arch14 zarch optparm -- --eb0000000071 lpswey SIY_RD " " arch14 zarch --b200 lbear S_RD " " arch14 zarch --b201 stbear S_RD " " arch14 zarch -- --b28f qpaci S_RD " " arch14 zarch -+# arch14 (z16) instructions -+ -+# Vector-Packed-Decimal-Enhancement Facility 2 -+ -+e60000000074 vschp VRR_VVV0U0U "decimal scale and convert to hfp" arch14 zarch -+e60000002074 vschsp VRR_VVV0U0 "decimal scale and convert to short hfp" arch14 zarch -+e60000003074 vschdp VRR_VVV0U0 "decimal scale and convert to long hfp" arch14 zarch -+e60000004074 vschxp VRR_VVV0U0 "decimal scale and convert to extended hfp" arch14 zarch -+e6000000007c vscshp VRR_VVV "decimal scale and convert and split to hfp" arch14 zarch -+e6000000007d vcsph VRR_VVV0U0 "vector convert hfp to scaled decimal" arch14 zarch -+e60000000051 vclzdp VRR_VV0U2 "vector count leading zero digits" arch14 zarch -+e60000000070 vpkzr VRI_VVV0UU2 "vector pack zoned register" arch14 zarch -+e60000000072 vsrpr VRI_VVV0UU2 "vector shift and round decimal register" arch14 zarch -+e60000000054 vupkzh VRR_VV0U2 "vector unpack zoned high" arch14 zarch -+e6000000005c vupkzl VRR_VV0U2 "vector unpack zoned low" arch14 zarch -+ -+# Neural-Network-Processing-Assist Facility -+ -+b93b nnpa RRE_00 "neural network processing assist" arch14 zarch -+e60000000056 vclfnh VRR_VV0UU2 "vector fp convert and lengthen from nnp high" arch14 zarch -+e6000000005e vclfnl VRR_VV0UU2 "vector fp convert and lengthen from nnp low" arch14 zarch -+e60000000075 vcrnf VRR_VVV0UU "vector fp convert and round to nnp" arch14 zarch -+e6000000005d vcfn VRR_VV0UU2 "vector fp convert from nnp" arch14 zarch -+e60000000055 vcnf VRR_VV0UU2 "vector fp convert to nnp" arch14 zarch -+ -+# Reset-DAT-Protection Facility -+ -+b98B rdp RRF_RURR2 "reset dat protection" arch14 zarch optparm -+ -+# BEAR-Enhancement Facility -+ -+eb0000000071 lpswey SIY_RD "load PSW extended" arch14 zarch -+b200 lbear S_RD "load bear" arch14 zarch -+b201 stbear S_RD "store bear" arch14 zarch -+ -+# Processor-Activity-Instrumentation Facility -+ -+b28f qpaci S_RD "query processor activity counter information" arch14 zarch - -base-commit: 84b9218d98eb2ac242fe3afc81598206279f7b13 --- -2.35.3 - diff --git a/s390-relax-risbg-n-z-risb-h-l-gz-rns-ros-rxs-bgt-ope.patch b/s390-relax-risbg-n-z-risb-h-l-gz-rns-ros-rxs-bgt-ope.patch index 95a331d..021a7a9 100644 --- a/s390-relax-risbg-n-z-risb-h-l-gz-rns-ros-rxs-bgt-ope.patch +++ b/s390-relax-risbg-n-z-risb-h-l-gz-rns-ros-rxs-bgt-ope.patch @@ -1,7 +1,7 @@ -From 4937386aac97ff53c395b2cf0ea0dd7c8f4383a4 Mon Sep 17 00:00:00 2001 +From 4ace867f88db894184062814e6ae71e0b9dfffd8 Mon Sep 17 00:00:00 2001 From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:51 +0100 -Subject: [PATCH 21/28] s390: Relax risbg[n]z, risb{h|l}gz, {rns|ros|rxs}bgt +Date: Fri, 7 Mar 2025 13:06:51 +0100 +Subject: [PATCH 03/10] s390: Relax risbg[n]z, risb{h|l}gz, {rns|ros|rxs}bgt operand constraints This leverages commit ("s390: Simplify (dis)assembly of insn operands @@ -51,7 +51,7 @@ Signed-off-by: Jens Remus 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/opcodes/s390-opc.c b/opcodes/s390-opc.c -index 47ba37b5dc6..4fd0065a058 100644 +index 987004d7b07..fe0299aa4e5 100644 --- a/opcodes/s390-opc.c +++ b/opcodes/s390-opc.c @@ -216,15 +216,9 @@ const struct s390_operand s390_operands[] = diff --git a/s390-simplify-dis-assembly-of-insn-operands-with-con.patch b/s390-simplify-dis-assembly-of-insn-operands-with-con.patch index f92bd68..b0b8974 100644 --- a/s390-simplify-dis-assembly-of-insn-operands-with-con.patch +++ b/s390-simplify-dis-assembly-of-insn-operands-with-con.patch @@ -1,7 +1,7 @@ -From 4f0c674b6694a484d46a4e7768ab3d98746d9bc1 Mon Sep 17 00:00:00 2001 +From 0a5b57ac3e464b3e4a1eaf4aba5d6bd8c98b7186 Mon Sep 17 00:00:00 2001 From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:51 +0100 -Subject: [PATCH 20/28] s390: Simplify (dis)assembly of insn operands with +Date: Fri, 7 Mar 2025 13:06:51 +0100 +Subject: [PATCH 02/10] s390: Simplify (dis)assembly of insn operands with const bits Simplify assembly and disassembly of extended mnemonics with operands @@ -66,7 +66,7 @@ Signed-off-by: Jens Remus 3 files changed, 17 insertions(+), 27 deletions(-) diff --git a/include/opcode/s390.h b/include/opcode/s390.h -index 772552b5397..19f973a7306 100644 +index e5dfcb27570..8de03701172 100644 --- a/include/opcode/s390.h +++ b/include/opcode/s390.h @@ -193,8 +193,4 @@ extern const struct s390_operand s390_operands[]; @@ -79,7 +79,7 @@ index 772552b5397..19f973a7306 100644 - #endif /* S390_H */ diff --git a/opcodes/s390-dis.c b/opcodes/s390-dis.c -index d88e82bc4a1..2050d8b13a1 100644 +index ee2f2cb62ed..852d2f6ebb9 100644 --- a/opcodes/s390-dis.c +++ b/opcodes/s390-dis.c @@ -299,12 +299,14 @@ s390_print_insn_with_opcode (bfd_vma memaddr, @@ -104,7 +104,7 @@ index d88e82bc4a1..2050d8b13a1 100644 if ((opcode->flags & S390_INSTR_FLAG_OPTPARM) && val.u == 0 diff --git a/opcodes/s390-opc.c b/opcodes/s390-opc.c -index ad22d61346c..47ba37b5dc6 100644 +index 10482fbc1e0..987004d7b07 100644 --- a/opcodes/s390-opc.c +++ b/opcodes/s390-opc.c @@ -208,17 +208,9 @@ const struct s390_operand s390_operands[] = diff --git a/s390-support-for-jump-visualization-in-disassembly.patch b/s390-support-for-jump-visualization-in-disassembly.patch deleted file mode 100644 index d954d7d..0000000 --- a/s390-support-for-jump-visualization-in-disassembly.patch +++ /dev/null @@ -1,367 +0,0 @@ -From b87360eed347bd19e89536f3006cf50fc8cdd212 Mon Sep 17 00:00:00 2001 -From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:46 +0100 -Subject: [PATCH 06/28] s390: Support for jump visualization in disassembly - -Add support for jump visualization for the s390 architecture in -disassembly: - -objdump -d --visualize-jumps ... - -Annotate the (conditional) jump and branch relative instructions with -information required for jump visualization: -- jump: Unconditional jump / branch relative. -- condjump: Conditional jump / branch relative. -- jumpsr: Jump / branch relative to subroutine. - -Unconditional jump and branch relative instructions are annotated as -jump. -Conditional jump and branch relative instructions, jump / branch -relative on count/index, and compare and jump / branch relative -instructions are annotated as condjump. -Jump and save (jas, jasl) and branch relative and save (bras, brasl) -instructions are annotated as jumpsr (jump to subroutine). - -Provide instruction information required for jump visualization during -disassembly. -The instruction type is provided after determining the opcode. -For non-code it is set to dis_noninsn. Otherwise it defaults to -dis_nonbranch. No annotation is done for data reference instructions -(i.e. instruction types dis_dref and dis_dref2). Note that the -instruction type needs to be provided before printing of the -instruction, as it is used in print_address_func() to translate the -argument value into an address if it is assumed to be a PC-relative -offset. Note that this is never the case on s390, as -print_address_func() is only called with addresses and never with -offsets. -The target of the (conditional) jump and branch relative instructions -is provided during print, when the PC relative operand is decoded. - -include/ - * opcode/s390.h: Define opcode flags to annotate instruction - class information for jump visualization: - S390_INSTR_FLAG_CLASS_BRANCH, S390_INSTR_FLAG_CLASS_RELATIVE, - S390_INSTR_FLAG_CLASS_CONDITIONAL, and - S390_INSTR_FLAG_CLASS_SUBROUTINE. - Define opcode flags mask S390_INSTR_FLAG_CLASS_MASK for above - instruction class information. - Define helpers for common instruction class flag combinations: - S390_INSTR_FLAGS_CLASS_JUMP, S390_INSTR_FLAGS_CLASS_CONDJUMP, - and S390_INSTR_FLAGS_CLASS_JUMPSR. - -opcodes/ - * s390-mkopc.c: Add opcode flags to annotate information - for jump visualization: jump, condjump, and jumpsr. - * s390-opc.txt: Annotate (conditional) jump and branch relative - instructions with information for jump visualization. - * s390-dis.c (print_insn_s390, s390_print_insn_with_opcode): - Provide instruction information for jump visualization. - -Signed-off-by: Jens Remus -Reviewed-by: Andreas Krebbel - -(cherry picked from commit c5306fed7d4) -(cherry pick dropped: binutils/NEWS) ---- - include/opcode/s390.h | 25 +++++++++++-- - opcodes/s390-dis.c | 36 ++++++++++++++++++- - opcodes/s390-mkopc.c | 12 +++++++ - opcodes/s390-opc.txt | 82 +++++++++++++++++++++---------------------- - 4 files changed, 110 insertions(+), 45 deletions(-) - -diff --git a/include/opcode/s390.h b/include/opcode/s390.h -index f787b901632..d540e1dfd00 100644 ---- a/include/opcode/s390.h -+++ b/include/opcode/s390.h -@@ -48,14 +48,35 @@ enum s390_opcode_cpu_val - S390_OPCODE_MAXCPU - }; - --/* Instruction specific flags. */ -+/* Values defined for the flags field of a struct s390_opcode. */ -+ -+/* Last one or two instruction operands are optional. */ - #define S390_INSTR_FLAG_OPTPARM 0x1 - #define S390_INSTR_FLAG_OPTPARM2 0x2 - -+/* Instruction requires a specific facility. */ - #define S390_INSTR_FLAG_HTM 0x4 - #define S390_INSTR_FLAG_VX 0x8 - #define S390_INSTR_FLAG_FACILITY_MASK 0xc - -+/* Instruction annotations for jump visualization. */ -+#define S390_INSTR_FLAG_CLASS_BRANCH 0x10 -+#define S390_INSTR_FLAG_CLASS_RELATIVE 0x20 -+#define S390_INSTR_FLAG_CLASS_CONDITIONAL 0x40 -+#define S390_INSTR_FLAG_CLASS_SUBROUTINE 0x80 -+#define S390_INSTR_FLAG_CLASS_MASK 0xf0 -+ -+#define S390_INSTR_FLAGS_CLASS_JUMP \ -+ (S390_INSTR_FLAG_CLASS_BRANCH | S390_INSTR_FLAG_CLASS_RELATIVE) -+ -+#define S390_INSTR_FLAGS_CLASS_CONDJUMP \ -+ (S390_INSTR_FLAG_CLASS_BRANCH | S390_INSTR_FLAG_CLASS_RELATIVE \ -+ | S390_INSTR_FLAG_CLASS_CONDITIONAL) -+ -+#define S390_INSTR_FLAGS_CLASS_JUMPSR \ -+ (S390_INSTR_FLAG_CLASS_BRANCH | S390_INSTR_FLAG_CLASS_RELATIVE \ -+ | S390_INSTR_FLAG_CLASS_SUBROUTINE) -+ - /* The opcode table is an array of struct s390_opcode. */ - - struct s390_opcode -@@ -101,8 +122,6 @@ extern const int s390_num_opcodes; - extern const struct s390_opcode s390_opformats[]; - extern const int s390_num_opformats; - --/* Values defined for the flags field of a struct s390_opcode. */ -- - /* The operands table is an array of struct s390_operand. */ - - struct s390_operand -diff --git a/opcodes/s390-dis.c b/opcodes/s390-dis.c -index 2a3b4c21c3a..8c8a98c4e24 100644 ---- a/opcodes/s390-dis.c -+++ b/opcodes/s390-dis.c -@@ -26,6 +26,7 @@ - #include "opintl.h" - #include "opcode/s390.h" - #include "libiberty.h" -+#include "dis-asm.h" - - static int opc_index[256]; - static int current_arch_mask = 0; -@@ -259,9 +260,14 @@ s390_print_insn_with_opcode (bfd_vma memaddr, - } - else if (flags & S390_OPERAND_PCREL) - { -+ bfd_vma target = memaddr + val.i + val.i; -+ -+ /* Provide info for jump visualization. May be evaluated by p_a_f(). */ -+ info->target = target; -+ - info->fprintf_styled_func (info->stream, dis_style_text, - "%c", separator); -- info->print_address_func (memaddr + val.i + val.i, info); -+ info->print_address_func (target, info); - } - else if (flags & S390_OPERAND_SIGNED) - { -@@ -332,6 +338,14 @@ print_insn_s390 (bfd_vma memaddr, struct disassemble_info *info) - /* The output looks better if we put 6 bytes on a line. */ - info->bytes_per_line = 6; - -+ /* Set some defaults for the insn info. */ -+ info->insn_info_valid = 0; -+ info->branch_delay_insns = 0; -+ info->data_size = 0; -+ info->insn_type = dis_nonbranch; -+ info->target = 0; -+ info->target2 = 0; -+ - /* Every S390 instruction is max 6 bytes long. */ - memset (buffer, 0, 6); - status = info->read_memory_func (memaddr, buffer, 6, info); -@@ -373,6 +387,23 @@ print_insn_s390 (bfd_vma memaddr, struct disassemble_info *info) - - if (opcode != NULL) - { -+ /* Provide info for jump visualization. Must be done before print. */ -+ switch (opcode->flags & S390_INSTR_FLAG_CLASS_MASK) -+ { -+ case S390_INSTR_FLAGS_CLASS_JUMP: -+ info->insn_type = dis_branch; -+ break; -+ case S390_INSTR_FLAGS_CLASS_CONDJUMP: -+ info->insn_type = dis_condbranch; -+ break; -+ case S390_INSTR_FLAGS_CLASS_JUMPSR: -+ info->insn_type = dis_jsr; -+ break; -+ default: -+ info->insn_type = dis_nonbranch; -+ } -+ info->insn_info_valid = 1; -+ - /* The instruction is valid. Print it and return its size. */ - s390_print_insn_with_opcode (memaddr, info, buffer, opcode); - return opsize; -@@ -394,6 +425,9 @@ print_insn_s390 (bfd_vma memaddr, struct disassemble_info *info) - if (bytes_to_dump == 0) - return 0; - -+ info->insn_type = dis_noninsn; -+ info->insn_info_valid = 1; -+ - /* Fall back to hex print. */ - switch (bytes_to_dump) - { -diff --git a/opcodes/s390-mkopc.c b/opcodes/s390-mkopc.c -index 48b1c1e0cdb..5f921ee0628 100644 ---- a/opcodes/s390-mkopc.c -+++ b/opcodes/s390-mkopc.c -@@ -431,6 +431,18 @@ main (void) - && (str[2] == 0 || str[2] == ',')) { - flag_bits |= S390_INSTR_FLAG_VX; - str += 2; -+ } else if (strncmp (str, "jump", 7) == 0 -+ && (str[4] == 0 || str[4] == ',')) { -+ flag_bits |= S390_INSTR_FLAGS_CLASS_JUMP; -+ str += 4; -+ } else if (strncmp (str, "condjump", 7) == 0 -+ && (str[8] == 0 || str[8] == ',')) { -+ flag_bits |= S390_INSTR_FLAGS_CLASS_CONDJUMP; -+ str += 8; -+ } else if (strncmp (str, "jumpsr", 7) == 0 -+ && (str[6] == 0 || str[6] == ',')) { -+ flag_bits |= S390_INSTR_FLAGS_CLASS_JUMPSR; -+ str += 6; - } else { - fprintf (stderr, "Couldn't parse flags string %s\n", - flags_string); -diff --git a/opcodes/s390-opc.txt b/opcodes/s390-opc.txt -index 59c43060ab4..78b9678cc7f 100644 ---- a/opcodes/s390-opc.txt -+++ b/opcodes/s390-opc.txt -@@ -245,15 +245,15 @@ d7 xc SS_L0RDRD "exclusive OR" g5 esa,zarch - 17 xr RR_RR "exclusive OR" g5 esa,zarch - f8 zap SS_LLRDRD "zero and add" g5 esa,zarch - a70a ahi RI_RI "add halfword immediate" g5 esa,zarch --84 brxh RSI_RRP "branch relative on index high" g5 esa,zarch --84 jxh RSI_RRP "branch relative on index high" g5 esa,zarch --85 brxle RSI_RRP "branch relative on index low or equal" g5 esa,zarch --85 jxle RSI_RRP "branch relative on index low or equal" g5 esa,zarch --a705 bras RI_RP "branch relative and save" g5 esa,zarch --a705 jas RI_RP "branch relative and save" g5 esa,zarch --a704 brc RI_UP "branch relative on condition" g5 esa,zarch --a706 brct RI_RP "branch relative on count" g5 esa,zarch --a706 jct RI_RP "branch relative on count" g5 esa,zarch -+84 brxh RSI_RRP "branch relative on index high" g5 esa,zarch condjump -+84 jxh RSI_RRP "branch relative on index high" g5 esa,zarch condjump -+85 brxle RSI_RRP "branch relative on index low or equal" g5 esa,zarch condjump -+85 jxle RSI_RRP "branch relative on index low or equal" g5 esa,zarch condjump -+a705 bras RI_RP "branch relative and save" g5 esa,zarch jumpsr -+a705 jas RI_RP "branch relative and save" g5 esa,zarch jumpsr -+a704 brc RI_UP "branch relative on condition" g5 esa,zarch condjump -+a706 brct RI_RP "branch relative on count" g5 esa,zarch condjump -+a706 jct RI_RP "branch relative on count" g5 esa,zarch condjump - b241 cksm RRE_RR "checksum" g5 esa,zarch - a70e chi RI_RI "compare halfword immediate" g5 esa,zarch - a9 clcle RS_RRRD "compare logical long extended" g5 esa,zarch -@@ -272,12 +272,12 @@ a701 tml RI_RU "test under mask low" g5 esa,zarch - 4700 nop RX_0RRD "no operation" g5 esa,zarch optparm - 4700 b*8 RX_0RRD "conditional branch" g5 esa,zarch - 47f0 b RX_0RRD "unconditional branch" g5 esa,zarch --a704 jc RI_UP "conditional jump" g5 esa,zarch -+a704 jc RI_UP "conditional jump" g5 esa,zarch condjump - a704 jnop RI_0P "nop jump" g5 esa,zarch --a704 j*8 RI_0P "conditional jump" g5 esa,zarch --a704 br*8 RI_0P "conditional jump" g5 esa,zarch --a7f4 j RI_0P "unconditional jump" g5 esa,zarch --a7f4 bru RI_0P "unconditional jump" g5 esa,zarch -+a704 j*8 RI_0P "conditional jump" g5 esa,zarch condjump -+a704 br*8 RI_0P "conditional jump" g5 esa,zarch condjump -+a7f4 j RI_0P "unconditional jump" g5 esa,zarch jump -+a7f4 bru RI_0P "unconditional jump" g5 esa,zarch jump - b34a axbr RRE_FEFE "add extended bfp" g5 esa,zarch - b31a adbr RRE_FF "add long bfp" g5 esa,zarch - ed000000001a adb RXE_FRRD "add long bfp" g5 esa,zarch -@@ -446,10 +446,10 @@ e3000000000b slg RXE_RRRD "subtract logical 64" z900 zarch - e3000000001b slgf RXE_RRRD "subtract logical 64<32" z900 zarch - e3000000000c msg RXE_RRRD "multiply single 64" z900 zarch - e3000000001c msgf RXE_RRRD "multiply single 64<32" z900 zarch --ec0000000044 brxhg RIE_RRP "branch relative on index high 64" z900 zarch --ec0000000044 jxhg RIE_RRP "branch relative on index high 64" z900 zarch --ec0000000045 brxlg RIE_RRP "branch relative on index low or equal 64" z900 zarch --ec0000000045 jxleg RIE_RRP "branch relative on index low or equal 64" z900 zarch -+ec0000000044 brxhg RIE_RRP "branch relative on index high 64" z900 zarch condjump -+ec0000000044 jxhg RIE_RRP "branch relative on index high 64" z900 zarch condjump -+ec0000000045 brxlg RIE_RRP "branch relative on index low or equal 64" z900 zarch condjump -+ec0000000045 jxleg RIE_RRP "branch relative on index low or equal 64" z900 zarch condjump - eb0000000044 bxhg RSE_RRRD "branch on index high 64" z900 zarch - eb0000000045 bxleg RSE_RRRD "branch on index low or equal 64" z900 zarch - eb000000000c srlg RSE_RRRD "shift right single logical 64" z900 zarch -@@ -473,18 +473,18 @@ eb000000002c stcmh RSE_RURD "store characters under mask high" z900 zarch - eb0000000080 icmh RSE_RURD "insert characters under mask high" z900 zarch - a702 tmhh RI_RU "test under mask high high" z900 zarch - a703 tmhl RI_RU "test under mask high low" z900 zarch --c004 brcl RIL_UP "branch relative on condition long" z900 esa,zarch -+c004 brcl RIL_UP "branch relative on condition long" z900 esa,zarch condjump - # jlc omitted due to missing jl* (see jl*8) and not added as non-standard jgc - c004 jgnop RIL_0P "nop jump long" z900 esa,zarch --c004 jg*8 RIL_0P "conditional jump long" z900 esa,zarch -+c004 jg*8 RIL_0P "conditional jump long" z900 esa,zarch condjump - # jl*8 omitted due to clash with non-standard j*8 flavors jle and jlh; exists as non-standard jg*8 instead --c004 br*8l RIL_0P "conditional jump long" z900 esa,zarch --c0f4 jg RIL_0P "unconditional jump long" z900 esa,zarch --c0f4 brul RIL_0P "unconditional jump long" z900 esa,zarch --c005 brasl RIL_RP "branch relative and save long" z900 esa,zarch --c005 jasl RIL_RP "branch relative and save long" z900 esa,zarch --a707 brctg RI_RP "branch relative on count 64" z900 zarch --a707 jctg RI_RP "branch relative on count 64" z900 zarch -+c004 br*8l RIL_0P "conditional jump long" z900 esa,zarch condjump -+c0f4 jg RIL_0P "unconditional jump long" z900 esa,zarch jump -+c0f4 brul RIL_0P "unconditional jump long" z900 esa,zarch jump -+c005 brasl RIL_RP "branch relative and save long" z900 esa,zarch jumpsr -+c005 jasl RIL_RP "branch relative and save long" z900 esa,zarch jumpsr -+a707 brctg RI_RP "branch relative on count 64" z900 zarch condjump -+a707 jctg RI_RP "branch relative on count 64" z900 zarch condjump - a709 lghi RI_RI "load halfword immediate 64" z900 zarch - a70b aghi RI_RI "add halfword immediate 64" z900 zarch - a70d mghi RI_RI "multiply halfword immediate 64" z900 zarch -@@ -896,18 +896,18 @@ ec00000000f6 crb$32 RRS_RRRD0 "compare and branch (32)" z10 zarch - ec00000000f6 crb RRS_RRRDU "compare and branch (32)" z10 zarch - ec00000000e4 cgrb$32 RRS_RRRD0 "compare and branch (64)" z10 zarch - ec00000000e4 cgrb RRS_RRRDU "compare and branch (64)" z10 zarch --ec0000000076 crj$32 RIE_RRP0 "compare and branch relative (32)" z10 zarch --ec0000000076 crj RIE_RRPU "compare and branch relative (32)" z10 zarch --ec0000000064 cgrj$32 RIE_RRP0 "compare and branch relative (64)" z10 zarch --ec0000000064 cgrj RIE_RRPU "compare and branch relative (64)" z10 zarch -+ec0000000076 crj$32 RIE_RRP0 "compare and branch relative (32)" z10 zarch condjump -+ec0000000076 crj RIE_RRPU "compare and branch relative (32)" z10 zarch condjump -+ec0000000064 cgrj$32 RIE_RRP0 "compare and branch relative (64)" z10 zarch condjump -+ec0000000064 cgrj RIE_RRPU "compare and branch relative (64)" z10 zarch condjump - ec00000000fe cib$12 RIS_R0RDI "compare immediate and branch (32<8)" z10 zarch - ec00000000fe cib RIS_RURDI "compare immediate and branch (32<8)" z10 zarch - ec00000000fc cgib$12 RIS_R0RDI "compare immediate and branch (64<8)" z10 zarch - ec00000000fc cgib RIS_RURDI "compare immediate and branch (64<8)" z10 zarch --ec000000007e cij$12 RIE_R0PI "compare immediate and branch relative (32<8)" z10 zarch --ec000000007e cij RIE_RUPI "compare immediate and branch relative (32<8)" z10 zarch --ec000000007c cgij$12 RIE_R0PI "compare immediate and branch relative (64<8)" z10 zarch --ec000000007c cgij RIE_RUPI "compare immediate and branch relative (64<8)" z10 zarch -+ec000000007e cij$12 RIE_R0PI "compare immediate and branch relative (32<8)" z10 zarch condjump -+ec000000007e cij RIE_RUPI "compare immediate and branch relative (32<8)" z10 zarch condjump -+ec000000007c cgij$12 RIE_R0PI "compare immediate and branch relative (64<8)" z10 zarch condjump -+ec000000007c cgij RIE_RUPI "compare immediate and branch relative (64<8)" z10 zarch condjump - b9720000 crt$16 RRF_00RR "compare and trap" z10 zarch - b972 crt RRF_U0RR "compare and trap" z10 zarch - b9600000 cgrt$16 RRF_00RR "compare and trap 64" z10 zarch -@@ -934,10 +934,10 @@ ec00000000f7 clrb$32 RRS_RRRD0 "compare logical and branch (32)" z10 zarch - ec00000000f7 clrb RRS_RRRDU "compare logical and branch (32)" z10 zarch - ec00000000e5 clgrb$32 RRS_RRRD0 "compare logical and branch (64)" z10 zarch - ec00000000e5 clgrb RRS_RRRDU "compare logical and branch (64)" z10 zarch --ec0000000077 clrj$32 RIE_RRP0 "compare logical and branch relative (32)" z10 zarch --ec0000000077 clrj RIE_RRPU "compare logical and branch relative (32)" z10 zarch --ec0000000065 clgrj$32 RIE_RRP0 "compare logical and branch relative (64)" z10 zarch --ec0000000065 clgrj RIE_RRPU "compare logical and branch relative (64)" z10 zarch -+ec0000000077 clrj$32 RIE_RRP0 "compare logical and branch relative (32)" z10 zarch condjump -+ec0000000077 clrj RIE_RRPU "compare logical and branch relative (32)" z10 zarch condjump -+ec0000000065 clgrj$32 RIE_RRP0 "compare logical and branch relative (64)" z10 zarch condjump -+ec0000000065 clgrj RIE_RRPU "compare logical and branch relative (64)" z10 zarch condjump - ec00000000ff clib$12 RIS_R0RDU "compare logical immediate and branch (32<8)" z10 zarch - ec00000000ff clib RIS_RURDU "compare logical immediate and branch (32<8)" z10 zarch - ec00000000fd clgib$12 RIS_R0RDU "compare logical immediate and branch (64<8)" z10 zarch -@@ -1011,8 +1011,8 @@ b9ca alhhhr RRF_R0RR2 "add logical high high" z196 zarch - b9da alhhlr RRF_R0RR2 "add logical high low" z196 zarch - cc0a alsih RIL_RI "add logical with signed immediate high with cc" z196 zarch - cc0b alsihn RIL_RI "add logical with signed immediate high no cc" z196 zarch --cc06 brcth RIL_RP "branch relative on count high" z196 zarch --cc06 jcth RIL_RP "jump on count high" z196 zarch -+cc06 brcth RIL_RP "branch relative on count high" z196 zarch condjump -+cc06 jcth RIL_RP "jump on count high" z196 zarch condjump - b9cd chhr RRE_RR "compare high high" z196 zarch - b9dd chlr RRE_RR "compare high low" z196 zarch - e300000000cd chf RXY_RRRD "compare high" z196 zarch --- -2.43.0 - diff --git a/s390-treat-addressing-operand-sequence-as-one-in-dis.patch b/s390-treat-addressing-operand-sequence-as-one-in-dis.patch index 1da8678..34d69c6 100644 --- a/s390-treat-addressing-operand-sequence-as-one-in-dis.patch +++ b/s390-treat-addressing-operand-sequence-as-one-in-dis.patch @@ -1,7 +1,7 @@ -From f1c477fe0e9591f8731b434db6b631d143827eac Mon Sep 17 00:00:00 2001 +From 921996dc9f1d1322fcad32822125546a7c6a6e93 Mon Sep 17 00:00:00 2001 From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:53 +0100 -Subject: [PATCH 27/28] s390: Treat addressing operand sequence as one in +Date: Fri, 7 Mar 2025 13:06:53 +0100 +Subject: [PATCH 09/10] s390: Treat addressing operand sequence as one in disassembler Reuse logic introduced with the preceding commit in the assembler to @@ -32,7 +32,7 @@ Signed-off-by: Jens Remus 1 file changed, 66 insertions(+), 18 deletions(-) diff --git a/opcodes/s390-dis.c b/opcodes/s390-dis.c -index 4724610e778..78b597e68cd 100644 +index 1a23afc8f40..8e7b9838f81 100644 --- a/opcodes/s390-dis.c +++ b/opcodes/s390-dis.c @@ -180,6 +180,69 @@ s390_extract_operand (const bfd_byte *insn, diff --git a/s390-use-proper-string-lengths-when-parsing-opcode-t.patch b/s390-use-proper-string-lengths-when-parsing-opcode-t.patch deleted file mode 100644 index a88bb97..0000000 --- a/s390-use-proper-string-lengths-when-parsing-opcode-t.patch +++ /dev/null @@ -1,45 +0,0 @@ -From deb7e96f0052ee85c18e29c01f6382c41e999707 Mon Sep 17 00:00:00 2001 -From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:49 +0100 -Subject: [PATCH 14/28] s390: Use proper string lengths when parsing opcode - table flags - -opcodes/ - * s390-mkopc.c: Use proper string lengths when parsing opcode - table flags. - -Fixes: c5306fed7d4 ("s390: Support for jump visualization in disassembly") -Signed-off-by: Jens Remus -Reviewed-by: Andreas Krebbel - -(cherry picked from commit 996097d5ca9) ---- - opcodes/s390-mkopc.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/opcodes/s390-mkopc.c b/opcodes/s390-mkopc.c -index c6d28b82e8a..4bab358378d 100644 ---- a/opcodes/s390-mkopc.c -+++ b/opcodes/s390-mkopc.c -@@ -491,15 +491,15 @@ main (void) - && (str[2] == 0 || str[2] == ',')) { - flag_bits |= S390_INSTR_FLAG_VX; - str += 2; -- } else if (strncmp (str, "jump", 7) == 0 -+ } else if (strncmp (str, "jump", 4) == 0 - && (str[4] == 0 || str[4] == ',')) { - flag_bits |= S390_INSTR_FLAGS_CLASS_JUMP; - str += 4; -- } else if (strncmp (str, "condjump", 7) == 0 -+ } else if (strncmp (str, "condjump", 8) == 0 - && (str[8] == 0 || str[8] == ',')) { - flag_bits |= S390_INSTR_FLAGS_CLASS_CONDJUMP; - str += 8; -- } else if (strncmp (str, "jumpsr", 7) == 0 -+ } else if (strncmp (str, "jumpsr", 6) == 0 - && (str[6] == 0 || str[6] == ',')) { - flag_bits |= S390_INSTR_FLAGS_CLASS_JUMPSR; - str += 6; --- -2.43.0 - diff --git a/s390-use-safe-string-functions-and-length-macros-in-.patch b/s390-use-safe-string-functions-and-length-macros-in-.patch deleted file mode 100644 index 2175ba1..0000000 --- a/s390-use-safe-string-functions-and-length-macros-in-.patch +++ /dev/null @@ -1,161 +0,0 @@ -From add9c74ad324359a1dcc742d53a24305e22ccba2 Mon Sep 17 00:00:00 2001 -From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:47 +0100 -Subject: [PATCH 09/28] s390: Use safe string functions and length macros in - s390-mkopc - -Use strncpy() and snprintf() instead of strcpy() and strcat(). Define -and use macros for string lengths, such as mnemonic, instruction -format, and instruction description. - -This is a mechanical change, although some buffers have increased in -length by one character. This has been confirmed by verifying that the -generated opcode/s390-opc.tab is unchanged. - -opcodes/ - * s390-mkopc.c: Use strncpy() and strncat(). - -Suggested-by: Nick Clifton -Signed-off-by: Jens Remus -Reviewed-by: Andreas Krebbel - -(cherry picked from commit a3fa108623c) ---- - opcodes/s390-mkopc.c | 77 ++++++++++++++++++++++++++++++-------------- - 1 file changed, 52 insertions(+), 25 deletions(-) - -diff --git a/opcodes/s390-mkopc.c b/opcodes/s390-mkopc.c -index aad093f18ff..eae0397d497 100644 ---- a/opcodes/s390-mkopc.c -+++ b/opcodes/s390-mkopc.c -@@ -25,6 +25,19 @@ - #include - #include "opcode/s390.h" - -+#define STRINGIFY(x) _STRINGIFY(x) -+#define _STRINGIFY(x) #x -+ -+/* Length of strings without terminating '\0' character. */ -+#define MAX_OPCODE_LEN 15 -+#define MAX_MNEMONIC_LEN 15 -+#define MAX_FORMAT_LEN 15 -+#define MAX_DESCRIPTION_LEN 79 -+ -+#define MAX_CPU_LEN 15 -+#define MAX_MODES_LEN 15 -+#define MAX_FLAGS_LEN 79 -+ - /* Return code. */ - int return_code = EXIT_SUCCESS; - -@@ -44,9 +57,9 @@ print_error (const char *fmt, ...) - - struct op_struct - { -- char opcode[16]; -- char mnemonic[16]; -- char format[16]; -+ char opcode[MAX_OPCODE_LEN + 1]; -+ char mnemonic[MAX_MNEMONIC_LEN + 1]; -+ char format[MAX_FORMAT_LEN + 1]; - int mode_bits; - int min_cpu; - int flags; -@@ -108,9 +121,12 @@ insertOpcode (char *opcode, char *mnemonic, char *format, - break; - for (k = no_ops; k > ix; k--) - op_array[k] = op_array[k-1]; -- strcpy(op_array[ix].opcode, opcode); -- strcpy(op_array[ix].mnemonic, mnemonic); -- strcpy(op_array[ix].format, format); -+ strncpy (op_array[ix].opcode, opcode, MAX_OPCODE_LEN); -+ op_array[ix].opcode[MAX_OPCODE_LEN] = '\0'; -+ strncpy (op_array[ix].mnemonic, mnemonic, MAX_MNEMONIC_LEN); -+ op_array[ix].mnemonic[MAX_MNEMONIC_LEN] = '\0'; -+ strncpy (op_array[ix].format, format, MAX_FORMAT_LEN); -+ op_array[ix].format[MAX_FORMAT_LEN] = '\0'; - op_array[ix].sort_value = sort_value; - op_array[ix].no_nibbles = no_nibbles; - op_array[ix].min_cpu = min_cpu; -@@ -180,9 +196,9 @@ insertExpandedMnemonic (char *opcode, char *mnemonic, char *format, - int min_cpu, int mode_bits, int flags) - { - char *tag; -- char prefix[15]; -- char suffix[15]; -- char number[15]; -+ char prefix[MAX_MNEMONIC_LEN + 1]; -+ char suffix[MAX_MNEMONIC_LEN + 1]; -+ char number[MAX_MNEMONIC_LEN + 1]; - int mask_start, i = 0, tag_found = 0, reading_number = 0; - int number_p = 0, suffix_p = 0, prefix_p = 0; - const struct s390_cond_ext_format *ext_table; -@@ -263,12 +279,17 @@ insertExpandedMnemonic (char *opcode, char *mnemonic, char *format, - - for (i = 0; i < ext_table_length; i++) - { -- char new_mnemonic[15]; -+ char new_mnemonic[MAX_MNEMONIC_LEN + 1]; - -- strcpy (new_mnemonic, prefix); - opcode[mask_start] = ext_table[i].nibble; -- strcat (new_mnemonic, ext_table[i].extension); -- strcat (new_mnemonic, suffix); -+ -+ if (snprintf (new_mnemonic, sizeof (new_mnemonic), "%s%s%s", prefix, -+ ext_table[i].extension, suffix) >= sizeof (new_mnemonic)) -+ { -+ print_error ("Mnemonic: \"%s\": Concatenated mnemonic exceeds max. length\n", mnemonic); -+ return; -+ } -+ - insertOpcode (opcode, new_mnemonic, format, min_cpu, mode_bits, flags); - } - return; -@@ -338,13 +359,13 @@ main (void) - make an entry into the opcode table. */ - while (fgets (currentLine, sizeof (currentLine), stdin) != NULL) - { -- char opcode[16]; -- char mnemonic[16]; -- char format[16]; -- char description[80]; -- char cpu_string[16]; -- char modes_string[16]; -- char flags_string[80]; -+ char opcode[MAX_OPCODE_LEN + 1]; -+ char mnemonic[MAX_MNEMONIC_LEN + 1]; -+ char format[MAX_FORMAT_LEN + 1]; -+ char description[MAX_DESCRIPTION_LEN + 1]; -+ char cpu_string[MAX_CPU_LEN + 1]; -+ char modes_string[MAX_MODES_LEN + 1]; -+ char flags_string[MAX_FLAGS_LEN + 1]; - int min_cpu; - int mode_bits; - int flag_bits; -@@ -353,11 +374,17 @@ main (void) - - if (currentLine[0] == '#' || currentLine[0] == '\n') - continue; -- memset (opcode, 0, 8); -- num_matched = -- sscanf (currentLine, "%15s %15s %15s \"%79[^\"]\" %15s %15s %79[^\n]", -- opcode, mnemonic, format, description, -- cpu_string, modes_string, flags_string); -+ memset (opcode, '\0', sizeof(opcode)); -+ num_matched = sscanf (currentLine, -+ "%" STRINGIFY (MAX_OPCODE_LEN) "s " -+ "%" STRINGIFY (MAX_MNEMONIC_LEN) "s " -+ "%" STRINGIFY (MAX_FORMAT_LEN) "s " -+ "\"%" STRINGIFY (MAX_DESCRIPTION_LEN) "[^\"]\" " -+ "%" STRINGIFY (MAX_CPU_LEN) "s " -+ "%" STRINGIFY (MAX_MODES_LEN) "s " -+ "%" STRINGIFY (MAX_FLAGS_LEN) "[^\n]", -+ opcode, mnemonic, format, description, -+ cpu_string, modes_string, flags_string); - if (num_matched != 6 && num_matched != 7) - { - print_error ("Couldn't scan line %s\n", currentLine); --- -2.43.0 - diff --git a/s390-warn-when-register-name-type-does-not-match-ope.patch b/s390-warn-when-register-name-type-does-not-match-ope.patch deleted file mode 100644 index 1d1e795..0000000 --- a/s390-warn-when-register-name-type-does-not-match-ope.patch +++ /dev/null @@ -1,195 +0,0 @@ -From acd6d26a783f5eef5ba74e5c5b1dacd5303c6a05 Mon Sep 17 00:00:00 2001 -From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:50 +0100 -Subject: [PATCH 16/28] s390: Warn when register name type does not match - operand - -Print a warning message when the register type of a specified register -name does not match with the operand's register type: - -operand {#}: expected {access|control|floating-point|general|vector} - register name [as {base|index} register] - -Introduce a s390-specific assembler option "warn-regtype-mismatch" -with the values "strict", "relaxed", and "no" as well as an option -"no-warn-regtype-mismatch" which control whether the assembler -performs register name type checks and generates above warning messages. - -warn-regtype-mismatch=strict: - Perform strict register name type checks. - -warn-regtype-mismatch=relaxed: - Perform relaxed register name type checks, which allow floating-point - register (FPR) names %f0 to %f15 to be specified as argument to vector - register (VR) operands and vector register (VR) names %v0 to %v15 to - be specified as argument to floating-point register (FPR) operands. - This is acceptable as the FPRs are embedded into the lower halves of - the VRs. Make "relaxed" the default, as GCC generates assembler code - using FPR and VR interchangeably, which would cause assembler warnings - to be generated with "strict". - -warn-regtype-mismatch=no: -no-warn-regtype-mismatch: - Disable any register name type checks. - -Tag .insn pseudo mnemonics as such, to skip register name type checks -on those. They need to be skipped, as there do not exist .insn pseudo -mnemonics for every possible operand register type combination. Keep -track of the currently parsed operand number to provide it as reference -in warning messages. - -To verify that the introduction of this change does not unnecessarily -affect the compilation of existing code the GNU Binutils, GNU C Library, -and Linux Kernel have been build with the new assembler, verifying that -the assembler did not generate any of the new warning messages. - -gas/ - * config/tc-s390.c: Handle new assembler options - "[no]warn-regtype-mismatch[=strict|relaxed|no". Annotate - parsed register expressions with register type. Keep track of - operand number being parsed. Print warning message in case of - register type mismatch between instruction operand and parsed - register expression. - * doc/as.texi: Document new s390-specific assembler options - "[no-]warn-regtype-mismatch[=strict|relaxed|no]". - * NEWS: Mention new s390-specific register name type checks and - related assembler option "warn-regtype-mismatch=strict| - relaxed|no". - * testsuite/gas/s390/s390.exp: Add test cases for new assembler - option "warn-regtype-mismatch={strict|relaxed}". - * testsuite/gas/s390/esa-g5.s: Fix register types in tests for - didbr, diebr, tbdr, and tbedr. - * testsuite/gas/s390/zarch-z13.s: Fix register types in tests - for vgef, vgeg, vscef, and vsceg. - * testsuite/gas/s390/zarch-warn-regtype-mismatch-strict.s: - Tests for assembler option "warn-regtype-mismatch=strict". - * testsuite/gas/s390/zarch-warn-regtype-mismatch-strict.l: - Likewise. - * gas/testsuite/gas/s390/zarch-warn-regtype-mismatch-relaxed.s: - Tests for assembler option "warn-regtype-mismatch=relaxed". - * gas/testsuite/gas/s390/zarch-warn-regtype-mismatch-relaxed.l: - Likewise. - * gas/testsuite/gas/s390/zarch-omitted-base-index-err.s: Update - test cases for assembler option "warn-regtype-mismatch" - defaulting to "relaxed". - * testsuite/gas/s390/zarch-omitted-base-index-err.l: Likewise. - -include/ - * opcode/s390.h (S390_INSTR_FLAG_PSEUDO_MNEMONIC): Add - instruction flag to tag .insn pseudo-mnemonics. - -opcodes/ - * s390-opc.c (s390_opformats): Tag .insn pseudo-mnemonics as - such. - -Reviewed-by: Andreas Krebbel -Signed-off-by: Jens Remus - -(cherry picked from commit dfa4ac9728c) -(cherry pick dropped: gas/NEWS) -(cherry pick dropped: gas/config/tc-s390.c) -(cherry pick dropped: gas/doc/as.texi) -(cherry pick dropped: gas/testsuite/gas/s390/esa-g5.s) -(cherry pick dropped: gas/testsuite/gas/s390/s390.exp) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-omitted-base-index-err.l) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-omitted-base-index-err.s) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-warn-regtype-mismatch-relaxed.l) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-warn-regtype-mismatch-relaxed.s) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-warn-regtype-mismatch-strict.l) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-warn-regtype-mismatch-strict.s) -(cherry pick dropped: gas/testsuite/gas/s390/zarch-z13.s) ---- - include/opcode/s390.h | 3 +++ - opcodes/s390-opc.c | 62 +++++++++++++++++++++---------------------- - 2 files changed, 34 insertions(+), 31 deletions(-) - -diff --git a/include/opcode/s390.h b/include/opcode/s390.h -index 319bfe2d629..772552b5397 100644 ---- a/include/opcode/s390.h -+++ b/include/opcode/s390.h -@@ -77,6 +77,9 @@ enum s390_opcode_cpu_val - (S390_INSTR_FLAG_CLASS_BRANCH | S390_INSTR_FLAG_CLASS_RELATIVE \ - | S390_INSTR_FLAG_CLASS_SUBROUTINE) - -+/* Instruction is an .insn pseudo-mnemonic. */ -+#define S390_INSTR_FLAG_PSEUDO_MNEMONIC 0x100 -+ - /* The opcode table is an array of struct s390_opcode. */ - - struct s390_opcode -diff --git a/opcodes/s390-opc.c b/opcodes/s390-opc.c -index e44621a7479..ad22d61346c 100644 ---- a/opcodes/s390-opc.c -+++ b/opcodes/s390-opc.c -@@ -774,37 +774,37 @@ unused_s390_operands_static_asserts (void) - - const struct s390_opcode s390_opformats[] = - { -- { "e", OP8(0x00LL), MASK_E, INSTR_E, 3, 0, 0, NULL }, -- { "ri", OP8(0x00LL), MASK_RI_RI, INSTR_RI_RI, 3, 0, 0, NULL }, -- { "rie", OP8(0x00LL), MASK_RIE_RRP, INSTR_RIE_RRP, 3, 0, 0, NULL }, -- { "ril", OP8(0x00LL), MASK_RIL_RP, INSTR_RIL_RP, 3, 0, 0, NULL }, -- { "rilu", OP8(0x00LL), MASK_RIL_RU, INSTR_RIL_RU, 3, 0, 0, NULL }, -- { "ris", OP8(0x00LL), MASK_RIS_RURDI, INSTR_RIS_RURDI, 3, 6, 0, NULL }, -- { "rr", OP8(0x00LL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 0, NULL }, -- { "rre", OP8(0x00LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 0, NULL }, -- { "rrf", OP8(0x00LL), MASK_RRF_RURR, INSTR_RRF_RURR, 3, 0, 0, NULL }, -- { "rrs", OP8(0x00LL), MASK_RRS_RRRDU, INSTR_RRS_RRRDU, 3, 6, 0, NULL }, -- { "rs", OP8(0x00LL), MASK_RS_RRRD, INSTR_RS_RRRD, 3, 0, 0, NULL }, -- { "rse", OP8(0x00LL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 3, 0, 0, NULL }, -- { "rsi", OP8(0x00LL), MASK_RSI_RRP, INSTR_RSI_RRP, 3, 0, 0, NULL }, -- { "rsy", OP8(0x00LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 3, 3, 0, NULL }, -- { "rx", OP8(0x00LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 0, NULL }, -- { "rxe", OP8(0x00LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 3, 0, 0, NULL }, -- { "rxf", OP8(0x00LL), MASK_RXF_RRRDR, INSTR_RXF_RRRDR, 3, 0, 0, NULL }, -- { "rxy", OP8(0x00LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 3, 3, 0, NULL }, -- { "s", OP8(0x00LL), MASK_S_RD, INSTR_S_RD, 3, 0, 0, NULL }, -- { "si", OP8(0x00LL), MASK_SI_URD, INSTR_SI_URD, 3, 0, 0, NULL }, -- { "siy", OP8(0x00LL), MASK_SIY_URD, INSTR_SIY_URD, 3, 3, 0, NULL }, -- { "sil", OP8(0x00LL), MASK_SIL_RDI, INSTR_SIL_RDI, 3, 6, 0, NULL }, -- { "ss", OP8(0x00LL), MASK_SS_RRRDRD, INSTR_SS_RRRDRD, 3, 0, 0, NULL }, -- { "sse", OP8(0x00LL), MASK_SSE_RDRD, INSTR_SSE_RDRD, 3, 0, 0, NULL }, -- { "ssf", OP8(0x00LL), MASK_SSF_RRDRD, INSTR_SSF_RRDRD, 3, 0, 0, NULL }, -- { "vrv", OP8(0x00LL), MASK_VRV_VVXRDU, INSTR_VRV_VVXRDU, 3, 9, 0, NULL }, -- { "vri", OP8(0x00LL), MASK_VRI_VVUUU, INSTR_VRI_VVUUU, 3, 9, 0, NULL }, -- { "vrx", OP8(0x00LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 3, 9, 0, NULL }, -- { "vrs", OP8(0x00LL), MASK_VRS_RVRDU, INSTR_VRS_RVRDU, 3, 9, 0, NULL }, -- { "vrr", OP8(0x00LL), MASK_VRR_VVV0UUU, INSTR_VRR_VVV0UUU, 3, 9, 0, NULL }, -- { "vsi", OP8(0x00LL), MASK_VSI_URDV, INSTR_VSI_URDV, 3, 10, 0, NULL }, -+ { "e", OP8(0x00LL), MASK_E, INSTR_E, 3, 0, 256, NULL }, -+ { "ri", OP8(0x00LL), MASK_RI_RI, INSTR_RI_RI, 3, 0, 256, NULL }, -+ { "rie", OP8(0x00LL), MASK_RIE_RRP, INSTR_RIE_RRP, 3, 0, 256, NULL }, -+ { "ril", OP8(0x00LL), MASK_RIL_RP, INSTR_RIL_RP, 3, 0, 256, NULL }, -+ { "rilu", OP8(0x00LL), MASK_RIL_RU, INSTR_RIL_RU, 3, 0, 256, NULL }, -+ { "ris", OP8(0x00LL), MASK_RIS_RURDI, INSTR_RIS_RURDI, 3, 6, 256, NULL }, -+ { "rr", OP8(0x00LL), MASK_RR_RR, INSTR_RR_RR, 3, 0, 256, NULL }, -+ { "rre", OP8(0x00LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 0, 256, NULL }, -+ { "rrf", OP8(0x00LL), MASK_RRF_RURR, INSTR_RRF_RURR, 3, 0, 256, NULL }, -+ { "rrs", OP8(0x00LL), MASK_RRS_RRRDU, INSTR_RRS_RRRDU, 3, 6, 256, NULL }, -+ { "rs", OP8(0x00LL), MASK_RS_RRRD, INSTR_RS_RRRD, 3, 0, 256, NULL }, -+ { "rse", OP8(0x00LL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 3, 0, 256, NULL }, -+ { "rsi", OP8(0x00LL), MASK_RSI_RRP, INSTR_RSI_RRP, 3, 0, 256, NULL }, -+ { "rsy", OP8(0x00LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 3, 3, 256, NULL }, -+ { "rx", OP8(0x00LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3, 0, 256, NULL }, -+ { "rxe", OP8(0x00LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 3, 0, 256, NULL }, -+ { "rxf", OP8(0x00LL), MASK_RXF_RRRDR, INSTR_RXF_RRRDR, 3, 0, 256, NULL }, -+ { "rxy", OP8(0x00LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 3, 3, 256, NULL }, -+ { "s", OP8(0x00LL), MASK_S_RD, INSTR_S_RD, 3, 0, 256, NULL }, -+ { "si", OP8(0x00LL), MASK_SI_URD, INSTR_SI_URD, 3, 0, 256, NULL }, -+ { "siy", OP8(0x00LL), MASK_SIY_URD, INSTR_SIY_URD, 3, 3, 256, NULL }, -+ { "sil", OP8(0x00LL), MASK_SIL_RDI, INSTR_SIL_RDI, 3, 6, 256, NULL }, -+ { "ss", OP8(0x00LL), MASK_SS_RRRDRD, INSTR_SS_RRRDRD, 3, 0, 256, NULL }, -+ { "sse", OP8(0x00LL), MASK_SSE_RDRD, INSTR_SSE_RDRD, 3, 0, 256, NULL }, -+ { "ssf", OP8(0x00LL), MASK_SSF_RRDRD, INSTR_SSF_RRDRD, 3, 0, 256, NULL }, -+ { "vrv", OP8(0x00LL), MASK_VRV_VVXRDU, INSTR_VRV_VVXRDU, 3, 9, 256, NULL }, -+ { "vri", OP8(0x00LL), MASK_VRI_VVUUU, INSTR_VRI_VVUUU, 3, 9, 256, NULL }, -+ { "vrx", OP8(0x00LL), MASK_VRX_VRRDU, INSTR_VRX_VRRDU, 3, 9, 256, NULL }, -+ { "vrs", OP8(0x00LL), MASK_VRS_RVRDU, INSTR_VRS_RVRDU, 3, 9, 256, NULL }, -+ { "vrr", OP8(0x00LL), MASK_VRR_VVV0UUU, INSTR_VRR_VVV0UUU, 3, 9, 256, NULL }, -+ { "vsi", OP8(0x00LL), MASK_VSI_URDV, INSTR_VSI_URDV, 3, 10, 256, NULL }, - }; - - const int s390_num_opformats = --- -2.43.0 - diff --git a/s390-whitespace-fixes-in-conditional-branch-flavor-d.patch b/s390-whitespace-fixes-in-conditional-branch-flavor-d.patch deleted file mode 100644 index 23ca4ab..0000000 --- a/s390-whitespace-fixes-in-conditional-branch-flavor-d.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 4c33c834e1577b92ce256a22c9e5a9fa459e3960 Mon Sep 17 00:00:00 2001 -From: Jens Remus -Date: Thu, 13 Mar 2025 15:09:49 +0100 -Subject: [PATCH 13/28] s390: Whitespace fixes in conditional branch flavor - descriptions - -opcodes/ - * s390-mkopc.c: Whitespace fixes in conditional branch flavor - descriptions. - -Signed-off-by: Jens Remus -Reviewed-by: Andreas Krebbel - -(cherry picked from commit d9d4fc898d2) ---- - opcodes/s390-mkopc.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/opcodes/s390-mkopc.c b/opcodes/s390-mkopc.c -index 025dbdb037f..c6d28b82e8a 100644 ---- a/opcodes/s390-mkopc.c -+++ b/opcodes/s390-mkopc.c -@@ -150,8 +150,8 @@ struct s390_cond_ext_format - the '*' tag. */ - #define NUM_COND_EXTENSIONS 20 - const struct s390_cond_ext_format s390_cond_extensions[NUM_COND_EXTENSIONS] = --{ { '1', "o", "on overflow / if ones"}, /* jump on overflow / if ones */ -- { '2', "h", "on A high"}, /* jump on A high */ -+{ { '1', "o", "on overflow / if ones" }, /* jump on overflow / if ones */ -+ { '2', "h", "on A high" }, /* jump on A high */ - { '2', "p", "on plus" }, /* jump on plus */ - { '3', "nle", "on not low or equal" }, /* jump on not low or equal */ - { '4', "l", "on A low" }, /* jump on A low */ -@@ -162,7 +162,7 @@ const struct s390_cond_ext_format s390_cond_extensions[NUM_COND_EXTENSIONS] = - { '7', "nz", "on not zero / if not zeros" }, /* jump on not zero / if not zeros */ - { '8', "e", "on A equal B" }, /* jump on A equal B */ - { '8', "z", "on zero / if zeros" }, /* jump on zero / if zeros */ -- { '9', "nlh", "on not low or high " }, /* jump on not low or high */ -+ { '9', "nlh", "on not low or high" }, /* jump on not low or high */ - { 'a', "he", "on high or equal" }, /* jump on high or equal */ - { 'b', "nl", "on A not low" }, /* jump on A not low */ - { 'b', "nm", "on not minus / if not mixed" }, /* jump on not minus / if not mixed */ --- -2.43.0 - diff --git a/use-setvariable-in-gdb.dap-scopes.exp.patch b/use-setvariable-in-gdb.dap-scopes.exp.patch new file mode 100644 index 0000000..844fb39 --- /dev/null +++ b/use-setvariable-in-gdb.dap-scopes.exp.patch @@ -0,0 +1,64 @@ +From 44651f4eae0a9ecf4a734e996bf75c9cd67e5f63 Mon Sep 17 00:00:00 2001 +From: Tom de Vries +Date: Tue, 10 Dec 2024 20:30:05 +0100 +Subject: [PATCH 20/46] Use setVariable in gdb.dap/scopes.exp + +The test-case gdb.dap/scopes.exp contains the following outdated comment: +... + # setVariable isn't implemented yet, so use the register name. +... + +Now that setVariable is implemented, use it to set variable scalar, and remove +the bit that sets the first register. That part is known to fail on s390x, +because the first register isn't writeable [1]. + +Tested on x86_64-linux. + +Suggested-By: Tom Tromey +Approved-By: Tom Tromey + +[1] https://sourceware.org/pipermail/gdb-patches/2024-December/213823.html +--- + gdb/testsuite/gdb.dap/scopes.exp | 27 +++++++++------------------ + 1 file changed, 9 insertions(+), 18 deletions(-) + +diff --git a/gdb/testsuite/gdb.dap/scopes.exp b/gdb/testsuite/gdb.dap/scopes.exp +index aa3bb688c0e..c78ae6e1202 100644 +--- a/gdb/testsuite/gdb.dap/scopes.exp ++++ b/gdb/testsuite/gdb.dap/scopes.exp +@@ -133,23 +133,14 @@ set val [dap_check_request_and_response "fetch first register" \ + "variables" \ + [format {o variablesReference [i %d] count [i 1]} $num]] + +-# Try setting the value to something else. +-set val [dict get [lindex $val 0] body variables] +-set name [dict get [lindex $val 0] name] +-set val [dict get [lindex $val 0] value] +-# Just make sure it is different from the original value. +-set val [expr {$val ^ 7}] +- +-# setVariable isn't implemented yet, so use the register name. Note +-# that we sneak the "$" into the name, written in a slightly funny way +-# to work around apparent TON limitations. +-set response [dap_check_request_and_response "set first register" \ +- setExpression \ +- [format {o expression [s \$%s] value [s %d] frameId [i %d]} \ +- $name $val $frame_id]] +-set response [lindex $response 0] +- +-gdb_assert {[dict get $response body value] == $val} \ +- "setting register yields updated value" ++set num [dict get $scope variablesReference] ++set refs [lindex [dap_check_request_and_response "set variable scalar" \ ++ "setVariable" \ ++ [format {o variablesReference [i %d] name [s scalar] \ ++ value [s 32]} \ ++ $num]] \ ++ 0] ++gdb_assert { [dict get $refs body value] == 32 } \ ++ "setting variable yields updated value" + + dap_shutdown +-- +2.43.0 +