aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'gdb')
-rw-r--r--gdb/MAINTAINERS3
-rw-r--r--gdb/Makefile.in77
-rw-r--r--gdb/NEWS78
-rw-r--r--gdb/README11
-rw-r--r--gdb/aarch64-fbsd-nat.c4
-rw-r--r--gdb/aarch64-fbsd-tdep.c7
-rw-r--r--gdb/aarch64-linux-nat.c4
-rw-r--r--gdb/aarch64-linux-tdep.c9
-rw-r--r--gdb/aarch64-newlib-tdep.c4
-rw-r--r--gdb/aarch64-tdep.c4
-rw-r--r--gdb/ada-lang.c4
-rw-r--r--gdb/ada-tasks.c4
-rw-r--r--gdb/ada-typeprint.c2
-rw-r--r--gdb/addrmap.c61
-rw-r--r--gdb/agent.c4
-rw-r--r--gdb/aix-thread.c4
-rw-r--r--gdb/alpha-bsd-nat.c4
-rw-r--r--gdb/alpha-linux-nat.c4
-rw-r--r--gdb/alpha-linux-tdep.c9
-rw-r--r--gdb/alpha-netbsd-tdep.c7
-rw-r--r--gdb/alpha-obsd-tdep.c7
-rw-r--r--gdb/alpha-tdep.c4
-rw-r--r--gdb/amd-dbgapi-target.c155
-rw-r--r--gdb/amd-dbgapi-target.h5
-rw-r--r--gdb/amd64-darwin-tdep.c6
-rw-r--r--gdb/amd64-dicos-tdep.c4
-rw-r--r--gdb/amd64-fbsd-nat.c4
-rw-r--r--gdb/amd64-fbsd-tdep.c7
-rw-r--r--gdb/amd64-gnu-tdep.c7
-rw-r--r--gdb/amd64-linux-nat.c4
-rw-r--r--gdb/amd64-linux-tdep.c11
-rw-r--r--gdb/amd64-netbsd-nat.c4
-rw-r--r--gdb/amd64-netbsd-tdep.c7
-rw-r--r--gdb/amd64-obsd-nat.c4
-rw-r--r--gdb/amd64-obsd-tdep.c7
-rw-r--r--gdb/amd64-sol2-tdep.c7
-rw-r--r--gdb/amd64-tdep.c134
-rw-r--r--gdb/amd64-windows-nat.c4
-rw-r--r--gdb/amd64-windows-tdep.c4
-rw-r--r--gdb/amdgpu-tdep.c5
-rw-r--r--gdb/annotate.c4
-rw-r--r--gdb/arc-linux-nat.c4
-rw-r--r--gdb/arc-linux-tdep.c10
-rw-r--r--gdb/arc-newlib-tdep.c4
-rw-r--r--gdb/arc-tdep.c4
-rw-r--r--gdb/arch-utils.c4
-rw-r--r--gdb/arm-fbsd-nat.c4
-rw-r--r--gdb/arm-fbsd-tdep.c7
-rw-r--r--gdb/arm-linux-nat.c4
-rw-r--r--gdb/arm-linux-tdep.c8
-rw-r--r--gdb/arm-netbsd-nat.c4
-rw-r--r--gdb/arm-netbsd-tdep.c7
-rw-r--r--gdb/arm-none-tdep.c4
-rw-r--r--gdb/arm-obsd-tdep.c7
-rw-r--r--gdb/arm-pikeos-tdep.c4
-rw-r--r--gdb/arm-tdep.c6
-rw-r--r--gdb/arm-wince-tdep.c4
-rw-r--r--gdb/auto-load.c4
-rw-r--r--gdb/auxv.c4
-rw-r--r--gdb/avr-tdep.c4
-rw-r--r--gdb/ax-gdb.c4
-rw-r--r--gdb/bfin-linux-tdep.c4
-rw-r--r--gdb/bfin-tdep.c4
-rw-r--r--gdb/block.c4
-rw-r--r--gdb/bpf-tdep.c4
-rw-r--r--gdb/break-catch-exec.c4
-rw-r--r--gdb/break-catch-fork.c4
-rw-r--r--gdb/break-catch-load.c8
-rw-r--r--gdb/break-catch-sig.c4
-rw-r--r--gdb/break-catch-syscall.c6
-rw-r--r--gdb/break-catch-throw.c4
-rw-r--r--gdb/break-cond-parse.c17
-rw-r--r--gdb/breakpoint.c66
-rw-r--r--gdb/breakpoint.h4
-rw-r--r--gdb/bsd-uthread.c11
-rw-r--r--gdb/btrace.c4
-rw-r--r--gdb/build-id.c8
-rw-r--r--gdb/c-exp.y10
-rw-r--r--gdb/charset.c4
-rw-r--r--gdb/cli/cli-cmds.c49
-rw-r--r--gdb/cli/cli-dump.c4
-rw-r--r--gdb/cli/cli-interp.c4
-rw-r--r--gdb/cli/cli-logging.c4
-rw-r--r--gdb/cli/cli-script.c4
-rw-r--r--gdb/cli/cli-style.c4
-rw-r--r--gdb/coff-pe-read.c4
-rw-r--r--gdb/coffread.c4
-rw-r--r--gdb/compile/compile-c-support.c8
-rw-r--r--gdb/compile/compile-cplus-types.c4
-rw-r--r--gdb/compile/compile.c4
-rw-r--r--gdb/complaints.c4
-rw-r--r--gdb/completer.c4
-rw-r--r--gdb/config.in12
-rwxr-xr-xgdb/configure83
-rw-r--r--gdb/configure.ac48
-rw-r--r--gdb/configure.tgt62
-rw-r--r--gdb/contrib/ari/create-web-ari-in-src.sh2
-rwxr-xr-xgdb/contrib/ari/gdb_ari.sh4
-rw-r--r--gdb/contrib/ari/update-web-ari.sh6
-rw-r--r--gdb/contrib/codespell-dictionary.txt1
-rw-r--r--gdb/contrib/codespell-ignore-words.txt1
-rw-r--r--gdb/contrib/setup.cfg1
-rw-r--r--gdb/copying.c4
-rw-r--r--gdb/corefile.c4
-rw-r--r--gdb/corelow.c11
-rw-r--r--gdb/cp-abi.c4
-rw-r--r--gdb/cp-name-parser.y26
-rw-r--r--gdb/cp-namespace.c4
-rw-r--r--gdb/cp-support.c21
-rw-r--r--gdb/cp-support.h4
-rw-r--r--gdb/cp-valprint.c4
-rw-r--r--gdb/cris-linux-tdep.c9
-rw-r--r--gdb/cris-tdep.c4
-rw-r--r--gdb/csky-linux-tdep.c8
-rw-r--r--gdb/csky-tdep.c4
-rw-r--r--gdb/darwin-nat-info.c4
-rw-r--r--gdb/darwin-nat.c6
-rw-r--r--gdb/dbxread.c4
-rw-r--r--gdb/dcache.c4
-rw-r--r--gdb/debuginfod-support.c4
-rw-r--r--gdb/defs.h8
-rw-r--r--gdb/dicos-tdep.c2
-rw-r--r--gdb/disasm-selftests.c4
-rw-r--r--gdb/disasm.c4
-rw-r--r--gdb/displaced-stepping.c4
-rw-r--r--gdb/doc/gdb.texinfo249
-rw-r--r--gdb/doc/guile.texi16
-rw-r--r--gdb/doc/python.texi124
-rw-r--r--gdb/dtrace-probe.c4
-rw-r--r--gdb/dummy-frame.c4
-rw-r--r--gdb/dwarf2/attribute.c16
-rw-r--r--gdb/dwarf2/attribute.h19
-rw-r--r--gdb/dwarf2/call-site.h2
-rw-r--r--gdb/dwarf2/cooked-index-entry.c4
-rw-r--r--gdb/dwarf2/cooked-index-worker.c2
-rw-r--r--gdb/dwarf2/cooked-index-worker.h30
-rw-r--r--gdb/dwarf2/cooked-index.c7
-rw-r--r--gdb/dwarf2/cu.h13
-rw-r--r--gdb/dwarf2/dwz.c60
-rw-r--r--gdb/dwarf2/frame-tailcall.c4
-rw-r--r--gdb/dwarf2/frame.c4
-rw-r--r--gdb/dwarf2/frame.h61
-rw-r--r--gdb/dwarf2/index-cache.c4
-rw-r--r--gdb/dwarf2/index-write.c4
-rw-r--r--gdb/dwarf2/loc.c6
-rw-r--r--gdb/dwarf2/loc.h70
-rw-r--r--gdb/dwarf2/public.h25
-rw-r--r--gdb/dwarf2/read-debug-names.c26
-rw-r--r--gdb/dwarf2/read-gdb-index.c9
-rw-r--r--gdb/dwarf2/read.c500
-rw-r--r--gdb/dwarf2/read.h19
-rw-r--r--gdb/dwarf2/section.h2
-rw-r--r--gdb/elfread.c4
-rw-r--r--gdb/eval.c21
-rw-r--r--gdb/event-top.c4
-rw-r--r--gdb/exec.c44
-rw-r--r--gdb/extension.c4
-rw-r--r--gdb/extract-store-integer.c4
-rw-r--r--gdb/f-lang.c4
-rw-r--r--gdb/f-valprint.c4
-rw-r--r--gdb/fbsd-nat.c6
-rw-r--r--gdb/filesystem.c4
-rw-r--r--gdb/findcmd.c4
-rw-r--r--gdb/fork-child.c4
-rw-r--r--gdb/frame-unwind.c6
-rw-r--r--gdb/frame.c4
-rw-r--r--gdb/frv-linux-tdep.c4
-rw-r--r--gdb/frv-tdep.c7
-rw-r--r--gdb/frv-tdep.h3
-rw-r--r--gdb/ft32-tdep.c4
-rw-r--r--gdb/gcore-1.in6
-rw-r--r--gdb/gcore.c4
-rw-r--r--gdb/gdb-demangle.c4
-rw-r--r--gdb/gdb-gdb.py.in8
-rw-r--r--gdb/gdb-stabs.h4
-rw-r--r--gdb/gdb_bfd.c4
-rw-r--r--gdb/gdb_buildall.sh2
-rw-r--r--gdb/gdbarch-gen.c24
-rw-r--r--gdb/gdbarch-gen.h7
-rw-r--r--gdb/gdbarch-selftests.c4
-rw-r--r--gdb/gdbarch.h1
-rw-r--r--gdb/gdbarch_components.py12
-rw-r--r--gdb/gdbtypes.c42
-rw-r--r--gdb/gdbtypes.h24
-rw-r--r--gdb/gmp-utils.c5
-rw-r--r--gdb/gnu-nat.c4
-rw-r--r--gdb/gnu-v2-abi.c14
-rw-r--r--gdb/gnu-v3-abi.c6
-rw-r--r--gdb/go32-nat.c4
-rw-r--r--gdb/guile/guile-internal.h9
-rw-r--r--gdb/guile/guile.c4
-rw-r--r--gdb/guile/scm-cmd.c83
-rw-r--r--gdb/guile/scm-param.c41
-rw-r--r--gdb/h8300-tdep.c4
-rw-r--r--gdb/hppa-bsd-tdep.c3
-rw-r--r--gdb/hppa-linux-nat.c4
-rw-r--r--gdb/hppa-linux-tdep.c8
-rw-r--r--gdb/hppa-netbsd-nat.c4
-rw-r--r--gdb/hppa-netbsd-tdep.c4
-rw-r--r--gdb/hppa-obsd-nat.c4
-rw-r--r--gdb/hppa-obsd-tdep.c4
-rw-r--r--gdb/hppa-tdep.c4
-rw-r--r--gdb/i386-bsd-nat.c4
-rw-r--r--gdb/i386-darwin-nat.c4
-rw-r--r--gdb/i386-darwin-tdep.c6
-rw-r--r--gdb/i386-dicos-tdep.c4
-rw-r--r--gdb/i386-fbsd-nat.c4
-rw-r--r--gdb/i386-fbsd-tdep.c7
-rw-r--r--gdb/i386-gnu-tdep.c7
-rw-r--r--gdb/i386-go32-tdep.c4
-rw-r--r--gdb/i386-linux-nat.c4
-rw-r--r--gdb/i386-linux-tdep.c8
-rw-r--r--gdb/i386-netbsd-nat.c4
-rw-r--r--gdb/i386-netbsd-tdep.c7
-rw-r--r--gdb/i386-obsd-nat.c4
-rw-r--r--gdb/i386-obsd-tdep.c7
-rw-r--r--gdb/i386-sol2-nat.c4
-rw-r--r--gdb/i386-sol2-tdep.c7
-rw-r--r--gdb/i386-tdep.c4
-rw-r--r--gdb/i386-windows-nat.c4
-rw-r--r--gdb/i386-windows-tdep.c4
-rw-r--r--gdb/ia64-libunwind-tdep.c4
-rw-r--r--gdb/ia64-linux-nat.c4
-rw-r--r--gdb/ia64-linux-tdep.c8
-rw-r--r--gdb/ia64-tdep.c4
-rw-r--r--gdb/ia64-vms-tdep.c4
-rw-r--r--gdb/inf-child.c6
-rw-r--r--gdb/inf-child.h4
-rw-r--r--gdb/infcall.c4
-rw-r--r--gdb/infcmd.c19
-rw-r--r--gdb/inferior.h9
-rw-r--r--gdb/inflow.c4
-rw-r--r--gdb/infrun.c16
-rw-r--r--gdb/inline-frame.c4
-rw-r--r--gdb/interps.c4
-rw-r--r--gdb/interps.h8
-rw-r--r--gdb/iq2000-tdep.c4
-rw-r--r--gdb/jit.c4
-rw-r--r--gdb/language.c4
-rw-r--r--gdb/linespec.c83
-rw-r--r--gdb/linux-fork.c4
-rw-r--r--gdb/linux-nat.c29
-rw-r--r--gdb/linux-nat.h3
-rw-r--r--gdb/linux-tdep.c196
-rw-r--r--gdb/linux-tdep.h6
-rw-r--r--gdb/linux-thread-db.c4
-rw-r--r--gdb/lm32-tdep.c4
-rw-r--r--gdb/loongarch-linux-nat.c4
-rw-r--r--gdb/loongarch-linux-tdep.c12
-rw-r--r--gdb/loongarch-tdep.c22
-rw-r--r--gdb/m32c-tdep.c4
-rw-r--r--gdb/m32r-linux-nat.c4
-rw-r--r--gdb/m32r-linux-tdep.c8
-rw-r--r--gdb/m32r-tdep.c4
-rw-r--r--gdb/m68hc11-tdep.c4
-rw-r--r--gdb/m68k-bsd-nat.c4
-rw-r--r--gdb/m68k-bsd-tdep.c7
-rw-r--r--gdb/m68k-linux-nat.c4
-rw-r--r--gdb/m68k-linux-tdep.c8
-rw-r--r--gdb/m68k-tdep.c4
-rw-r--r--gdb/machoread.c4
-rw-r--r--gdb/macrocmd.c41
-rw-r--r--gdb/macroscope.c39
-rw-r--r--gdb/macroscope.h20
-rw-r--r--gdb/main.c2
-rw-r--r--gdb/maint-test-options.c4
-rw-r--r--gdb/maint-test-settings.c4
-rw-r--r--gdb/maint.c36
-rw-r--r--gdb/maint.h8
-rwxr-xr-xgdb/make-init-c25
-rw-r--r--gdb/mdebugread.c25
-rw-r--r--gdb/mdebugread.h33
-rw-r--r--gdb/memattr.c4
-rw-r--r--gdb/mep-tdep.c4
-rw-r--r--gdb/mi/mi-cmd-env.c4
-rw-r--r--gdb/mi/mi-cmd-file.c5
-rw-r--r--gdb/mi/mi-cmds.c4
-rw-r--r--gdb/mi/mi-interp.c12
-rw-r--r--gdb/mi/mi-main.c4
-rw-r--r--gdb/microblaze-linux-tdep.c8
-rw-r--r--gdb/microblaze-tdep.c4
-rw-r--r--gdb/mingw-hdep.c64
-rw-r--r--gdb/minsyms.c2
-rw-r--r--gdb/mips-fbsd-nat.c4
-rw-r--r--gdb/mips-fbsd-tdep.c61
-rw-r--r--gdb/mips-linux-nat.c4
-rw-r--r--gdb/mips-linux-tdep.c76
-rw-r--r--gdb/mips-netbsd-nat.c4
-rw-r--r--gdb/mips-netbsd-tdep.c58
-rw-r--r--gdb/mips-sde-tdep.c4
-rw-r--r--gdb/mips-tdep.c4
-rw-r--r--gdb/mips64-obsd-nat.c4
-rw-r--r--gdb/mips64-obsd-tdep.c7
-rw-r--r--gdb/mipsread.c16
-rw-r--r--gdb/mn10300-linux-tdep.c8
-rw-r--r--gdb/mn10300-tdep.c4
-rw-r--r--gdb/moxie-tdep.c4
-rw-r--r--gdb/msp430-tdep.c4
-rw-r--r--gdb/nat/linux-namespaces.c167
-rw-r--r--gdb/nat/linux-namespaces.h11
-rw-r--r--gdb/nat/linux-procfs.c30
-rw-r--r--gdb/nat/linux-procfs.h14
-rw-r--r--gdb/nat/linux-ptrace.c4
-rw-r--r--gdb/nds32-tdep.c4
-rw-r--r--gdb/objc-lang.c4
-rw-r--r--gdb/objfiles.c12
-rw-r--r--gdb/objfiles.h23
-rw-r--r--gdb/observable.c4
-rw-r--r--gdb/or1k-linux-nat.c4
-rw-r--r--gdb/or1k-linux-tdep.c8
-rw-r--r--gdb/or1k-tdep.c4
-rw-r--r--gdb/osabi.c4
-rw-r--r--gdb/osdata.c4
-rw-r--r--gdb/p-valprint.c4
-rw-r--r--gdb/pager.h16
-rw-r--r--gdb/parse.c4
-rw-r--r--gdb/ppc-fbsd-nat.c4
-rw-r--r--gdb/ppc-fbsd-tdep.c10
-rw-r--r--gdb/ppc-linux-nat.c4
-rw-r--r--gdb/ppc-linux-tdep.c63
-rw-r--r--gdb/ppc-netbsd-nat.c4
-rw-r--r--gdb/ppc-netbsd-tdep.c7
-rw-r--r--gdb/ppc-obsd-nat.c4
-rw-r--r--gdb/ppc-obsd-tdep.c7
-rw-r--r--gdb/ppc-sysv-tdep.c1
-rw-r--r--gdb/printcmd.c6
-rw-r--r--gdb/probe.c4
-rw-r--r--gdb/proc-api.c4
-rw-r--r--gdb/proc-events.c4
-rw-r--r--gdb/proc-service.c4
-rw-r--r--gdb/procfs.c18
-rw-r--r--gdb/producer.c4
-rw-r--r--gdb/progspace.c1
-rw-r--r--gdb/progspace.h39
-rw-r--r--gdb/psymtab.c4
-rw-r--r--gdb/python/lib/gdb/__init__.py153
-rw-r--r--gdb/python/lib/gdb/dap/breakpoint.py6
-rw-r--r--gdb/python/lib/gdb/dap/completions.py7
-rw-r--r--gdb/python/lib/gdb/dap/evaluate.py6
-rw-r--r--gdb/python/lib/gdb/dap/events.py6
-rw-r--r--gdb/python/lib/gdb/dap/next.py15
-rw-r--r--gdb/python/lib/gdb/dap/server.py90
-rw-r--r--gdb/python/lib/gdb/dap/sources.py6
-rw-r--r--gdb/python/lib/gdb/dap/threads.py23
-rw-r--r--gdb/python/py-breakpoint.c4
-rw-r--r--gdb/python/py-cmd.c108
-rw-r--r--gdb/python/py-connection.c4
-rw-r--r--gdb/python/py-dap.c4
-rw-r--r--gdb/python/py-gdb-readline.c4
-rw-r--r--gdb/python/py-micmd.c4
-rw-r--r--gdb/python/py-param.c18
-rw-r--r--gdb/python/py-type.c2
-rw-r--r--gdb/python/py-unwind.c4
-rw-r--r--gdb/python/python-internal.h16
-rw-r--r--gdb/python/python.c46
-rw-r--r--gdb/ravenscar-thread.c4
-rw-r--r--gdb/record-btrace.c33
-rw-r--r--gdb/record-full.c4
-rw-r--r--gdb/record.c4
-rw-r--r--gdb/regcache-dump.c4
-rw-r--r--gdb/regcache.c4
-rw-r--r--gdb/reggroups.c4
-rw-r--r--gdb/remote-notif.c4
-rw-r--r--gdb/remote-sim.c4
-rw-r--r--gdb/remote.c39
-rw-r--r--gdb/reverse.c4
-rw-r--r--gdb/riscv-fbsd-nat.c4
-rw-r--r--gdb/riscv-fbsd-tdep.c11
-rw-r--r--gdb/riscv-linux-nat.c4
-rw-r--r--gdb/riscv-linux-tdep.c12
-rw-r--r--gdb/riscv-none-tdep.c4
-rw-r--r--gdb/riscv-tdep.c6
-rw-r--r--gdb/rl78-tdep.c4
-rw-r--r--gdb/rs6000-aix-nat.c4
-rw-r--r--gdb/rs6000-aix-tdep.c6
-rw-r--r--gdb/rs6000-lynx178-tdep.c4
-rw-r--r--gdb/rs6000-tdep.c4
-rw-r--r--gdb/run-on-main-thread.c4
-rw-r--r--gdb/rust-exp.h36
-rw-r--r--gdb/rust-lang.c33
-rw-r--r--gdb/rust-parse.c4
-rw-r--r--gdb/rx-tdep.c4
-rw-r--r--gdb/s12z-tdep.c4
-rw-r--r--gdb/s390-linux-nat.c4
-rw-r--r--gdb/s390-linux-tdep.c11
-rw-r--r--gdb/s390-tdep.c4
-rw-r--r--gdb/ser-go32.c4
-rw-r--r--gdb/ser-mingw.c4
-rw-r--r--gdb/ser-pipe.c4
-rw-r--r--gdb/ser-tcp.c4
-rw-r--r--gdb/ser-uds.c4
-rw-r--r--gdb/ser-unix.c164
-rw-r--r--gdb/serial.c4
-rw-r--r--gdb/sh-linux-tdep.c8
-rw-r--r--gdb/sh-netbsd-nat.c4
-rw-r--r--gdb/sh-netbsd-tdep.c7
-rw-r--r--gdb/sh-tdep.c4
-rw-r--r--gdb/skip.c4
-rw-r--r--gdb/sol-thread.c18
-rw-r--r--gdb/solib-aix.c92
-rw-r--r--gdb/solib-aix.h7
-rw-r--r--gdb/solib-darwin.c92
-rw-r--r--gdb/solib-darwin.h6
-rw-r--r--gdb/solib-dsbt.c81
-rw-r--r--gdb/solib-dsbt.h6
-rw-r--r--gdb/solib-frv.c79
-rw-r--r--gdb/solib-frv.h28
-rw-r--r--gdb/solib-rocm.c170
-rw-r--r--gdb/solib-svr4-linux.c98
-rw-r--r--gdb/solib-svr4-linux.h47
-rw-r--r--gdb/solib-svr4.c504
-rw-r--r--gdb/solib-svr4.h130
-rw-r--r--gdb/solib-target.c64
-rw-r--r--gdb/solib-target.h16
-rw-r--r--gdb/solib.c230
-rw-r--r--gdb/solib.h253
-rw-r--r--gdb/solist.h225
-rw-r--r--gdb/source-cache.c4
-rw-r--r--gdb/source.c4
-rw-r--r--gdb/sparc-linux-nat.c4
-rw-r--r--gdb/sparc-linux-tdep.c8
-rw-r--r--gdb/sparc-nat.c4
-rw-r--r--gdb/sparc-netbsd-nat.c4
-rw-r--r--gdb/sparc-netbsd-tdep.c7
-rw-r--r--gdb/sparc-obsd-tdep.c4
-rw-r--r--gdb/sparc-sol2-tdep.c7
-rw-r--r--gdb/sparc-tdep.c4
-rw-r--r--gdb/sparc64-fbsd-nat.c4
-rw-r--r--gdb/sparc64-fbsd-tdep.c7
-rw-r--r--gdb/sparc64-linux-nat.c4
-rw-r--r--gdb/sparc64-linux-tdep.c8
-rw-r--r--gdb/sparc64-nat.c4
-rw-r--r--gdb/sparc64-netbsd-nat.c4
-rw-r--r--gdb/sparc64-netbsd-tdep.c7
-rw-r--r--gdb/sparc64-obsd-nat.c4
-rw-r--r--gdb/sparc64-obsd-tdep.c7
-rw-r--r--gdb/sparc64-sol2-tdep.c7
-rw-r--r--gdb/sparc64-tdep.c4
-rw-r--r--gdb/stabsread.c4
-rw-r--r--gdb/stack.c4
-rw-r--r--gdb/stap-probe.c4
-rw-r--r--gdb/std-regs.c4
-rw-r--r--gdb/svr4-tls-tdep.c4
-rw-r--r--gdb/symfile-debug.c4
-rw-r--r--gdb/symfile-mem.c4
-rw-r--r--gdb/symfile.c10
-rw-r--r--gdb/symmisc.c4
-rw-r--r--gdb/symtab.c27
-rw-r--r--gdb/symtab.h6
-rwxr-xr-xgdb/syscalls/riscv-canonicalize-syscall-gen.py2
-rw-r--r--gdb/target-connection.c5
-rw-r--r--gdb/target-dcache.c4
-rw-r--r--gdb/target-descriptions.c4
-rw-r--r--gdb/target.c18
-rw-r--r--gdb/target.h8
-rw-r--r--gdb/testsuite/gdb.ada/dyn-bit-offset.exp43
-rw-r--r--gdb/testsuite/gdb.ada/dyn-bit-offset/exam.adb2
-rw-r--r--gdb/testsuite/gdb.ada/finish-var-size.exp8
-rw-r--r--gdb/testsuite/gdb.ada/negative-bit-offset.exp36
-rw-r--r--gdb/testsuite/gdb.ada/negative-bit-offset/prog.adb36
-rw-r--r--gdb/testsuite/gdb.arch/amd64-watchpoint-downgrade.exp2
-rw-r--r--gdb/testsuite/gdb.arch/i386-prologue-skip-cf-protection-stackalign.c27
-rw-r--r--gdb/testsuite/gdb.arch/i386-prologue-skip-cf-protection.exp70
-rw-r--r--gdb/testsuite/gdb.base/attach-deleted-exec.exp44
-rw-r--r--gdb/testsuite/gdb.base/bp-cond-failure.exp4
-rw-r--r--gdb/testsuite/gdb.base/bp-permanent.c2
-rw-r--r--gdb/testsuite/gdb.base/bp-permanent.exp4
-rw-r--r--gdb/testsuite/gdb.base/break-dbg.cc31
-rw-r--r--gdb/testsuite/gdb.base/break-dbg.exp70
-rw-r--r--gdb/testsuite/gdb.base/catch-fork-kill.exp2
-rw-r--r--gdb/testsuite/gdb.base/catch-fork-static.exp4
-rw-r--r--gdb/testsuite/gdb.base/catch-signal-fork.exp1
-rw-r--r--gdb/testsuite/gdb.base/corefile-shmem-zero-id-lib.c522
-rw-r--r--gdb/testsuite/gdb.base/corefile-shmem-zero-id.c63
-rw-r--r--gdb/testsuite/gdb.base/corefile-shmem-zero-id.exp228
-rw-r--r--gdb/testsuite/gdb.base/default.exp209
-rw-r--r--gdb/testsuite/gdb.base/dlmopen-ns-ids.exp20
-rw-r--r--gdb/testsuite/gdb.base/filename-completion.exp27
-rw-r--r--gdb/testsuite/gdb.base/foll-exec-c++.exp24
-rw-r--r--gdb/testsuite/gdb.base/foll-exec-c.exp23
-rw-r--r--gdb/testsuite/gdb.base/foll-exec.c33
-rw-r--r--gdb/testsuite/gdb.base/foll-exec.exp.tcl (renamed from gdb/testsuite/gdb.base/foll-exec.exp)90
-rw-r--r--gdb/testsuite/gdb.base/foll-fork-syscall.c35
-rw-r--r--gdb/testsuite/gdb.base/foll-fork-syscall.exp143
-rw-r--r--gdb/testsuite/gdb.base/foll-fork.exp2
-rw-r--r--gdb/testsuite/gdb.base/foll-vfork.exp7
-rw-r--r--gdb/testsuite/gdb.base/fork-no-detach-follow-child-dlopen.exp1
-rw-r--r--gdb/testsuite/gdb.base/fork-print-inferior-events.exp2
-rw-r--r--gdb/testsuite/gdb.base/fork-running-state.exp2
-rw-r--r--gdb/testsuite/gdb.base/infcall-failure.exp16
-rw-r--r--gdb/testsuite/gdb.base/inferior-died.exp5
-rw-r--r--gdb/testsuite/gdb.base/info-shared.exp3
-rw-r--r--gdb/testsuite/gdb.base/interrupt-daemon.exp2
-rw-r--r--gdb/testsuite/gdb.base/jit-elf-fork.exp1
-rw-r--r--gdb/testsuite/gdb.base/kill-detach-inferiors-cmd.exp1
-rw-r--r--gdb/testsuite/gdb.base/maint.exp38
-rw-r--r--gdb/testsuite/gdb.base/multi-forks.exp6
-rw-r--r--gdb/testsuite/gdb.base/options.exp16
-rw-r--r--gdb/testsuite/gdb.base/pie-fork.exp2
-rw-r--r--gdb/testsuite/gdb.base/run-control-while-bg-execution.exp5
-rw-r--r--gdb/testsuite/gdb.base/sigall.exp9
-rw-r--r--gdb/testsuite/gdb.base/step-over-exit.exp7
-rw-r--r--gdb/testsuite/gdb.base/style.exp277
-rw-r--r--gdb/testsuite/gdb.base/user-namespace-attach.c35
-rw-r--r--gdb/testsuite/gdb.base/user-namespace-attach.exp148
-rw-r--r--gdb/testsuite/gdb.base/vfork-follow-parent.exp2
-rw-r--r--gdb/testsuite/gdb.base/watch-before-fork.exp2
-rw-r--r--gdb/testsuite/gdb.base/watch-vfork.exp2
-rw-r--r--gdb/testsuite/gdb.base/watchpoint-hw-attach.exp21
-rw-r--r--gdb/testsuite/gdb.btrace/multi-inferior.exp2
-rw-r--r--gdb/testsuite/gdb.cp/chained-calls.cc17
-rw-r--r--gdb/testsuite/gdb.cp/chained-calls.exp3
-rw-r--r--gdb/testsuite/gdb.cp/cpexprs.exp.tcl36
-rw-r--r--gdb/testsuite/gdb.dap/attach.exp4
-rw-r--r--gdb/testsuite/gdb.dap/log-message.exp9
-rw-r--r--gdb/testsuite/gdb.dap/threads.c67
-rw-r--r--gdb/testsuite/gdb.dap/threads.exp81
-rw-r--r--gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp2
-rw-r--r--gdb/testsuite/gdb.debuginfod/corefile-mapped-file.exp4
-rw-r--r--gdb/testsuite/gdb.debuginfod/solib-with-soname.exp2
-rw-r--r--gdb/testsuite/gdb.dwarf2/ada-array-bound.c29
-rw-r--r--gdb/testsuite/gdb.dwarf2/ada-array-bound.exp89
-rw-r--r--gdb/testsuite/gdb.dwarf2/dw-form-strx-out-of-bounds.exp6
-rw-r--r--gdb/testsuite/gdb.dwarf2/dw-form-strx.exp2
-rw-r--r--gdb/testsuite/gdb.dwarf2/dw-form-strx.exp.tcl12
-rw-r--r--gdb/testsuite/gdb.dwarf2/dw2-modula2-self-type.S6
-rw-r--r--gdb/testsuite/gdb.dwarf2/dw2-ranges-psym-warning.exp2
-rw-r--r--gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.S6
-rw-r--r--gdb/testsuite/gdb.dwarf2/dw2-strp.S6
-rw-r--r--gdb/testsuite/gdb.dwarf2/dynamic-bit-offset.exp95
-rw-r--r--gdb/testsuite/gdb.dwarf2/fission-dw-form-strx.exp88
-rw-r--r--gdb/testsuite/gdb.dwarf2/pr11465.S6
-rw-r--r--gdb/testsuite/gdb.guile/scm-cmd.exp59
-rw-r--r--gdb/testsuite/gdb.guile/scm-frame.exp2
-rw-r--r--gdb/testsuite/gdb.guile/scm-parameter.exp195
-rw-r--r--gdb/testsuite/gdb.linespec/linespec.exp6
-rw-r--r--gdb/testsuite/gdb.linespec/lspec.cc2
-rw-r--r--gdb/testsuite/gdb.mi/interrupt-thread-group.exp2
-rw-r--r--gdb/testsuite/gdb.mi/mi-condbreak-throw.exp2
-rw-r--r--gdb/testsuite/gdb.mi/mi-multi-commands.exp2
-rw-r--r--gdb/testsuite/gdb.mi/mi-var-display.exp4
-rw-r--r--gdb/testsuite/gdb.mi/user-selected-context-sync.exp4
-rw-r--r--gdb/testsuite/gdb.multi/attach-no-multi-process.exp5
-rw-r--r--gdb/testsuite/gdb.multi/attach-while-running.exp3
-rw-r--r--gdb/testsuite/gdb.multi/bp-thread-specific.exp2
-rw-r--r--gdb/testsuite/gdb.multi/dummy-frame-restore.exp2
-rw-r--r--gdb/testsuite/gdb.multi/multi-arch.exp2
-rw-r--r--gdb/testsuite/gdb.multi/multi-attach.exp2
-rw-r--r--gdb/testsuite/gdb.multi/multi-exit.exp2
-rw-r--r--gdb/testsuite/gdb.multi/multi-kill.exp2
-rw-r--r--gdb/testsuite/gdb.multi/multi-re-run.exp2
-rw-r--r--gdb/testsuite/gdb.multi/multi-target.exp.tcl4
-rw-r--r--gdb/testsuite/gdb.multi/multi-term-settings.exp2
-rw-r--r--gdb/testsuite/gdb.multi/start-inferior-specific.exp2
-rw-r--r--gdb/testsuite/gdb.multi/stop-all-on-exit.exp2
-rw-r--r--gdb/testsuite/gdb.multi/tids-gid-reset.exp2
-rw-r--r--gdb/testsuite/gdb.multi/tids.exp7
-rw-r--r--gdb/testsuite/gdb.multi/watchpoint-multi-exit.exp2
-rw-r--r--gdb/testsuite/gdb.multi/watchpoint-multi.exp2
-rw-r--r--gdb/testsuite/gdb.opt/break-on-_exit.exp2
-rw-r--r--gdb/testsuite/gdb.pascal/integers.exp2
-rw-r--r--gdb/testsuite/gdb.python/py-cmd.exp85
-rw-r--r--gdb/testsuite/gdb.python/py-parameter-prefix.exp382
-rw-r--r--gdb/testsuite/gdb.python/py-parameter.exp187
-rw-r--r--gdb/testsuite/gdb.python/py-source-styling-2.exp24
-rw-r--r--gdb/testsuite/gdb.python/py-warning.exp63
-rw-r--r--gdb/testsuite/gdb.replay/connect.exp2
-rw-r--r--gdb/testsuite/gdb.reverse/i386-avx-reverse.exp2
-rw-r--r--gdb/testsuite/gdb.reverse/solib-precsave.exp2
-rw-r--r--gdb/testsuite/gdb.reverse/solib-reverse.exp2
-rw-r--r--gdb/testsuite/gdb.rocm/code-object-load-while-breakpoint-hit.cpp86
-rw-r--r--gdb/testsuite/gdb.rocm/code-object-load-while-breakpoint-hit.exp68
-rw-r--r--gdb/testsuite/gdb.rocm/fork-exec-gpu-to-non-gpu.exp1
-rw-r--r--gdb/testsuite/gdb.rocm/fork-exec-non-gpu-to-gpu.exp1
-rw-r--r--gdb/testsuite/gdb.rocm/precise-memory-fork.exp1
-rw-r--r--gdb/testsuite/gdb.rocm/precise-memory.exp2
-rw-r--r--gdb/testsuite/gdb.server/build-id-seqno.exp6
-rw-r--r--gdb/testsuite/gdb.server/fileio-packets.exp66
-rw-r--r--gdb/testsuite/gdb.server/fileio-packets.py208
-rw-r--r--gdb/testsuite/gdb.server/pread-offset-size.S29
-rw-r--r--gdb/testsuite/gdb.server/pread-offset-size.exp49
-rw-r--r--gdb/testsuite/gdb.stabs/weird.def2
-rw-r--r--gdb/testsuite/gdb.testsuite/gdb_test_multiple-lbl.exp84
-rwxr-xr-xgdb/testsuite/gdb.testsuite/gdb_test_multiple-lbl.gdb25
-rw-r--r--gdb/testsuite/gdb.threads/access-mem-running-thread-exit.exp89
-rw-r--r--gdb/testsuite/gdb.threads/current-lwp-dead.exp2
-rw-r--r--gdb/testsuite/gdb.threads/detach-step-over.exp2
-rw-r--r--gdb/testsuite/gdb.threads/foll-fork-other-thread.exp2
-rw-r--r--gdb/testsuite/gdb.threads/fork-child-threads.exp5
-rw-r--r--gdb/testsuite/gdb.threads/fork-plus-threads.exp2
-rw-r--r--gdb/testsuite/gdb.threads/fork-thread-pending.exp6
-rw-r--r--gdb/testsuite/gdb.threads/forking-threads-plus-breakpoint.exp2
-rw-r--r--gdb/testsuite/gdb.threads/info-threads-options.c77
-rw-r--r--gdb/testsuite/gdb.threads/info-threads-options.exp131
-rw-r--r--gdb/testsuite/gdb.threads/next-fork-exec-other-thread.exp2
-rw-r--r--gdb/testsuite/gdb.threads/next-fork-other-thread.exp2
-rw-r--r--gdb/testsuite/gdb.threads/pending-fork-event-detach-ns.exp2
-rw-r--r--gdb/testsuite/gdb.threads/pending-fork-event-detach.exp2
-rw-r--r--gdb/testsuite/gdb.threads/thread-bp-deleted.exp2
-rw-r--r--gdb/testsuite/gdb.threads/thread-execl.c10
-rw-r--r--gdb/testsuite/gdb.threads/threadapply.exp6
-rw-r--r--gdb/testsuite/gdb.threads/vfork-follow-child-exec.exp2
-rw-r--r--gdb/testsuite/gdb.threads/vfork-follow-child-exit.exp2
-rw-r--r--gdb/testsuite/gdb.threads/vfork-multi-inferior.exp4
-rw-r--r--gdb/testsuite/gdb.threads/vfork-multi-thread.exp2
-rw-r--r--gdb/testsuite/gdb.threads/watchpoint-fork.exp2
-rw-r--r--gdb/testsuite/gdb.trace/tspeed.exp2
-rw-r--r--gdb/testsuite/gdb.tui/pr30056.exp4
-rw-r--r--gdb/testsuite/gdb.tui/tui-focus.exp2
-rw-r--r--gdb/testsuite/gdb.xml/bad-include.xml2
-rw-r--r--gdb/testsuite/gdb.xml/tdesc-xinclude.exp2
-rw-r--r--gdb/testsuite/lib/dwarf.exp36
-rw-r--r--gdb/testsuite/lib/gdb.exp93
-rw-r--r--gdb/testsuite/lib/gdbserver-support.exp2
-rwxr-xr-xgdb/testsuite/make-check-all.sh4
-rw-r--r--gdb/thread.c126
-rw-r--r--gdb/tic6x-linux-tdep.c6
-rw-r--r--gdb/tic6x-tdep.c4
-rw-r--r--gdb/tilegx-linux-nat.c4
-rw-r--r--gdb/tilegx-linux-tdep.c11
-rw-r--r--gdb/tilegx-tdep.c4
-rw-r--r--gdb/top.c8
-rw-r--r--gdb/tracectf.c6
-rw-r--r--gdb/tracefile-tfile.c6
-rw-r--r--gdb/tracefile.c4
-rw-r--r--gdb/tracepoint.c4
-rw-r--r--gdb/tui/tui-disasm.c4
-rw-r--r--gdb/tui/tui-hooks.c4
-rw-r--r--gdb/tui/tui-interp.c4
-rw-r--r--gdb/tui/tui-layout.c4
-rw-r--r--gdb/tui/tui-regs.c4
-rw-r--r--gdb/tui/tui-status.c4
-rw-r--r--gdb/tui/tui-win.c4
-rw-r--r--gdb/tui/tui.c4
-rw-r--r--gdb/typeprint.c4
-rw-r--r--gdb/ui.c4
-rw-r--r--gdb/unittests/array-view-selftests.c4
-rw-r--r--gdb/unittests/child-path-selftests.c4
-rw-r--r--gdb/unittests/cli-utils-selftests.c4
-rw-r--r--gdb/unittests/command-def-selftests.c4
-rw-r--r--gdb/unittests/common-utils-selftests.c4
-rw-r--r--gdb/unittests/copy_bitwise-selftests.c4
-rw-r--r--gdb/unittests/enum-flags-selftests.c5
-rw-r--r--gdb/unittests/environ-selftests.c4
-rw-r--r--gdb/unittests/filtered_iterator-selftests.c4
-rw-r--r--gdb/unittests/format_pieces-selftests.c4
-rw-r--r--gdb/unittests/frame_info_ptr-selftests.c4
-rw-r--r--gdb/unittests/function-view-selftests.c4
-rw-r--r--gdb/unittests/gdb_tilde_expand-selftests.c4
-rw-r--r--gdb/unittests/gmp-utils-selftests.c5
-rw-r--r--gdb/unittests/intrusive_list-selftests.c5
-rw-r--r--gdb/unittests/lookup_name_info-selftests.c4
-rw-r--r--gdb/unittests/main-thread-selftests.c4
-rw-r--r--gdb/unittests/memory-map-selftests.c4
-rw-r--r--gdb/unittests/memrange-selftests.c4
-rw-r--r--gdb/unittests/mkdir-recursive-selftests.c4
-rw-r--r--gdb/unittests/observable-selftests.c4
-rw-r--r--gdb/unittests/offset-type-selftests.c4
-rw-r--r--gdb/unittests/packed-selftests.c4
-rw-r--r--gdb/unittests/parallel-for-selftests.c141
-rw-r--r--gdb/unittests/parse-connection-spec-selftests.c4
-rw-r--r--gdb/unittests/path-join-selftests.c4
-rw-r--r--gdb/unittests/remote-arg-selftests.c5
-rw-r--r--gdb/unittests/rsp-low-selftests.c4
-rw-r--r--gdb/unittests/scoped_fd-selftests.c4
-rw-r--r--gdb/unittests/scoped_ignore_signal-selftests.c4
-rw-r--r--gdb/unittests/scoped_mmap-selftests.c4
-rw-r--r--gdb/unittests/scoped_restore-selftests.c4
-rw-r--r--gdb/unittests/search-memory-selftests.c4
-rw-r--r--gdb/unittests/style-selftests.c4
-rw-r--r--gdb/unittests/tracepoint-selftests.c4
-rw-r--r--gdb/unittests/tui-selftests.c4
-rw-r--r--gdb/unittests/ui-file-selftests.c4
-rw-r--r--gdb/unittests/unique_xmalloc_ptr_char.c4
-rw-r--r--gdb/unittests/unpack-selftests.c4
-rw-r--r--gdb/unittests/vec-utils-selftests.c4
-rw-r--r--gdb/unittests/xml-utils-selftests.c4
-rw-r--r--gdb/user-regs.c4
-rw-r--r--gdb/utils.c40
-rw-r--r--gdb/utils.h2
-rw-r--r--gdb/v850-tdep.c4
-rw-r--r--gdb/valops.c4
-rw-r--r--gdb/valprint.c4
-rw-r--r--gdb/value.c4
-rw-r--r--gdb/varobj.c4
-rw-r--r--gdb/vax-bsd-nat.c4
-rw-r--r--gdb/vax-netbsd-tdep.c7
-rw-r--r--gdb/vax-tdep.c4
-rw-r--r--gdb/windows-nat.c16
-rw-r--r--gdb/windows-tdep.c31
-rw-r--r--gdb/x86-bsd-nat.c4
-rw-r--r--gdb/x86-gnu-nat.c4
-rw-r--r--gdb/x86-linux-nat.c4
-rw-r--r--gdb/xcoffread.c4
-rw-r--r--gdb/xml-support.c5
-rw-r--r--gdb/xml-syscall.c2
-rw-r--r--gdb/xml-tdesc.c2
-rw-r--r--gdb/xstormy16-tdep.c4
-rw-r--r--gdb/xtensa-linux-nat.c4
-rw-r--r--gdb/xtensa-linux-tdep.c8
-rw-r--r--gdb/xtensa-tdep.c7
-rw-r--r--gdb/z80-tdep.c11
702 files changed, 9757 insertions, 4517 deletions
diff --git a/gdb/MAINTAINERS b/gdb/MAINTAINERS
index 5e1aada..5284110 100644
--- a/gdb/MAINTAINERS
+++ b/gdb/MAINTAINERS
@@ -492,7 +492,7 @@ sim/ See sim/MAINTAINERS
readline/ Master version: ftp://ftp.cwru.edu/pub/bash/
ALL
- Host maintainers (host dependant parts)
+ Host maintainers (host dependent parts)
(but get your changes into the master version)
tcl/ tk/ itcl/ ALL
@@ -602,6 +602,7 @@ Klaus Gerlicher klaus.gerlicher@intel.com
Mircea Gherzan mircea.gherzan@intel.com
Paul Gilliam pgilliam@us.ibm.com
Tristan Gingold tgingold@free.fr
+Timur Golubovich timurgol007@gmail.com
Anton Gorenkov xgsa@yandex.ru
Raoul Gough RaoulGough@yahoo.co.uk
Anthony Green green@redhat.com
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 285a00b..fc0c565 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -265,7 +265,7 @@ INCSUPPORT = \
-I..
#
-# CLI sub directory definitons
+# CLI sub directory definitions
#
SUBDIR_CLI_SRCS = \
cli/cli-cmds.c \
@@ -282,7 +282,7 @@ SUBDIR_CLI_SRCS = \
SUBDIR_CLI_OBS = $(patsubst %.c,%.o,$(SUBDIR_CLI_SRCS))
#
-# MI sub directory definitons
+# MI sub directory definitions
#
SUBDIR_MI_SRCS = \
mi/mi-cmd-break.c \
@@ -350,7 +350,7 @@ SUBDIR_GCC_COMPILE_SRCS = \
SUBDIR_GCC_COMPILE_OBS = $(patsubst %.c,%.o,$(filter %.c,$(SUBDIR_GCC_COMPILE_SRCS)))
#
-# Guile sub directory definitons for guile support.
+# Guile sub directory definitions for guile support.
#
SUBDIR_GUILE_SRCS = \
guile/guile.c \
@@ -387,7 +387,7 @@ SUBDIR_GUILE_LDFLAGS =
SUBDIR_GUILE_CFLAGS =
#
-# python sub directory definitons
+# python sub directory definitions
#
SUBDIR_PYTHON_SRCS = \
python/py-arch.c \
@@ -891,6 +891,7 @@ ALL_TARGET_OBS = \
solib-dsbt.o \
solib-frv.o \
solib-svr4.o \
+ solib-svr4-linux.o \
sparc-linux-tdep.o \
sparc-netbsd-tdep.o \
sparc-obsd-tdep.o \
@@ -1092,36 +1093,6 @@ COMMON_SFILES = \
disasm.c \
displaced-stepping.c \
dummy-frame.c \
- dwarf2/abbrev.c \
- dwarf2/abbrev-table-cache.c \
- dwarf2/ada-imported.c \
- dwarf2/aranges.c \
- dwarf2/attribute.c \
- dwarf2/cooked-index.c \
- dwarf2/cooked-index-entry.c \
- dwarf2/cooked-index-shard.c \
- dwarf2/cooked-index-worker.c \
- dwarf2/cooked-indexer.c \
- dwarf2/cu.c \
- dwarf2/die.c \
- dwarf2/dwz.c \
- dwarf2/expr.c \
- dwarf2/frame-tailcall.c \
- dwarf2/frame.c \
- dwarf2/index-cache.c \
- dwarf2/index-common.c \
- dwarf2/index-write.c \
- dwarf2/leb.c \
- dwarf2/line-header.c \
- dwarf2/loc.c \
- dwarf2/macro.c \
- dwarf2/parent-map.c \
- dwarf2/read.c \
- dwarf2/read-debug-names.c \
- dwarf2/read-gdb-index.c \
- dwarf2/section.c \
- dwarf2/stringify.c \
- dwarf2/unit-head.c \
extract-store-integer.c \
eval.c \
event-top.c \
@@ -1172,7 +1143,6 @@ COMMON_SFILES = \
maint.c \
maint-test-options.c \
maint-test-settings.c \
- mdebugread.c \
mem-break.c \
memattr.c \
memory-map.c \
@@ -1509,9 +1479,10 @@ HFILES_NO_SRCDIR = \
solib.h \
solib-aix.h \
solib-darwin.h \
+ solib-frv.h \
solib-svr4.h \
+ solib-svr4-linux.h \
solib-target.h \
- solist.h \
source.h \
source-cache.h \
sparc-nat.h \
@@ -1913,6 +1884,40 @@ TAGFILES_NO_SRCDIR = $(SFILES) $(HFILES_NO_SRCDIR) $(ALLDEPFILES) \
$(CONFIG_SRCS)
TAGFILES_WITH_SRCDIR = $(HFILES_WITH_SRCDIR)
+# Files that are used to support certain debuginfo formats
+DWARF2_SRCS = \
+ dwarf2/abbrev.c \
+ dwarf2/abbrev-table-cache.c \
+ dwarf2/ada-imported.c \
+ dwarf2/aranges.c \
+ dwarf2/attribute.c \
+ dwarf2/cooked-index.c \
+ dwarf2/cooked-index-entry.c \
+ dwarf2/cooked-index-shard.c \
+ dwarf2/cooked-index-worker.c \
+ dwarf2/cooked-indexer.c \
+ dwarf2/cu.c \
+ dwarf2/die.c \
+ dwarf2/dwz.c \
+ dwarf2/expr.c \
+ dwarf2/frame-tailcall.c \
+ dwarf2/frame.c \
+ dwarf2/index-cache.c \
+ dwarf2/index-common.c \
+ dwarf2/index-write.c \
+ dwarf2/leb.c \
+ dwarf2/line-header.c \
+ dwarf2/loc.c \
+ dwarf2/macro.c \
+ dwarf2/parent-map.c \
+ dwarf2/read.c \
+ dwarf2/read-debug-names.c \
+ dwarf2/read-gdb-index.c \
+ dwarf2/section.c \
+ dwarf2/stringify.c \
+ dwarf2/unit-head.c
+DWARF2_OBS = $(patsubst %.c,%.o, $(DWARF2_SRCS))
+
COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
mi/mi-common.o \
version.o \
diff --git a/gdb/NEWS b/gdb/NEWS
index a82b7e3..2abe376 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -35,18 +35,18 @@
a -h or --help option, which prints each options and a brief
description.
-* On systems that support linkage namespaces, the output of the command
+* On systems that support linker namespaces, the output of the command
"info sharedlibraries" may add one more column, NS, which identifies the
namespace into which the library was loaded, if more than one namespace
is active.
* New built-in convenience variables $_active_linker_namespaces and
- $_current_linker_namespace. These show the number of active linkage
+ $_linker_namespace. These show the number of active linker
namespaces, and the namespace to which the current location belongs to.
- In systems that don't support linkage namespaces, these always return 1
- and [[0]] respectively.
+ In systems that don't support linker namespaces, these always return
+ the integers 1 and 0 respectively.
- * Add record full support for rv64gc architectures
+* Add record full support for rv64gc architectures
* New commands
@@ -59,6 +59,12 @@ maintenance check symtabs
maintenance canonicalize
Show the canonical form of a C++ name.
+maintenance set console-translation-mode <binary|text>
+maintenance show console-translation-mode
+ Controls the translation mode of GDB stdout/stderr. MS-Windows only. In
+ binary mode, no translation is done. In text mode, a Line Feed is
+ translated into a Carriage Return-Line Feed combination.
+
set riscv numeric-register-names on|off
show riscv numeric-register-names
Controls whether GDB refers to risc-v registers by their numeric names
@@ -90,6 +96,18 @@ info sharedlibrary
command are now for the full memory range allocated to the shared
library.
+info threads [-gid] [-stopped] [-running] [ID]...
+ If no threads match the given ID(s) or filter options, GDB now prints
+
+ No threads matched.
+
+ without printing the provided arguments. The newly added '-stopped'
+ option makes GDB list the stopped threads only. Similarly,
+ '-running' makes GDB list the running threads only. If both options
+ are given together, both stopped and running threads are listed.
+ These new flags can be useful to get a reduced list when there is a
+ large number of threads.
+
* GDB-internal Thread Local Storage (TLS) support
** Linux targets for the x86_64, aarch64, ppc64, s390x, and riscv
@@ -112,6 +130,8 @@ info sharedlibrary
* Python API
+ ** GDB no longer supports Python versions less than 3.4.
+
** New class gdb.Color for dealing with colors.
** New constant gdb.PARAM_COLOR represents color type of a
@@ -128,6 +148,23 @@ info sharedlibrary
when output is going to standard output, and False when output is
going to a string.
+ ** Setting the documentation string (__doc__) of a gdb.Parameter
+ sub-class to the empty string, means GDB will only display the
+ set_doc or show_doc strings in the set/show help output.
+
+ ** New gdb.ParameterPrefix class. This can be used to create 'set'
+ and 'show' gdb.Command prefixes, suitable for use with new
+ gdb.Parameters.
+
+ ** Prefix commands (gdb.Command sub-classes) that don't have an
+ invoke method will now behave like builtin prefix commands when
+ invoked without a sub-command name. This means printing the help
+ text for all sub-commands, unless the prefix command is a 'show'
+ command, in which case the value of all sub-commands is printed.
+
+ ** New gdb.warning() function that takes a string and prints it as a
+ warning, with GDB's standard 'warning' prefix.
+
* Guile API
** New type <gdb:color> for dealing with colors.
@@ -135,6 +172,17 @@ info sharedlibrary
** New constant PARAM_COLOR represents color type of a value
of a <gdb:parameter> object. Parameter's value is <gdb::color> instance.
+ ** Eliding the #:doc string from make-parameter now means that GDB
+ will use a default documentation string. Setting #:doc to the
+ empty string for make-parameter means GDB will only display the
+ #:set_doc or #:show_doc strings in the set/show help output.
+
+ ** Prefix commands (using make-command) that don't have a #:invoke
+ property will now behave like builtin prefix commands when
+ invoked without a sub-command name. This means printing the help
+ text for all sub-commands, unless the prefix command is a 'show'
+ command, in which case the value of all sub-commands is printed.
+
* New remote packets
binary-upload in qSupported reply
@@ -143,6 +191,11 @@ binary-upload in qSupported reply
stub doesn't report this feature supported, then GDB will not use
the 'x' packet.
+vFile:lstat
+ Return information about files on the remote system. Like
+ vFile:stat but if the filename is a symbolic link, return
+ information about the link itself, the file the link refers to.
+
* Changed remote packets
qXfer:threads:read
@@ -151,6 +204,11 @@ qXfer:threads:read
should print as the target ID of the thread, for example in the
"info threads" command or when switching to the thread.
+vFile:stat
+ Previously, gdbserver incorrectly implemented this packet using
+ lstat rather than stat. This has now been corrected. The
+ documentation has also been clarified.
+
* MI changes
** The =library-unloaded event now includes the 'ranges' field, which
@@ -170,6 +228,14 @@ qXfer:threads:read
subsystem to be disabled at configure time, in the form of
--disable-gdb-compile.
+* A new configure option was added, allowing support for DWARF debug
+ information to be disabled at configure time. The flag is
+ --disable-gdb-dwarf-support.
+
+* A new configure option was added, allowing support for mdebug/ecoff
+ debug information to be disabled at configure time. The flag to do
+ that is --disable-gdb-mdebug-support.
+
*** Changes in GDB 16
* Support for Nios II targets has been removed as this architecture
@@ -7545,7 +7611,7 @@ for DW_OP_piece is still missing).
A number of long standing bugs that caused GDB to die while starting a
Java application have been fixed. GDB's Java support is now
-considered "useable".
+considered "usable".
* GNU/Linux support for fork, vfork, and exec.
diff --git a/gdb/README b/gdb/README
index 5a00305..eca4181c 100644
--- a/gdb/README
+++ b/gdb/README
@@ -443,7 +443,14 @@ more obscure GDB `configure' options are not listed here.
supported).
`--disable-gdb-compile'
- Build GDB without support for the 'compile' command.
+ Build GDB without support for the 'compile' command. DWARF support
+ is required for this feature.
+
+`--disable-gdb-dwarf-support'
+ Build GDB without support for reading DWARF debug information.
+
+`--disable-gdb-mdebug-support'
+ Build GDB without support for reading mdebug debug information.
`--with-curses'
Use the curses library instead of the termcap library, for
@@ -533,7 +540,7 @@ more obscure GDB `configure' options are not listed here.
GDB scripting much more powerful than the restricted CLI
scripting language. If your host does not have Python installed,
you can find it on `http://www.python.org/download/'. The oldest
- version of Python supported by GDB is 3.2. The optional argument
+ version of Python supported by GDB is 3.4. The optional argument
PYTHON is used to find the Python headers and libraries. It can
be either the name of a Python executable, or the name of the
directory in which Python is installed.
diff --git a/gdb/aarch64-fbsd-nat.c b/gdb/aarch64-fbsd-nat.c
index 1746ad1..ecf0bb2 100644
--- a/gdb/aarch64-fbsd-nat.c
+++ b/gdb/aarch64-fbsd-nat.c
@@ -348,9 +348,7 @@ aarch64_notify_debug_reg_change (ptid_t ptid,
}
#endif
-void _initialize_aarch64_fbsd_nat ();
-void
-_initialize_aarch64_fbsd_nat ()
+INIT_GDB_FILE (aarch64_fbsd_nat)
{
#ifdef HAVE_DBREG
aarch64_initialize_hw_point ();
diff --git a/gdb/aarch64-fbsd-tdep.c b/gdb/aarch64-fbsd-tdep.c
index 07fa38a..db9b82f 100644
--- a/gdb/aarch64-fbsd-tdep.c
+++ b/gdb/aarch64-fbsd-tdep.c
@@ -239,8 +239,7 @@ aarch64_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* Generic FreeBSD support. */
fbsd_init_abi (info, gdbarch);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
tramp_frame_prepend_unwinder (gdbarch, &aarch64_fbsd_sigframe);
@@ -261,9 +260,7 @@ aarch64_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
}
}
-void _initialize_aarch64_fbsd_tdep ();
-void
-_initialize_aarch64_fbsd_tdep ()
+INIT_GDB_FILE (aarch64_fbsd_tdep)
{
gdbarch_register_osabi (bfd_arch_aarch64, 0, GDB_OSABI_FREEBSD,
aarch64_fbsd_init_abi);
diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index d7869f4..725c632 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -1068,9 +1068,7 @@ aarch64_linux_nat_target::is_address_tagged (gdbarch *gdbarch, CORE_ADDR address
return gdbarch_tagged_address_p (gdbarch, address);
}
-void _initialize_aarch64_linux_nat ();
-void
-_initialize_aarch64_linux_nat ()
+INIT_GDB_FILE (aarch64_linux_nat)
{
aarch64_initialize_hw_point ();
diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index a194ac8..dd35eaf 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -23,6 +23,7 @@
#include "extract-store-integer.h"
#include "gdbarch.h"
#include "glibc-tdep.h"
+#include "solib-svr4-linux.h"
#include "linux-tdep.h"
#include "svr4-tls-tdep.h"
#include "aarch64-tdep.h"
@@ -2768,9 +2769,7 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->lowest_pc = 0x8000;
linux_init_abi (info, gdbarch, 1);
-
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_lp64_svr4_solib_ops);
/* Enable TLS support. */
set_gdbarch_fetch_tls_load_module_address (gdbarch,
@@ -3041,9 +3040,7 @@ aarch64_linux_ltag_tests (void)
} /* namespace selftests */
#endif /* GDB_SELF_TEST */
-void _initialize_aarch64_linux_tdep ();
-void
-_initialize_aarch64_linux_tdep ()
+INIT_GDB_FILE (aarch64_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_aarch64, 0, GDB_OSABI_LINUX,
aarch64_linux_init_abi);
diff --git a/gdb/aarch64-newlib-tdep.c b/gdb/aarch64-newlib-tdep.c
index c0ecd3f..5045d5f9 100644
--- a/gdb/aarch64-newlib-tdep.c
+++ b/gdb/aarch64-newlib-tdep.c
@@ -35,9 +35,7 @@ aarch64_newlib_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->jb_pc = 11;
}
-void _initialize_aarch64_newlib_tdep ();
-void
-_initialize_aarch64_newlib_tdep ()
+INIT_GDB_FILE (aarch64_newlib_tdep)
{
gdbarch_register_osabi (bfd_arch_aarch64, 0, GDB_OSABI_NEWLIB,
aarch64_newlib_init_abi);
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 8d54e59..f2e3ce2 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -4914,9 +4914,7 @@ static void aarch64_process_record_test (void);
}
#endif
-void _initialize_aarch64_tdep ();
-void
-_initialize_aarch64_tdep ()
+INIT_GDB_FILE (aarch64_tdep)
{
gdbarch_register (bfd_arch_aarch64, aarch64_gdbarch_init,
aarch64_dump_tdep);
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 3f5e707..329d114 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -13928,9 +13928,7 @@ static const char * const gnat_source_charsets[] =
nullptr
};
-void _initialize_ada_language ();
-void
-_initialize_ada_language ()
+INIT_GDB_FILE (ada_language)
{
add_setshow_prefix_cmd
("ada", no_class,
diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c
index 2595123..f9551d4 100644
--- a/gdb/ada-tasks.c
+++ b/gdb/ada-tasks.c
@@ -1650,9 +1650,7 @@ task_apply_command (const char *tidlist, int from_tty)
from_tty, flags);
}
-void _initialize_tasks ();
-void
-_initialize_tasks ()
+INIT_GDB_FILE (tasks)
{
/* Attach various observers. */
gdb::observers::normal_stop.attach (ada_tasks_normal_stop_observer,
diff --git a/gdb/ada-typeprint.c b/gdb/ada-typeprint.c
index 404d8fe..defd828 100644
--- a/gdb/ada-typeprint.c
+++ b/gdb/ada-typeprint.c
@@ -702,7 +702,7 @@ print_variant_part (const variant_part &part,
name = "?";
else
{
- name = type->field (part.discriminant_index).name ();;
+ name = type->field (part.discriminant_index).name ();
discr_type = type->field (part.discriminant_index).type ();
}
diff --git a/gdb/addrmap.c b/gdb/addrmap.c
index c625973..4549350 100644
--- a/gdb/addrmap.c
+++ b/gdb/addrmap.c
@@ -398,20 +398,20 @@ namespace selftests {
/* Convert P to CORE_ADDR. */
static CORE_ADDR
-core_addr (void *p)
+core_addr (const void *p)
{
- return (CORE_ADDR)(uintptr_t)p;
+ return (CORE_ADDR) (uintptr_t) p;
}
/* Check that &ARRAY[LOW]..&ARRAY[HIGH] has VAL in MAP. */
-#define CHECK_ADDRMAP_FIND(MAP, ARRAY, LOW, HIGH, VAL) \
- do \
- { \
- for (unsigned i = LOW; i <= HIGH; ++i) \
- SELF_CHECK (MAP->find (core_addr (&ARRAY[i])) == VAL); \
- } \
- while (0)
+static void
+check_addrmap_find (const addrmap &map, const char *array, unsigned int low,
+ unsigned int high, const void *val)
+{
+ for (unsigned int i = low; i <= high; ++i)
+ SELF_CHECK (map.find (core_addr (&array[i])) == val);
+}
/* Entry point for addrmap unit tests. */
@@ -427,25 +427,24 @@ test_addrmap ()
/* Create mutable addrmap. */
auto_obstack temp_obstack;
- auto map = std::make_unique<struct addrmap_mutable> ();
- SELF_CHECK (map != nullptr);
+ addrmap_mutable map;
/* Check initial state. */
- CHECK_ADDRMAP_FIND (map, array, 0, 19, nullptr);
+ check_addrmap_find (map, array, 0, 19, nullptr);
/* Insert address range into mutable addrmap. */
- map->set_empty (core_addr (&array[10]), core_addr (&array[12]), val1);
- CHECK_ADDRMAP_FIND (map, array, 0, 9, nullptr);
- CHECK_ADDRMAP_FIND (map, array, 10, 12, val1);
- CHECK_ADDRMAP_FIND (map, array, 13, 19, nullptr);
+ map.set_empty (core_addr (&array[10]), core_addr (&array[12]), val1);
+ check_addrmap_find (map, array, 0, 9, nullptr);
+ check_addrmap_find (map, array, 10, 12, val1);
+ check_addrmap_find (map, array, 13, 19, nullptr);
/* Create corresponding fixed addrmap. */
addrmap_fixed *map2
- = new (&temp_obstack) addrmap_fixed (&temp_obstack, map.get ());
+ = new (&temp_obstack) addrmap_fixed (&temp_obstack, &map);
SELF_CHECK (map2 != nullptr);
- CHECK_ADDRMAP_FIND (map2, array, 0, 9, nullptr);
- CHECK_ADDRMAP_FIND (map2, array, 10, 12, val1);
- CHECK_ADDRMAP_FIND (map2, array, 13, 19, nullptr);
+ check_addrmap_find (*map2, array, 0, 9, nullptr);
+ check_addrmap_find (*map2, array, 10, 12, val1);
+ check_addrmap_find (*map2, array, 13, 19, nullptr);
/* Iterate over both addrmaps. */
auto callback = [&] (CORE_ADDR start_addr, void *obj)
@@ -460,29 +459,27 @@ test_addrmap ()
SELF_CHECK (false);
return 0;
};
- SELF_CHECK (map->foreach (callback) == 0);
+ SELF_CHECK (map.foreach (callback) == 0);
SELF_CHECK (map2->foreach (callback) == 0);
/* Relocate fixed addrmap. */
map2->relocate (1);
- CHECK_ADDRMAP_FIND (map2, array, 0, 10, nullptr);
- CHECK_ADDRMAP_FIND (map2, array, 11, 13, val1);
- CHECK_ADDRMAP_FIND (map2, array, 14, 19, nullptr);
+ check_addrmap_find (*map2, array, 0, 10, nullptr);
+ check_addrmap_find (*map2, array, 11, 13, val1);
+ check_addrmap_find (*map2, array, 14, 19, nullptr);
/* Insert partially overlapping address range into mutable addrmap. */
- map->set_empty (core_addr (&array[11]), core_addr (&array[13]), val2);
- CHECK_ADDRMAP_FIND (map, array, 0, 9, nullptr);
- CHECK_ADDRMAP_FIND (map, array, 10, 12, val1);
- CHECK_ADDRMAP_FIND (map, array, 13, 13, val2);
- CHECK_ADDRMAP_FIND (map, array, 14, 19, nullptr);
+ map.set_empty (core_addr (&array[11]), core_addr (&array[13]), val2);
+ check_addrmap_find (map, array, 0, 9, nullptr);
+ check_addrmap_find (map, array, 10, 12, val1);
+ check_addrmap_find (map, array, 13, 13, val2);
+ check_addrmap_find (map, array, 14, 19, nullptr);
}
} /* namespace selftests */
#endif /* GDB_SELF_TEST */
-void _initialize_addrmap ();
-void
-_initialize_addrmap ()
+INIT_GDB_FILE (addrmap)
{
#if GDB_SELF_TEST
selftests::register_test ("addrmap", selftests::test_addrmap);
diff --git a/gdb/agent.c b/gdb/agent.c
index 2009980..dd3a557 100644
--- a/gdb/agent.c
+++ b/gdb/agent.c
@@ -73,9 +73,7 @@ agent_new_objfile (struct objfile *objfile)
agent_look_up_symbols (objfile);
}
-void _initialize_agent ();
-void
-_initialize_agent ()
+INIT_GDB_FILE (agent)
{
gdb::observers::new_objfile.attach (agent_new_objfile,
"agent");
diff --git a/gdb/aix-thread.c b/gdb/aix-thread.c
index 2fd6121..1e3015d 100644
--- a/gdb/aix-thread.c
+++ b/gdb/aix-thread.c
@@ -2062,9 +2062,7 @@ aix_thread_target::get_ada_task_ptid (long lwp, ULONGEST thread)
/* Module startup initialization function, automagically called by
init.c. */
-void _initialize_aix_thread ();
-void
-_initialize_aix_thread ()
+INIT_GDB_FILE (aix_thread)
{
/* Notice when object files get loaded and unloaded. */
gdb::observers::new_objfile.attach (new_objfile, "aix-thread");
diff --git a/gdb/alpha-bsd-nat.c b/gdb/alpha-bsd-nat.c
index 85fb525..5f7d3ef 100644
--- a/gdb/alpha-bsd-nat.c
+++ b/gdb/alpha-bsd-nat.c
@@ -156,9 +156,7 @@ alphabsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
}
-void _initialize_alphabsd_nat ();
-void
-_initialize_alphabsd_nat ()
+INIT_GDB_FILE (alphabsd_nat)
{
add_inf_child_target (&the_alpha_bsd_nat_target);
diff --git a/gdb/alpha-linux-nat.c b/gdb/alpha-linux-nat.c
index 6d9de81..1297a45 100644
--- a/gdb/alpha-linux-nat.c
+++ b/gdb/alpha-linux-nat.c
@@ -100,9 +100,7 @@ alpha_linux_nat_target::register_u_offset (struct gdbarch *gdbarch,
return FPR_BASE + regno - gdbarch_fp0_regnum (gdbarch);
}
-void _initialize_alpha_linux_nat ();
-void
-_initialize_alpha_linux_nat ()
+INIT_GDB_FILE (alpha_linux_nat)
{
linux_target = &the_alpha_linux_nat_target;
add_inf_child_target (&the_alpha_linux_nat_target);
diff --git a/gdb/alpha-linux-tdep.c b/gdb/alpha-linux-tdep.c
index 2f6affa..8b4b4f1 100644
--- a/gdb/alpha-linux-tdep.c
+++ b/gdb/alpha-linux-tdep.c
@@ -17,6 +17,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "frame.h"
+#include "solib-svr4-linux.h"
#include "osabi.h"
#include "solib-svr4.h"
#include "symtab.h"
@@ -369,9 +370,7 @@ alpha_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->jb_elt_size = 8;
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
-
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_lp64_svr4_solib_ops);
/* Enable TLS support. */
set_gdbarch_fetch_tls_load_module_address (gdbarch,
@@ -386,9 +385,7 @@ alpha_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
alpha_linux_gdb_signal_to_target);
}
-void _initialize_alpha_linux_tdep ();
-void
-_initialize_alpha_linux_tdep ()
+INIT_GDB_FILE (alpha_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_LINUX,
alpha_linux_init_abi);
diff --git a/gdb/alpha-netbsd-tdep.c b/gdb/alpha-netbsd-tdep.c
index a240039..0f5e305 100644
--- a/gdb/alpha-netbsd-tdep.c
+++ b/gdb/alpha-netbsd-tdep.c
@@ -264,8 +264,7 @@ alphanbsd_init_abi (struct gdbarch_info info,
set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
/* NetBSD/alpha has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
tdep->dynamic_sigtramp_offset = alphanbsd_sigtramp_offset;
tdep->pc_in_sigtramp = alphanbsd_pc_in_sigtramp;
@@ -279,9 +278,7 @@ alphanbsd_init_abi (struct gdbarch_info info,
}
-void _initialize_alphanbsd_tdep ();
-void
-_initialize_alphanbsd_tdep ()
+INIT_GDB_FILE (alphanbsd_tdep)
{
/* Even though NetBSD/alpha used ELF since day one, it used the
traditional a.out-style core dump format before NetBSD 1.6, but
diff --git a/gdb/alpha-obsd-tdep.c b/gdb/alpha-obsd-tdep.c
index b5ddbbc..63f9050 100644
--- a/gdb/alpha-obsd-tdep.c
+++ b/gdb/alpha-obsd-tdep.c
@@ -109,8 +109,7 @@ alphaobsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
/* OpenBSD/alpha has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
tdep->dynamic_sigtramp_offset = alphaobsd_sigtramp_offset;
@@ -125,9 +124,7 @@ alphaobsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
}
-void _initialize_alphaobsd_tdep ();
-void
-_initialize_alphaobsd_tdep ()
+INIT_GDB_FILE (alphaobsd_tdep)
{
gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_OPENBSD,
alphaobsd_init_abi);
diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c
index f0272b0..92a6411 100644
--- a/gdb/alpha-tdep.c
+++ b/gdb/alpha-tdep.c
@@ -1815,9 +1815,7 @@ alpha_dwarf2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
}
-void _initialize_alpha_tdep ();
-void
-_initialize_alpha_tdep ()
+INIT_GDB_FILE (alpha_tdep)
{
gdbarch_register (bfd_arch_alpha, alpha_gdbarch_init, NULL);
diff --git a/gdb/amd-dbgapi-target.c b/gdb/amd-dbgapi-target.c
index 8e067b6..a0210f4 100644
--- a/gdb/amd-dbgapi-target.c
+++ b/gdb/amd-dbgapi-target.c
@@ -104,12 +104,26 @@ amd_dbgapi_lib_debug_module ()
static gdb::observers::token amd_dbgapi_target_inferior_created_observer_token;
+/* See amd-dbgapi-target.h. */
+
const gdb::observers::token &
get_amd_dbgapi_target_inferior_created_observer_token ()
{
return amd_dbgapi_target_inferior_created_observer_token;
}
+/* inferior_execd observer token. */
+
+static gdb::observers::token amd_dbgapi_target_inferior_execd_observer_token;
+
+/* See amd-dbgapi-target.h. */
+
+const gdb::observers::token &
+get_amd_dbgapi_target_inferior_execd_observer_token ()
+{
+ return amd_dbgapi_target_inferior_execd_observer_token;
+}
+
/* A type holding coordinates, etc. info for a given wave. */
struct wave_coordinates
@@ -234,7 +248,7 @@ struct amd_dbgapi_inferior_info
};
static amd_dbgapi_event_id_t process_event_queue
- (amd_dbgapi_process_id_t process_id,
+ (amd_dbgapi_inferior_info &info,
amd_dbgapi_event_kind_t until_event_kind = AMD_DBGAPI_EVENT_KIND_NONE);
static const target_info amd_dbgapi_target_info = {
@@ -443,6 +457,32 @@ async_event_handler_mark ()
mark_async_event_handler (amd_dbgapi_async_event_handler);
}
+/* Set forward progress requirement to REQUIRE for inferior INFO. */
+
+static void
+require_forward_progress (amd_dbgapi_inferior_info &info, bool require)
+{
+ /* If we try to disable forward progress requirement but the target expects
+ resumed threads to be committed to the target, we could wait for events
+ that will never arrive. */
+ if (!require)
+ gdb_assert (!info.inf->process_target ()->commit_resumed_state);
+
+ gdb_assert (info.process_id != AMD_DBGAPI_PROCESS_NONE);
+
+ /* Don't do unnecessary calls to amd-dbgapi to avoid polluting the logs. */
+ if (info.forward_progress_required == require)
+ return;
+
+ const auto progress
+ = require ? AMD_DBGAPI_PROGRESS_NORMAL : AMD_DBGAPI_PROGRESS_NO_FORWARD;
+ const auto status
+ = amd_dbgapi_process_set_progress (info.process_id, progress);
+ gdb_assert (status == AMD_DBGAPI_STATUS_SUCCESS);
+
+ info.forward_progress_required = require;
+}
+
/* Set forward progress requirement to REQUIRE for all processes of PROC_TARGET
matching PTID. */
@@ -457,21 +497,8 @@ require_forward_progress (ptid_t ptid, process_stratum_target *proc_target,
amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf);
- if (info->process_id == AMD_DBGAPI_PROCESS_NONE)
- continue;
-
- /* Don't do unnecessary calls to amd-dbgapi to avoid polluting the logs. */
- if (info->forward_progress_required == require)
- continue;
-
- amd_dbgapi_status_t status
- = amd_dbgapi_process_set_progress
- (info->process_id, (require
- ? AMD_DBGAPI_PROGRESS_NORMAL
- : AMD_DBGAPI_PROGRESS_NO_FORWARD));
- gdb_assert (status == AMD_DBGAPI_STATUS_SUCCESS);
-
- info->forward_progress_required = require;
+ if (info->process_id != AMD_DBGAPI_PROCESS_NONE)
+ require_forward_progress (*info, require);
/* If ptid targets a single inferior and we have found it, no need to
continue. */
@@ -555,11 +582,12 @@ amd_dbgapi_target_breakpoint::check_status (struct bpstat *bs)
if (action == AMD_DBGAPI_BREAKPOINT_ACTION_RESUME)
return;
+ require_forward_progress (*info, false);
+
/* If the action is AMD_DBGAPI_BREAKPOINT_ACTION_HALT, we need to wait until
a breakpoint resume event for this breakpoint_id is seen. */
amd_dbgapi_event_id_t resume_event_id
- = process_event_queue (info->process_id,
- AMD_DBGAPI_EVENT_KIND_BREAKPOINT_RESUME);
+ = process_event_queue (*info, AMD_DBGAPI_EVENT_KIND_BREAKPOINT_RESUME);
/* We should always get a breakpoint_resume event after processing all
events generated by reporting the breakpoint hit. */
@@ -1138,32 +1166,14 @@ add_gpu_thread (inferior *inf, ptid_t wave_ptid)
/* Process an event that was just pulled out of the amd-dbgapi library. */
static void
-process_one_event (amd_dbgapi_event_id_t event_id,
+process_one_event (amd_dbgapi_inferior_info &info,
+ amd_dbgapi_event_id_t event_id,
amd_dbgapi_event_kind_t event_kind)
{
/* Automatically mark this event processed when going out of scope. */
scoped_amd_dbgapi_event_processed mark_event_processed (event_id);
- amd_dbgapi_process_id_t process_id;
- amd_dbgapi_status_t status
- = amd_dbgapi_event_get_info (event_id, AMD_DBGAPI_EVENT_INFO_PROCESS,
- sizeof (process_id), &process_id);
- if (status != AMD_DBGAPI_STATUS_SUCCESS)
- error (_("event_get_info for event_%ld failed (%s)"), event_id.handle,
- get_status_string (status));
-
- amd_dbgapi_os_process_id_t pid;
- status = amd_dbgapi_process_get_info (process_id,
- AMD_DBGAPI_PROCESS_INFO_OS_ID,
- sizeof (pid), &pid);
- if (status != AMD_DBGAPI_STATUS_SUCCESS)
- error (_("process_get_info for process_%ld failed (%s)"),
- process_id.handle, get_status_string (status));
-
- auto *proc_target = current_inferior ()->process_target ();
- inferior *inf = find_inferior_pid (proc_target, pid);
- gdb_assert (inf != nullptr);
- amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf);
+ gdb_assert (info.inf != nullptr);
switch (event_kind)
{
@@ -1171,14 +1181,14 @@ process_one_event (amd_dbgapi_event_id_t event_id,
case AMD_DBGAPI_EVENT_KIND_WAVE_STOP:
{
amd_dbgapi_wave_id_t wave_id;
- status
+ amd_dbgapi_status_t status
= amd_dbgapi_event_get_info (event_id, AMD_DBGAPI_EVENT_INFO_WAVE,
sizeof (wave_id), &wave_id);
if (status != AMD_DBGAPI_STATUS_SUCCESS)
error (_("event_get_info for event_%ld failed (%s)"),
event_id.handle, get_status_string (status));
- ptid_t event_ptid = make_gpu_ptid (pid, wave_id);
+ ptid_t event_ptid = make_gpu_ptid (info.inf->pid, wave_id);
target_waitstatus ws;
amd_dbgapi_wave_stop_reasons_t stop_reason;
@@ -1219,9 +1229,10 @@ process_one_event (amd_dbgapi_event_id_t event_id,
else
ws.set_stopped (GDB_SIGNAL_0);
- thread_info *thread = proc_target->find_thread (event_ptid);
+ thread_info *thread
+ = info.inf->process_target ()->find_thread (event_ptid);
if (thread == nullptr)
- thread = add_gpu_thread (inf, event_ptid);
+ thread = add_gpu_thread (info.inf, event_ptid);
/* If the wave is stopped because of a software breakpoint, the
program counter needs to be adjusted so that it points to the
@@ -1243,7 +1254,7 @@ process_one_event (amd_dbgapi_event_id_t event_id,
error (_("wave_get_info for wave_%ld failed (%s)"),
wave_id.handle, get_status_string (status));
- info->wave_events.emplace_back (event_ptid, ws);
+ info.wave_events.emplace_back (event_ptid, ws);
break;
}
@@ -1261,7 +1272,7 @@ process_one_event (amd_dbgapi_event_id_t event_id,
When amd_dbgapi_target_breakpoint::check_status is called, the current
inferior is the inferior that hit the breakpoint, which should still be
the case now. */
- gdb_assert (inf == current_inferior ());
+ gdb_assert (info.inf == current_inferior ());
handle_solib_event ();
break;
@@ -1275,22 +1286,22 @@ process_one_event (amd_dbgapi_event_id_t event_id,
{
amd_dbgapi_runtime_state_t runtime_state;
- status = amd_dbgapi_event_get_info (event_id,
- AMD_DBGAPI_EVENT_INFO_RUNTIME_STATE,
- sizeof (runtime_state),
- &runtime_state);
+ amd_dbgapi_status_t status
+ = amd_dbgapi_event_get_info (event_id,
+ AMD_DBGAPI_EVENT_INFO_RUNTIME_STATE,
+ sizeof (runtime_state), &runtime_state);
if (status != AMD_DBGAPI_STATUS_SUCCESS)
error (_("event_get_info for event_%ld failed (%s)"),
event_id.handle, get_status_string (status));
gdb_assert (runtime_state == AMD_DBGAPI_RUNTIME_STATE_UNLOADED);
gdb_assert
- (info->runtime_state == AMD_DBGAPI_RUNTIME_STATE_LOADED_SUCCESS);
+ (info.runtime_state == AMD_DBGAPI_RUNTIME_STATE_LOADED_SUCCESS);
- info->runtime_state = runtime_state;
+ info.runtime_state = runtime_state;
- gdb_assert (inf->target_is_pushed (&the_amd_dbgapi_target));
- inf->unpush_target (&the_amd_dbgapi_target);
+ gdb_assert (info.inf->target_is_pushed (&the_amd_dbgapi_target));
+ info.inf->unpush_target (&the_amd_dbgapi_target);
}
break;
@@ -1331,20 +1342,18 @@ event_kind_str (amd_dbgapi_event_kind_t kind)
gdb_assert_not_reached ("unhandled amd_dbgapi_event_kind_t value");
}
-/* Drain the dbgapi event queue of a given process_id, or of all processes if
- process_id is AMD_DBGAPI_PROCESS_NONE. Stop processing the events if an
- event of a given kind is requested and `process_id` is not
- AMD_DBGAPI_PROCESS_NONE. Wave stop events that are not returned are queued
- into their inferior's amd_dbgapi_inferior_info pending wave events. */
+/* Drain the dbgapi event queue of a given inferior. Stop processing the
+ events if an event of a given kind is requested (not AMD_DBGAPI_EVENT_NONE).
+ Wave stop events that are not returned are queued into their inferior's
+ amd_dbgapi_inferior_info pending wave events. */
static amd_dbgapi_event_id_t
-process_event_queue (amd_dbgapi_process_id_t process_id,
+process_event_queue (amd_dbgapi_inferior_info &info,
amd_dbgapi_event_kind_t until_event_kind)
{
- /* An event of a given type can only be requested from a single
- process_id. */
- gdb_assert (until_event_kind == AMD_DBGAPI_EVENT_KIND_NONE
- || process_id != AMD_DBGAPI_PROCESS_NONE);
+ /* Pulling events with forward progress required may result in bad
+ performance, make sure it is not required. */
+ gdb_assert (!info.forward_progress_required);
while (true)
{
@@ -1352,7 +1361,7 @@ process_event_queue (amd_dbgapi_process_id_t process_id,
amd_dbgapi_event_kind_t event_kind;
amd_dbgapi_status_t status
- = amd_dbgapi_process_next_pending_event (process_id, &event_id,
+ = amd_dbgapi_process_next_pending_event (info.process_id, &event_id,
&event_kind);
if (status != AMD_DBGAPI_STATUS_SUCCESS)
@@ -1368,7 +1377,7 @@ process_event_queue (amd_dbgapi_process_id_t process_id,
if (event_id == AMD_DBGAPI_EVENT_NONE || event_kind == until_event_kind)
return event_id;
- process_one_event (event_id, event_kind);
+ process_one_event (info, event_id, event_kind);
}
}
@@ -1473,7 +1482,7 @@ amd_dbgapi_target::wait (ptid_t ptid, struct target_waitstatus *ws,
/* Drain the events for the current inferior from the amd_dbgapi and
preserve the ordering. */
auto info = get_amd_dbgapi_inferior_info (current_inferior ());
- process_event_queue (info->process_id, AMD_DBGAPI_EVENT_KIND_NONE);
+ process_event_queue (*info);
std::tie (event_ptid, gpu_waitstatus) = consume_one_event (ptid.pid ());
if (event_ptid == minus_one_ptid)
@@ -1860,13 +1869,14 @@ amd_dbgapi_target::update_thread_list ()
if (changed == AMD_DBGAPI_CHANGED_NO)
continue;
+ gdb::unique_xmalloc_ptr<amd_dbgapi_wave_id_t> wave_list_holder
+ (wave_list);
+
/* Create a set and free the wave list. */
std::set<ptid_t::tid_type> threads;
for (size_t i = 0; i < count; ++i)
threads.emplace (wave_list[i].handle);
- xfree (wave_list);
-
/* Prune the wave_ids that already have a thread_info. Any thread_info
which does not have a corresponding wave_id represents a wave which
is gone at this point and should be deleted. */
@@ -2479,10 +2489,7 @@ maybe_reset_amd_dbgapi ()
get_status_string (status));
}
-extern initialize_file_ftype _initialize_amd_dbgapi_target;
-
-void
-_initialize_amd_dbgapi_target ()
+INIT_GDB_FILE (amd_dbgapi_target)
{
/* Make sure the loaded debugger library version is greater than or equal to
the one used to build GDB. */
@@ -2510,7 +2517,9 @@ _initialize_amd_dbgapi_target ()
gdb::observers::inferior_created.attach
(amd_dbgapi_target_inferior_created,
amd_dbgapi_target_inferior_created_observer_token, "amd-dbgapi");
- gdb::observers::inferior_execd.attach (amd_dbgapi_inferior_execd, "amd-dbgapi");
+ gdb::observers::inferior_execd.attach
+ (amd_dbgapi_inferior_execd, amd_dbgapi_target_inferior_execd_observer_token,
+ "amd-dbgapi");
gdb::observers::inferior_forked.attach (amd_dbgapi_inferior_forked, "amd-dbgapi");
gdb::observers::inferior_exit.attach (amd_dbgapi_inferior_exited, "amd-dbgapi");
gdb::observers::inferior_pre_detach.attach (amd_dbgapi_inferior_pre_detach, "amd-dbgapi");
diff --git a/gdb/amd-dbgapi-target.h b/gdb/amd-dbgapi-target.h
index dd37ba3..fe3a50b 100644
--- a/gdb/amd-dbgapi-target.h
+++ b/gdb/amd-dbgapi-target.h
@@ -54,6 +54,11 @@ using is_amd_dbgapi_handle
const gdb::observers::token &
get_amd_dbgapi_target_inferior_created_observer_token ();
+/* Get the token of amd-dbgapi's inferior_execd observer. */
+
+const gdb::observers::token &
+ get_amd_dbgapi_target_inferior_execd_observer_token ();
+
/* Comparison operators for amd-dbgapi handle types. */
template <typename T,
diff --git a/gdb/amd64-darwin-tdep.c b/gdb/amd64-darwin-tdep.c
index dde023e..c687b1f 100644
--- a/gdb/amd64-darwin-tdep.c
+++ b/gdb/amd64-darwin-tdep.c
@@ -113,12 +113,10 @@ x86_darwin_init_abi_64 (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->jb_pc_offset = 56;
- set_gdbarch_so_ops (gdbarch, &darwin_so_ops);
+ set_gdbarch_make_solib_ops (gdbarch, make_darwin_solib_ops);
}
-void _initialize_amd64_darwin_tdep ();
-void
-_initialize_amd64_darwin_tdep ()
+INIT_GDB_FILE (amd64_darwin_tdep)
{
gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
GDB_OSABI_DARWIN, x86_darwin_init_abi_64);
diff --git a/gdb/amd64-dicos-tdep.c b/gdb/amd64-dicos-tdep.c
index 3e9b8c7..d7c211b 100644
--- a/gdb/amd64-dicos-tdep.c
+++ b/gdb/amd64-dicos-tdep.c
@@ -45,9 +45,7 @@ amd64_dicos_osabi_sniffer (bfd *abfd)
return GDB_OSABI_UNKNOWN;
}
-void _initialize_amd64_dicos_tdep ();
-void
-_initialize_amd64_dicos_tdep ()
+INIT_GDB_FILE (amd64_dicos_tdep)
{
gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour,
amd64_dicos_osabi_sniffer);
diff --git a/gdb/amd64-fbsd-nat.c b/gdb/amd64-fbsd-nat.c
index a783a5d1..89bb049 100644
--- a/gdb/amd64-fbsd-nat.c
+++ b/gdb/amd64-fbsd-nat.c
@@ -324,9 +324,7 @@ amd64_fbsd_nat_target::read_description ()
return i386_target_description (X86_XSTATE_SSE_MASK, true);
}
-void _initialize_amd64fbsd_nat ();
-void
-_initialize_amd64fbsd_nat ()
+INIT_GDB_FILE (amd64fbsd_nat)
{
add_inf_child_target (&the_amd64_fbsd_nat_target);
diff --git a/gdb/amd64-fbsd-tdep.c b/gdb/amd64-fbsd-tdep.c
index eea0105..12f1e22 100644
--- a/gdb/amd64-fbsd-tdep.c
+++ b/gdb/amd64-fbsd-tdep.c
@@ -328,8 +328,7 @@ amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
amd64fbsd_core_read_description);
/* FreeBSD uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
set_gdbarch_fetch_tls_load_module_address (gdbarch,
svr4_fetch_objfile_link_map);
@@ -337,9 +336,7 @@ amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
amd64fbsd_get_thread_local_address);
}
-void _initialize_amd64fbsd_tdep ();
-void
-_initialize_amd64fbsd_tdep ()
+INIT_GDB_FILE (amd64fbsd_tdep)
{
gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
GDB_OSABI_FREEBSD, amd64fbsd_init_abi);
diff --git a/gdb/amd64-gnu-tdep.c b/gdb/amd64-gnu-tdep.c
index 602fa8e..2b7337b 100644
--- a/gdb/amd64-gnu-tdep.c
+++ b/gdb/amd64-gnu-tdep.c
@@ -218,13 +218,10 @@ amd64_gnu_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->sc_num_regs = ARRAY_SIZE (amd64_gnu_sc_reg_offset);
/* Hurd uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
}
-void _initialize_amd64_gnu_tdep ();
-void
-_initialize_amd64_gnu_tdep ()
+INIT_GDB_FILE (amd64_gnu_tdep)
{
gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
GDB_OSABI_HURD, amd64_gnu_init_abi);
diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
index 75e63c6..dbb9b32 100644
--- a/gdb/amd64-linux-nat.c
+++ b/gdb/amd64-linux-nat.c
@@ -424,9 +424,7 @@ amd64_linux_nat_target::low_siginfo_fixup (siginfo_t *ptrace,
return false;
}
-void _initialize_amd64_linux_nat ();
-void
-_initialize_amd64_linux_nat ()
+INIT_GDB_FILE (amd64_linux_nat)
{
amd64_native_gregset32_reg_offset = amd64_linux_gregset32_reg_offset;
amd64_native_gregset32_num_regs = I386_LINUX_NUM_REGS;
diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
index e5a2ab9..13e9c0e 100644
--- a/gdb/amd64-linux-tdep.c
+++ b/gdb/amd64-linux-tdep.c
@@ -33,6 +33,7 @@
#include "amd64-linux-tdep.h"
#include "i386-linux-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "svr4-tls-tdep.h"
#include "gdbsupport/x86-xstate.h"
#include "inferior.h"
@@ -2130,8 +2131,7 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->i386_syscall_record = amd64_linux_syscall_record;
/* GNU/Linux uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_lp64_svr4_solib_ops);
/* Register DTrace handlers. */
set_gdbarch_dtrace_parse_probe_argument (gdbarch, amd64_dtrace_parse_probe_argument);
@@ -2344,13 +2344,10 @@ amd64_x32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->i386_syscall_record = amd64_x32_linux_syscall_record;
/* GNU/Linux uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
}
-void _initialize_amd64_linux_tdep ();
-void
-_initialize_amd64_linux_tdep ()
+INIT_GDB_FILE (amd64_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
GDB_OSABI_LINUX, amd64_linux_init_abi);
diff --git a/gdb/amd64-netbsd-nat.c b/gdb/amd64-netbsd-nat.c
index 92ad4b2..c960b3c 100644
--- a/gdb/amd64-netbsd-nat.c
+++ b/gdb/amd64-netbsd-nat.c
@@ -55,9 +55,7 @@ static int amd64nbsd32_r_reg_offset[] =
static amd64_bsd_nat_target<nbsd_nat_target> the_amd64_nbsd_nat_target;
-void _initialize_amd64nbsd_nat ();
-void
-_initialize_amd64nbsd_nat ()
+INIT_GDB_FILE (amd64nbsd_nat)
{
amd64_native_gregset32_reg_offset = amd64nbsd32_r_reg_offset;
amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64nbsd32_r_reg_offset);
diff --git a/gdb/amd64-netbsd-tdep.c b/gdb/amd64-netbsd-tdep.c
index f4464b7..3dbbdd9 100644
--- a/gdb/amd64-netbsd-tdep.c
+++ b/gdb/amd64-netbsd-tdep.c
@@ -116,13 +116,10 @@ amd64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->sc_num_regs = ARRAY_SIZE (amd64nbsd_r_reg_offset);
/* NetBSD uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
}
-void _initialize_amd64nbsd_tdep ();
-void
-_initialize_amd64nbsd_tdep ()
+INIT_GDB_FILE (amd64nbsd_tdep)
{
/* The NetBSD/amd64 native dependent code makes this assumption. */
gdb_assert (ARRAY_SIZE (amd64nbsd_r_reg_offset) == AMD64_NUM_GREGS);
diff --git a/gdb/amd64-obsd-nat.c b/gdb/amd64-obsd-nat.c
index 93d38df..8471520 100644
--- a/gdb/amd64-obsd-nat.c
+++ b/gdb/amd64-obsd-nat.c
@@ -127,9 +127,7 @@ amd64obsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
static amd64_bsd_nat_target<obsd_nat_target> the_amd64_obsd_nat_target;
-void _initialize_amd64obsd_nat ();
-void
-_initialize_amd64obsd_nat ()
+INIT_GDB_FILE (amd64obsd_nat)
{
amd64_native_gregset32_reg_offset = amd64obsd32_r_reg_offset;
amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64obsd32_r_reg_offset);
diff --git a/gdb/amd64-obsd-tdep.c b/gdb/amd64-obsd-tdep.c
index 5acc380..6b60e0a 100644
--- a/gdb/amd64-obsd-tdep.c
+++ b/gdb/amd64-obsd-tdep.c
@@ -443,16 +443,13 @@ amd64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
bsd_uthread_set_collect_uthread (gdbarch, amd64obsd_collect_uthread);
/* OpenBSD uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
/* Unwind kernel trap frames correctly. */
frame_unwind_prepend_unwinder (gdbarch, &amd64obsd_trapframe_unwind);
}
-void _initialize_amd64obsd_tdep ();
-void
-_initialize_amd64obsd_tdep ()
+INIT_GDB_FILE (amd64obsd_tdep)
{
/* The OpenBSD/amd64 native dependent code makes this assumption. */
gdb_assert (ARRAY_SIZE (amd64obsd_r_reg_offset) == AMD64_NUM_GREGS);
diff --git a/gdb/amd64-sol2-tdep.c b/gdb/amd64-sol2-tdep.c
index 84d5f87..da551a1 100644
--- a/gdb/amd64-sol2-tdep.c
+++ b/gdb/amd64-sol2-tdep.c
@@ -96,13 +96,10 @@ amd64_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->sc_num_regs = tdep->gregset_num_regs;
/* Solaris uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
}
-void _initialize_amd64_sol2_tdep ();
-void
-_initialize_amd64_sol2_tdep ()
+INIT_GDB_FILE (amd64_sol2_tdep)
{
gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
GDB_OSABI_SOLARIS, amd64_sol2_init_abi);
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index e495778..82dd1e0 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -2129,6 +2129,30 @@ amd64_alloc_frame_cache (void)
return cache;
}
+/* Check whether PC is at "endbr64" instruction. If so, return PC past it.
+ Otherwise, return PC passed to this function. */
+
+static CORE_ADDR
+amd64_skip_endbr (gdbarch *gdbarch, CORE_ADDR pc)
+{
+ static const gdb_byte endbr64[4] = { 0xf3, 0x0f, 0x1e, 0xfa };
+
+ bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ gdb_byte buf[3];
+ gdb_byte op = read_code_unsigned_integer (pc, 1, byte_order);
+
+ /* Check for the `endbr64` instruction, skip it if found. */
+ if (op == endbr64[0])
+ {
+ read_code (pc + 1, buf, 3);
+
+ if (memcmp (buf, &endbr64[1], 3) == 0)
+ return pc + 4;
+ }
+
+ return pc;
+}
+
/* GCC 4.4 and later, can put code in the prologue to realign the
stack pointer. Check whether PC points to such code, and update
CACHE accordingly. Return the first instruction after the code
@@ -2466,35 +2490,18 @@ amd64_x32_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc,
return std::min (pc + offset + 2, current_pc);
}
-/* Do a limited analysis of the prologue at PC and update CACHE
- accordingly. Bail out early if CURRENT_PC is reached. Return the
- address where the analysis stopped.
-
- We will handle only functions beginning with:
-
- pushq %rbp 0x55
- movq %rsp, %rbp 0x48 0x89 0xe5 (or 0x48 0x8b 0xec)
-
- or (for the X32 ABI):
-
- pushq %rbp 0x55
- movl %esp, %ebp 0x89 0xe5 (or 0x8b 0xec)
-
- The `endbr64` instruction can be found before these sequences, and will be
- skipped if found.
+/* Analyze frame setup instructions at PC on behalf of amd64_analyze_prologue
+ and update CACHE accordingly. Bail out early if CURRENT_PC is reached.
+ Return the address where the analysis stopped.
- Any function that doesn't start with one of these sequences will be
- assumed to have no prologue and thus no valid frame pointer in
- %rbp. */
+ See comment on amd64_analyze_prologue for the sequences handled. The
+ movq/movl after the push of %rbp is considered optional. 'endbr64' is
+ handled before this function. */
static CORE_ADDR
-amd64_analyze_prologue (struct gdbarch *gdbarch,
- CORE_ADDR pc, CORE_ADDR current_pc,
- struct amd64_frame_cache *cache)
+amd64_analyze_frame_setup (gdbarch *gdbarch, CORE_ADDR pc,
+ CORE_ADDR current_pc, amd64_frame_cache *cache)
{
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- /* The `endbr64` instruction. */
- static const gdb_byte endbr64[4] = { 0xf3, 0x0f, 0x1e, 0xfa };
/* There are two variations of movq %rsp, %rbp. */
static const gdb_byte mov_rsp_rbp_1[3] = { 0x48, 0x89, 0xe5 };
static const gdb_byte mov_rsp_rbp_2[3] = { 0x48, 0x8b, 0xec };
@@ -2502,34 +2509,11 @@ amd64_analyze_prologue (struct gdbarch *gdbarch,
static const gdb_byte mov_esp_ebp_1[2] = { 0x89, 0xe5 };
static const gdb_byte mov_esp_ebp_2[2] = { 0x8b, 0xec };
+ bfd_endian byte_order = gdbarch_byte_order (gdbarch);
gdb_byte buf[3];
- gdb_byte op;
-
- if (current_pc <= pc)
- return current_pc;
-
- if (gdbarch_ptr_bit (gdbarch) == 32)
- pc = amd64_x32_analyze_stack_align (pc, current_pc, cache);
- else
- pc = amd64_analyze_stack_align (pc, current_pc, cache);
-
- op = read_code_unsigned_integer (pc, 1, byte_order);
-
- /* Check for the `endbr64` instruction, skip it if found. */
- if (op == endbr64[0])
- {
- read_code (pc + 1, buf, 3);
-
- if (memcmp (buf, &endbr64[1], 3) == 0)
- pc += 4;
-
- op = read_code_unsigned_integer (pc, 1, byte_order);
- }
-
- if (current_pc <= pc)
- return current_pc;
+ gdb_byte op = read_code_unsigned_integer (pc, 1, byte_order);
- if (op == 0x55) /* pushq %rbp */
+ if (op == 0x55) /* pushq %rbp. */
{
/* Take into account that we've executed the `pushq %rbp' that
starts this instruction sequence. */
@@ -2569,6 +2553,50 @@ amd64_analyze_prologue (struct gdbarch *gdbarch,
return pc;
}
+/* Do a limited analysis of the prologue at PC and update CACHE
+ accordingly. Bail out early if CURRENT_PC is reached. Return the
+ address where the analysis stopped.
+
+ We will handle only functions beginning with:
+
+ pushq %rbp 0x55
+ movq %rsp, %rbp 0x48 0x89 0xe5 (or 0x48 0x8b 0xec)
+
+ or (for the X32 ABI):
+
+ pushq %rbp 0x55
+ movl %esp, %ebp 0x89 0xe5 (or 0x8b 0xec)
+
+ The `endbr64` instruction can be found before these sequences, and will be
+ skipped if found.
+
+ Any function that doesn't start with one of these sequences will be
+ assumed to have no prologue and thus no valid frame pointer in
+ %rbp. */
+
+static CORE_ADDR
+amd64_analyze_prologue (gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR current_pc,
+ amd64_frame_cache *cache)
+{
+ if (current_pc <= pc)
+ return current_pc;
+
+ /* If generated, 'endbr64' will be placed before stack alignment too. */
+ pc = amd64_skip_endbr (gdbarch, pc);
+ if (current_pc <= pc)
+ return current_pc;
+
+ if (gdbarch_ptr_bit (gdbarch) == 32)
+ pc = amd64_x32_analyze_stack_align (pc, current_pc, cache);
+ else
+ pc = amd64_analyze_stack_align (pc, current_pc, cache);
+
+ if (current_pc <= pc)
+ return current_pc;
+
+ return amd64_analyze_frame_setup (gdbarch, pc, current_pc, cache);
+}
+
/* Work around false termination of prologue - GCC PR debug/48827.
START_PC is the first instruction of a function, PC is its minimal already
@@ -3740,9 +3768,7 @@ amd64_insn_decode (void)
} // namespace selftests
#endif /* GDB_SELF_TEST */
-void _initialize_amd64_tdep ();
-void
-_initialize_amd64_tdep ()
+INIT_GDB_FILE (amd64_tdep)
{
gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, GDB_OSABI_NONE,
amd64_none_init_abi);
diff --git a/gdb/amd64-windows-nat.c b/gdb/amd64-windows-nat.c
index 223e078..f5c98f6 100644
--- a/gdb/amd64-windows-nat.c
+++ b/gdb/amd64-windows-nat.c
@@ -94,9 +94,7 @@ amd64_windows_segment_register_p (int regnum)
return regnum >= AMD64_CS_REGNUM && regnum <= AMD64_GS_REGNUM;
}
-void _initialize_amd64_windows_nat ();
-void
-_initialize_amd64_windows_nat ()
+INIT_GDB_FILE (amd64_windows_nat)
{
x86_set_debug_register_length (8);
}
diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c
index c4719dc..c7977d2 100644
--- a/gdb/amd64-windows-tdep.c
+++ b/gdb/amd64-windows-tdep.c
@@ -1404,9 +1404,7 @@ amd64_cygwin_core_osabi_sniffer (bfd *abfd)
return GDB_OSABI_UNKNOWN;
}
-void _initialize_amd64_windows_tdep ();
-void
-_initialize_amd64_windows_tdep ()
+INIT_GDB_FILE (amd64_windows_tdep)
{
gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, GDB_OSABI_WINDOWS,
amd64_windows_init_abi);
diff --git a/gdb/amdgpu-tdep.c b/gdb/amdgpu-tdep.c
index dc1b32f..26e5a27 100644
--- a/gdb/amdgpu-tdep.c
+++ b/gdb/amdgpu-tdep.c
@@ -1371,10 +1371,7 @@ amdgpu_register_type_parse_test ()
#endif
-void _initialize_amdgpu_tdep ();
-
-void
-_initialize_amdgpu_tdep ()
+INIT_GDB_FILE (amdgpu_tdep)
{
gdbarch_register (bfd_arch_amdgcn, amdgpu_gdbarch_init, NULL,
amdgpu_supports_arch_info);
diff --git a/gdb/annotate.c b/gdb/annotate.c
index ea0bfa9..55db2e2 100644
--- a/gdb/annotate.c
+++ b/gdb/annotate.c
@@ -627,9 +627,7 @@ breakpoint_changed (struct breakpoint *b)
annotate_breakpoints_invalid ();
}
-void _initialize_annotate ();
-void
-_initialize_annotate ()
+INIT_GDB_FILE (annotate)
{
gdb::observers::breakpoint_created.attach (breakpoint_changed, "annotate");
gdb::observers::breakpoint_deleted.attach (breakpoint_changed, "annotate");
diff --git a/gdb/arc-linux-nat.c b/gdb/arc-linux-nat.c
index 091a966..75fc4b7 100644
--- a/gdb/arc-linux-nat.c
+++ b/gdb/arc-linux-nat.c
@@ -309,9 +309,7 @@ ps_get_thread_area (struct ps_prochandle *ph, lwpid_t lwpid, int idx,
}
/* Suppress warning from -Wmissing-prototypes. */
-void _initialize_arc_linux_nat ();
-void
-_initialize_arc_linux_nat ()
+INIT_GDB_FILE (arc_linux_nat)
{
/* Register the target. */
linux_target = &the_arc_linux_nat_target;
diff --git a/gdb/arc-linux-tdep.c b/gdb/arc-linux-tdep.c
index adf6691..edbb3f8 100644
--- a/gdb/arc-linux-tdep.c
+++ b/gdb/arc-linux-tdep.c
@@ -19,6 +19,7 @@
/* GDB header files. */
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "objfiles.h"
#include "opcode/arc.h"
#include "osabi.h"
@@ -736,15 +737,10 @@ arc_linux_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* GNU/Linux uses SVR4-style shared libraries, with 32-bit ints, longs
and pointers (ILP32). */
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
}
-/* Suppress warning from -Wmissing-prototypes. */
-extern initialize_file_ftype _initialize_arc_linux_tdep;
-
-void
-_initialize_arc_linux_tdep ()
+INIT_GDB_FILE (arc_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_arc, 0, GDB_OSABI_LINUX,
arc_linux_init_osabi);
diff --git a/gdb/arc-newlib-tdep.c b/gdb/arc-newlib-tdep.c
index fd80bfa..9a6f7a8 100644
--- a/gdb/arc-newlib-tdep.c
+++ b/gdb/arc-newlib-tdep.c
@@ -58,9 +58,7 @@ arc_newlib_osabi_sniffer (bfd *abfd)
return GDB_OSABI_UNKNOWN;
}
-void _initialize_arc_newlib_tdep ();
-void
-_initialize_arc_newlib_tdep ()
+INIT_GDB_FILE (arc_newlib_tdep)
{
gdbarch_register_osabi_sniffer (bfd_arch_arc, bfd_target_elf_flavour,
arc_newlib_osabi_sniffer);
diff --git a/gdb/arc-tdep.c b/gdb/arc-tdep.c
index 8db6e7b..f5ae11c 100644
--- a/gdb/arc-tdep.c
+++ b/gdb/arc-tdep.c
@@ -2458,9 +2458,7 @@ dump_arc_instruction_command (const char *args, int from_tty)
arc_insn_dump (insn);
}
-void _initialize_arc_tdep ();
-void
-_initialize_arc_tdep ()
+INIT_GDB_FILE (arc_tdep)
{
gdbarch_register (bfd_arch_arc, arc_gdbarch_init, arc_dump_tdep);
diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c
index be0494f..f320d3d 100644
--- a/gdb/arch-utils.c
+++ b/gdb/arch-utils.c
@@ -1525,9 +1525,7 @@ core_file_exec_context::environment () const
return e;
}
-void _initialize_gdbarch_utils ();
-void
-_initialize_gdbarch_utils ()
+INIT_GDB_FILE (gdbarch_utils)
{
add_setshow_enum_cmd ("endian", class_support,
endian_enum, &set_endian_string,
diff --git a/gdb/arm-fbsd-nat.c b/gdb/arm-fbsd-nat.c
index 2b7b75a..e068023 100644
--- a/gdb/arm-fbsd-nat.c
+++ b/gdb/arm-fbsd-nat.c
@@ -104,9 +104,7 @@ arm_fbsd_nat_target::read_description ()
return desc;
}
-void _initialize_arm_fbsd_nat ();
-void
-_initialize_arm_fbsd_nat ()
+INIT_GDB_FILE (arm_fbsd_nat)
{
add_inf_child_target (&the_arm_fbsd_nat_target);
}
diff --git a/gdb/arm-fbsd-tdep.c b/gdb/arm-fbsd-tdep.c
index c9a466f..a37d8b7 100644
--- a/gdb/arm-fbsd-tdep.c
+++ b/gdb/arm-fbsd-tdep.c
@@ -300,8 +300,7 @@ arm_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tramp_frame_prepend_unwinder (gdbarch, &arm_fbsd_sigframe);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
tdep->jb_pc = 24;
tdep->jb_elt_size = 4;
@@ -322,9 +321,7 @@ arm_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
}
-void _initialize_arm_fbsd_tdep ();
-void
-_initialize_arm_fbsd_tdep ()
+INIT_GDB_FILE (arm_fbsd_tdep)
{
gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_FREEBSD,
arm_fbsd_init_abi);
diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c
index 3ff9fc6..813da8c 100644
--- a/gdb/arm-linux-nat.c
+++ b/gdb/arm-linux-nat.c
@@ -1393,9 +1393,7 @@ arm_linux_nat_target::low_new_fork (struct lwp_info *parent, pid_t child_pid)
*child_state = *parent_state;
}
-void _initialize_arm_linux_nat ();
-void
-_initialize_arm_linux_nat ()
+INIT_GDB_FILE (arm_linux_nat)
{
/* Register the target. */
linux_target = &the_arm_linux_nat_target;
diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c
index 485a5d9..08526d8 100644
--- a/gdb/arm-linux-tdep.c
+++ b/gdb/arm-linux-tdep.c
@@ -41,6 +41,7 @@
#include "arm-tdep.h"
#include "arm-linux-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "glibc-tdep.h"
#include "arch-utils.h"
#include "inferior.h"
@@ -1801,8 +1802,7 @@ arm_linux_init_abi (struct gdbarch_info info,
}
tdep->jb_elt_size = ARM_LINUX_JB_ELEMENT_SIZE;
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
/* Single stepping. */
set_gdbarch_software_single_step (gdbarch, arm_linux_software_single_step);
@@ -2026,9 +2026,7 @@ arm_linux_init_abi (struct gdbarch_info info,
set_gdbarch_gcc_target_options (gdbarch, arm_linux_gcc_target_options);
}
-void _initialize_arm_linux_tdep ();
-void
-_initialize_arm_linux_tdep ()
+INIT_GDB_FILE (arm_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_LINUX,
arm_linux_init_abi);
diff --git a/gdb/arm-netbsd-nat.c b/gdb/arm-netbsd-nat.c
index 3a24f51..ebf4084 100644
--- a/gdb/arm-netbsd-nat.c
+++ b/gdb/arm-netbsd-nat.c
@@ -354,9 +354,7 @@ arm_netbsd_nat_target::read_description ()
return arm_read_description (ARM_FP_TYPE_VFPV3, false);
}
-void _initialize_arm_netbsd_nat ();
-void
-_initialize_arm_netbsd_nat ()
+INIT_GDB_FILE (arm_netbsd_nat)
{
add_inf_child_target (&the_arm_netbsd_nat_target);
}
diff --git a/gdb/arm-netbsd-tdep.c b/gdb/arm-netbsd-tdep.c
index a162054..82ba0c6 100644
--- a/gdb/arm-netbsd-tdep.c
+++ b/gdb/arm-netbsd-tdep.c
@@ -156,13 +156,10 @@ arm_netbsd_elf_init_abi (struct gdbarch_info info,
tdep->fp_model = ARM_FLOAT_SOFT_VFP;
/* NetBSD ELF uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
}
-void _initialize_arm_netbsd_tdep ();
-void
-_initialize_arm_netbsd_tdep ()
+INIT_GDB_FILE (arm_netbsd_tdep)
{
gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_NETBSD,
arm_netbsd_elf_init_abi);
diff --git a/gdb/arm-none-tdep.c b/gdb/arm-none-tdep.c
index 81db22f..3ffcd2b 100644
--- a/gdb/arm-none-tdep.c
+++ b/gdb/arm-none-tdep.c
@@ -204,9 +204,7 @@ arm_none_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* Initialize ARM bare-metal target support. */
-void _initialize_arm_none_tdep ();
-void
-_initialize_arm_none_tdep ()
+INIT_GDB_FILE (arm_none_tdep)
{
gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_NONE,
arm_none_init_abi);
diff --git a/gdb/arm-obsd-tdep.c b/gdb/arm-obsd-tdep.c
index 6fd4c85..00e4bfd 100644
--- a/gdb/arm-obsd-tdep.c
+++ b/gdb/arm-obsd-tdep.c
@@ -83,8 +83,7 @@ armobsd_init_abi (struct gdbarch_info info,
tramp_frame_prepend_unwinder (gdbarch, &armobsd_sigframe);
/* OpenBSD/arm uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
tdep->jb_pc = 24;
@@ -114,9 +113,7 @@ armobsd_init_abi (struct gdbarch_info info,
}
}
-void _initialize_armobsd_tdep ();
-void
-_initialize_armobsd_tdep ()
+INIT_GDB_FILE (armobsd_tdep)
{
gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_OPENBSD,
armobsd_init_abi);
diff --git a/gdb/arm-pikeos-tdep.c b/gdb/arm-pikeos-tdep.c
index 428bb7d..12fd9c3 100644
--- a/gdb/arm-pikeos-tdep.c
+++ b/gdb/arm-pikeos-tdep.c
@@ -73,9 +73,7 @@ arm_pikeos_osabi_sniffer (bfd *abfd)
return GDB_OSABI_UNKNOWN;
}
-void _initialize_arm_pikeos_tdep ();
-void
-_initialize_arm_pikeos_tdep ()
+INIT_GDB_FILE (arm_pikeos_tdep)
{
/* Register the sniffer for the PikeOS targets. */
gdbarch_register_osabi_sniffer (bfd_arch_arm, bfd_target_elf_flavour,
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 5450056..a764825 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -1669,7 +1669,7 @@ arm_analyze_load_stack_chk_guard(CORE_ADDR pc, struct gdbarch *gdbarch,
ldr Rn, .Label
....
- .Lable:
+ .Label:
.word __stack_chk_guard
Since ldr/str is a very popular instruction, we can't use them as
@@ -11015,9 +11015,7 @@ static void arm_analyze_prologue_test ();
}
#endif
-void _initialize_arm_tdep ();
-void
-_initialize_arm_tdep ()
+INIT_GDB_FILE (arm_tdep)
{
long length;
int i, j;
diff --git a/gdb/arm-wince-tdep.c b/gdb/arm-wince-tdep.c
index b1e1304..b9ea59c 100644
--- a/gdb/arm-wince-tdep.c
+++ b/gdb/arm-wince-tdep.c
@@ -152,9 +152,7 @@ arm_wince_osabi_sniffer (bfd *abfd)
return GDB_OSABI_UNKNOWN;
}
-void _initialize_arm_wince_tdep ();
-void
-_initialize_arm_wince_tdep ()
+INIT_GDB_FILE (arm_wince_tdep)
{
gdbarch_register_osabi_sniffer (bfd_arch_arm, bfd_target_coff_flavour,
arm_wince_osabi_sniffer);
diff --git a/gdb/auto-load.c b/gdb/auto-load.c
index f33a8d0..114a7d5 100644
--- a/gdb/auto-load.c
+++ b/gdb/auto-load.c
@@ -1568,9 +1568,7 @@ found and/or loaded."),
gdb::observers::token auto_load_new_objfile_observer_token;
-void _initialize_auto_load ();
-void
-_initialize_auto_load ()
+INIT_GDB_FILE (auto_load)
{
struct cmd_list_element *cmd;
gdb::unique_xmalloc_ptr<char> scripts_directory_help, gdb_name_help,
diff --git a/gdb/auxv.c b/gdb/auxv.c
index 5ec39ea..06e2fb0 100644
--- a/gdb/auxv.c
+++ b/gdb/auxv.c
@@ -609,9 +609,7 @@ info_auxv_command (const char *cmd, int from_tty)
}
}
-void _initialize_auxv ();
-void
-_initialize_auxv ()
+INIT_GDB_FILE (auxv)
{
add_info ("auxv", info_auxv_command,
_("Display the inferior's auxiliary vector.\n\
diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c
index 36e6ec4..6274529 100644
--- a/gdb/avr-tdep.c
+++ b/gdb/avr-tdep.c
@@ -1629,9 +1629,7 @@ avr_io_reg_read_command (const char *args, int from_tty)
}
}
-void _initialize_avr_tdep ();
-void
-_initialize_avr_tdep ()
+INIT_GDB_FILE (avr_tdep)
{
gdbarch_register (bfd_arch_avr, avr_gdbarch_init);
diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
index e572465..08f542c 100644
--- a/gdb/ax-gdb.c
+++ b/gdb/ax-gdb.c
@@ -2634,9 +2634,7 @@ maint_agent_printf_command (const char *cmdrest, int from_tty)
/* Initialization code. */
-void _initialize_ax_gdb ();
-void
-_initialize_ax_gdb ()
+INIT_GDB_FILE (ax_gdb)
{
add_cmd ("agent", class_maintenance, maint_agent_command,
_("\
diff --git a/gdb/bfin-linux-tdep.c b/gdb/bfin-linux-tdep.c
index 3ba3146..d84f800 100644
--- a/gdb/bfin-linux-tdep.c
+++ b/gdb/bfin-linux-tdep.c
@@ -161,9 +161,7 @@ bfin_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
bfin_linux_get_syscall_number);
}
-void _initialize_bfin_linux_tdep ();
-void
-_initialize_bfin_linux_tdep ()
+INIT_GDB_FILE (bfin_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_bfin, 0, GDB_OSABI_LINUX,
bfin_linux_init_abi);
diff --git a/gdb/bfin-tdep.c b/gdb/bfin-tdep.c
index 32d9371..3a96e9f 100644
--- a/gdb/bfin-tdep.c
+++ b/gdb/bfin-tdep.c
@@ -837,9 +837,7 @@ bfin_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
return gdbarch;
}
-void _initialize_bfin_tdep ();
-void
-_initialize_bfin_tdep ()
+INIT_GDB_FILE (bfin_tdep)
{
gdbarch_register (bfd_arch_bfin, bfin_gdbarch_init);
}
diff --git a/gdb/block.c b/gdb/block.c
index fdf209c..1866c0f 100644
--- a/gdb/block.c
+++ b/gdb/block.c
@@ -924,9 +924,7 @@ maintenance_info_blocks (const char *arg, int from_tty)
-void _initialize_block ();
-void
-_initialize_block ()
+INIT_GDB_FILE (block)
{
add_cmd ("blocks", class_maintenance, maintenance_info_blocks,
_("\
diff --git a/gdb/bpf-tdep.c b/gdb/bpf-tdep.c
index 2c95607..be01e8b 100644
--- a/gdb/bpf-tdep.c
+++ b/gdb/bpf-tdep.c
@@ -368,9 +368,7 @@ bpf_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
return gdbarch;
}
-void _initialize_bpf_tdep ();
-void
-_initialize_bpf_tdep ()
+INIT_GDB_FILE (bpf_tdep)
{
gdbarch_register (bfd_arch_bpf, bpf_gdbarch_init);
diff --git a/gdb/break-catch-exec.c b/gdb/break-catch-exec.c
index 6716437..570018c 100644
--- a/gdb/break-catch-exec.c
+++ b/gdb/break-catch-exec.c
@@ -213,9 +213,7 @@ catch_exec_command_1 (const char *arg, int from_tty,
install_breakpoint (0, std::move (c), 1);
}
-void _initialize_break_catch_exec ();
-void
-_initialize_break_catch_exec ()
+INIT_GDB_FILE (break_catch_exec)
{
add_catch_command ("exec", _("Catch calls to exec."),
catch_exec_command_1,
diff --git a/gdb/break-catch-fork.c b/gdb/break-catch-fork.c
index cba3753..c8a6330 100644
--- a/gdb/break-catch-fork.c
+++ b/gdb/break-catch-fork.c
@@ -242,9 +242,7 @@ catch_fork_command_1 (const char *arg, int from_tty,
}
}
-void _initialize_break_catch_fork ();
-void
-_initialize_break_catch_fork ()
+INIT_GDB_FILE (break_catch_fork)
{
add_catch_command ("fork", _("Catch calls to fork."),
catch_fork_command_1,
diff --git a/gdb/break-catch-load.c b/gdb/break-catch-load.c
index 5e290fd..594884e 100644
--- a/gdb/break-catch-load.c
+++ b/gdb/break-catch-load.c
@@ -24,7 +24,7 @@
#include "cli/cli-decode.h"
#include "mi/mi-common.h"
#include "progspace.h"
-#include "solist.h"
+#include "solib.h"
#include "target.h"
#include "valprint.h"
@@ -119,7 +119,7 @@ solib_catchpoint::check_status (struct bpstat *bs)
for (solib *iter : current_program_space->added_solibs)
{
if (!regex
- || compiled->exec (iter->so_name.c_str (), 0, nullptr, 0) == 0)
+ || compiled->exec (iter->name.c_str (), 0, nullptr, 0) == 0)
return;
}
}
@@ -264,9 +264,7 @@ catch_unload_command_1 (const char *arg, int from_tty,
catch_load_or_unload (arg, from_tty, 0, command);
}
-void _initialize_break_catch_load ();
-void
-_initialize_break_catch_load ()
+INIT_GDB_FILE (break_catch_load)
{
add_catch_command ("load", _("Catch loads of shared libraries.\n\
Usage: catch load [REGEX]\n\
diff --git a/gdb/break-catch-sig.c b/gdb/break-catch-sig.c
index fb5d202..adfc48f 100644
--- a/gdb/break-catch-sig.c
+++ b/gdb/break-catch-sig.c
@@ -409,9 +409,7 @@ catch_signal_command (const char *arg, int from_tty,
create_signal_catchpoint (tempflag, std::move (filter), catch_all);
}
-void _initialize_break_catch_sig ();
-void
-_initialize_break_catch_sig ()
+INIT_GDB_FILE (break_catch_sig)
{
add_catch_command ("signal", _("\
Catch signals by their names and/or numbers.\n\
diff --git a/gdb/break-catch-syscall.c b/gdb/break-catch-syscall.c
index 348ff41..63bfec6 100644
--- a/gdb/break-catch-syscall.c
+++ b/gdb/break-catch-syscall.c
@@ -423,7 +423,7 @@ catch_syscall_command_1 (const char *arg, int from_tty,
struct syscall s;
struct gdbarch *gdbarch = get_current_arch ();
- /* Checking if the feature if supported. */
+ /* Checking if the feature is supported. */
if (gdbarch_get_syscall_number_p (gdbarch) == 0)
error (_("The feature 'catch syscall' is not supported on \
this architecture yet."));
@@ -570,9 +570,7 @@ clear_syscall_counts (struct inferior *inf)
inf_data->syscalls_counts.clear ();
}
-void _initialize_break_catch_syscall ();
-void
-_initialize_break_catch_syscall ()
+INIT_GDB_FILE (break_catch_syscall)
{
gdb::observers::inferior_exit.attach (clear_syscall_counts,
"break-catch-syscall");
diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c
index 41213e4..cb682a6 100644
--- a/gdb/break-catch-throw.c
+++ b/gdb/break-catch-throw.c
@@ -499,9 +499,7 @@ static const struct internalvar_funcs exception_funcs =
-void _initialize_break_catch_throw ();
-void
-_initialize_break_catch_throw ()
+INIT_GDB_FILE (break_catch_throw)
{
/* Add catch and tcatch sub-commands. */
add_catch_command ("catch", _("\
diff --git a/gdb/break-cond-parse.c b/gdb/break-cond-parse.c
index 705f4f6..04a8895 100644
--- a/gdb/break-cond-parse.c
+++ b/gdb/break-cond-parse.c
@@ -569,10 +569,10 @@ test (const char *input, const char *condition, int thread = -1,
gdb::unique_xmalloc_ptr<char> extracted_rest;
int extracted_thread, extracted_inferior, extracted_task;
bool extracted_force_condition;
- std::string exception_msg, error_str;
+ std::string exception_msg;
- if (error_msg != nullptr)
- error_str = std::string (error_msg) + "\n";
+ if (error_msg == nullptr)
+ error_msg = "";
try
{
@@ -584,10 +584,7 @@ test (const char *input, const char *condition, int thread = -1,
}
catch (const gdb_exception_error &ex)
{
- string_file buf;
-
- exception_print (&buf, ex);
- exception_msg = buf.release ();
+ exception_msg = ex.what ();
}
if ((condition == nullptr) != (extracted_condition.get () == nullptr)
@@ -599,7 +596,7 @@ test (const char *input, const char *condition, int thread = -1,
|| inferior != extracted_inferior
|| task != extracted_task
|| force != extracted_force_condition
- || exception_msg != error_str)
+ || exception_msg != error_msg)
{
if (run_verbose ())
{
@@ -687,9 +684,7 @@ create_breakpoint_parse_arg_string_tests ()
} /* namespace selftests */
#endif /* GDB_SELF_TEST */
-void _initialize_break_cond_parse ();
-void
-_initialize_break_cond_parse ()
+INIT_GDB_FILE (break_cond_parse)
{
#if GDB_SELF_TEST
selftests::register_test
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index f44ac45..d704ad1 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -50,7 +50,6 @@
#include "cli/cli-script.h"
#include "block.h"
#include "solib.h"
-#include "solist.h"
#include "observable.h"
#include "memattr.h"
#include "ada-lang.h"
@@ -255,14 +254,22 @@ DIAGNOSTIC_POP
static std::string
breakpoint_location_address_str (const bp_location *bl)
{
- std::string str = string_printf ("Breakpoint %d (%s) at address %s",
+ std::string str = string_printf ("Breakpoint %d (%s) ",
bl->owner->number,
- host_address_to_string (bl),
- paddress (bl->gdbarch, bl->address));
+ host_address_to_string (bl));
- std::string loc_string = bl->to_string ();
- if (!loc_string.empty ())
- str += string_printf (" %s", loc_string.c_str ());
+ if (bl_address_is_meaningful (bl))
+ {
+ gdb_assert (bl->gdbarch != nullptr);
+ str += string_printf ("at address %s",
+ paddress (bl->gdbarch, bl->address));
+
+ std::string loc_string = bl->to_string ();
+ if (!loc_string.empty ())
+ str += string_printf (" %s", loc_string.c_str ());
+ }
+ else
+ str += "with dummy location";
return str;
}
@@ -721,7 +728,8 @@ all_tracepoints ()
tracepoint_iterator (breakpoint_chain.end ()));
}
-/* Array is sorted by bp_location_is_less_than - primarily by the ADDRESS. */
+/* Array is sorted by bp_location_ptr_is_less_than - primarily by the
+ ADDRESS. */
static std::vector<bp_location *> bp_locations;
@@ -5136,7 +5144,7 @@ print_solib_event (bool is_catchpoint)
if (!first)
current_uiout->text (" ");
first = false;
- current_uiout->field_string ("library", iter->so_name);
+ current_uiout->field_string ("library", iter->name);
current_uiout->text ("\n");
}
}
@@ -7504,7 +7512,7 @@ breakpoint_locations_match (const struct bp_location *loc1,
else
/* We compare bp_location.length in order to cover ranged
breakpoints. Keep this in sync with
- bp_location_is_less_than. */
+ bp_location_ptr_is_less_than. */
return (breakpoint_address_match (loc1->pspace->aspace.get (),
loc1->address,
loc2->pspace->aspace.get (),
@@ -8144,7 +8152,7 @@ disable_breakpoints_in_unloaded_shlib (program_space *pspace, const solib &solib
target_terminal::ours_for_output ();
warning (_("Temporarily disabling breakpoints "
"for unloaded shared library \"%s\""),
- solib.so_name.c_str ());
+ solib.name.c_str ());
disabled_shlib_breaks = true;
}
}
@@ -11205,14 +11213,17 @@ breakpoint_auto_delete (bpstat *bs)
delete_breakpoint (&b);
}
-/* A comparison function for bp_location AP and BP being interfaced to
- std::sort. Sort elements primarily by their ADDRESS (no matter what
- bl_address_is_meaningful says), secondarily by ordering first
- permanent elements and tertiarily just ensuring the array is sorted
- stable way despite std::sort being an unstable algorithm. */
+/* A comparison function for bp_location pointers A and B being interfaced to
+ std::sort, for instance to sort an std::vector<bp_location *>. Sort
+ elements:
+ - primarily by their ADDRESS (no matter what bl_address_is_meaningful
+ says),
+ - secondarily by ordering first permanent elements, and
+ - tertiarily just ensuring the array is sorted in a stable way despite
+ std::sort being an unstable algorithm. */
-static int
-bp_location_is_less_than (const bp_location *a, const bp_location *b)
+static bool
+bp_location_ptr_is_less_than (const bp_location *a, const bp_location *b)
{
if (a->address != b->address)
return a->address < b->address;
@@ -11250,6 +11261,15 @@ bp_location_is_less_than (const bp_location *a, const bp_location *b)
return a < b;
}
+/* A comparison function for bp_locations A and B being interfaced to
+ std::sort, for instance to sort an std::vector<bp_location>. */
+
+static bool
+bp_location_is_less_than (const bp_location &a, const bp_location &b)
+{
+ return bp_location_ptr_is_less_than (&a, &b);
+}
+
/* Set bp_locations_placed_address_before_address_max and
bp_locations_shadow_len_after_address_max according to the current
content of the bp_locations array. */
@@ -11455,7 +11475,7 @@ update_global_location_list (enum ugll_insert_mode insert_mode)
handle_automatic_hardware_breakpoints (loc);
std::sort (bp_locations.begin (), bp_locations.end (),
- bp_location_is_less_than);
+ bp_location_ptr_is_less_than);
bp_locations_target_extensions_update ();
@@ -11903,9 +11923,7 @@ breakpoint::add_location (bp_location &loc)
auto ub = std::upper_bound (m_locations.begin (), m_locations.end (),
loc,
- [] (const bp_location &left,
- const bp_location &right)
- { return left.address < right.address; });
+ bp_location_is_less_than);
m_locations.insert (ub, loc);
}
@@ -14747,9 +14765,7 @@ static struct cmd_list_element *enablebreaklist = NULL;
cmd_list_element *commands_cmd_element = nullptr;
-void _initialize_breakpoint ();
-void
-_initialize_breakpoint ()
+INIT_GDB_FILE (breakpoint)
{
struct cmd_list_element *c;
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index 6b421f2..9341112 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -425,7 +425,9 @@ public:
simplicity is more important than memory usage for breakpoints. */
/* Architecture associated with this location's address. May be
- different from the breakpoint architecture. */
+ different from the breakpoint architecture. Not every location has
+ an address (e.g. see add_dummy_location), so not every location has
+ an associated gdbarch -- this can be NULL for a valid location. */
struct gdbarch *gdbarch = NULL;
/* The program space associated with this breakpoint location
diff --git a/gdb/bsd-uthread.c b/gdb/bsd-uthread.c
index 341aea9..4509376 100644
--- a/gdb/bsd-uthread.c
+++ b/gdb/bsd-uthread.c
@@ -25,7 +25,6 @@
#include "observable.h"
#include "regcache.h"
#include "solib.h"
-#include "solist.h"
#include "symfile.h"
#include "target.h"
@@ -280,13 +279,13 @@ bsd_uthread_solib_loaded (solib &so)
for (names = bsd_uthread_solib_names; *names; names++)
{
- if (startswith (so.so_original_name, *names))
+ if (startswith (so.original_name, *names))
{
solib_read_symbols (so, 0);
if (bsd_uthread_activate (so.objfile))
{
- bsd_uthread_solib_name = so.so_original_name;
+ bsd_uthread_solib_name = so.original_name;
return;
}
}
@@ -300,7 +299,7 @@ bsd_uthread_solib_unloaded (program_space *pspace, const solib &so,
if (bsd_uthread_solib_name.empty () || still_in_use)
return;
- if (so.so_original_name == bsd_uthread_solib_name)
+ if (so.original_name == bsd_uthread_solib_name)
bsd_uthread_deactivate ();
}
@@ -541,9 +540,7 @@ bsd_uthread_target::pid_to_str (ptid_t ptid)
return normal_pid_to_str (ptid);
}
-void _initialize_bsd_uthread ();
-void
-_initialize_bsd_uthread ()
+INIT_GDB_FILE (bsd_uthread)
{
gdb::observers::inferior_created.attach (bsd_uthread_inferior_created,
"bsd-uthread");
diff --git a/gdb/btrace.c b/gdb/btrace.c
index 3d883c5..b23de88 100644
--- a/gdb/btrace.c
+++ b/gdb/btrace.c
@@ -3501,9 +3501,7 @@ show_maint_btrace_pt_skip_pad (struct ui_file *file, int from_tty,
/* Initialize btrace maintenance commands. */
-void _initialize_btrace ();
-void
-_initialize_btrace ()
+INIT_GDB_FILE (btrace)
{
add_cmd ("btrace", class_maintenance, maint_info_btrace_cmd,
_("Info about branch tracing data."), &maintenanceinfolist);
diff --git a/gdb/build-id.c b/gdb/build-id.c
index 02602af..0ecd79f 100644
--- a/gdb/build-id.c
+++ b/gdb/build-id.c
@@ -29,6 +29,7 @@
#include "gdbsupport/scoped_fd.h"
#include "debuginfod-support.h"
#include "extension.h"
+#include "inferior.h"
/* See build-id.h. */
@@ -128,8 +129,9 @@ build_id_to_debug_bfd_1 (const std::string &original_link,
if (supports_target_stat != TRIBOOL_FALSE)
{
struct stat sb;
- int res = target_fileio_stat (nullptr, link_on_target, &sb,
- &target_errno);
+ int res = target_fileio_lstat (current_inferior (),
+ link_on_target, &sb,
+ &target_errno);
if (res != 0 && target_errno != FILEIO_ENOSYS)
{
@@ -157,7 +159,7 @@ build_id_to_debug_bfd_1 (const std::string &original_link,
the path doesn't exist, but we just assume that anything
other than EINVAL indicates the path doesn't exist. */
std::optional<std::string> link_target
- = target_fileio_readlink (nullptr, link_on_target,
+ = target_fileio_readlink (current_inferior (), link_on_target,
&target_errno);
if (link_target.has_value ()
|| target_errno == FILEIO_EINVAL)
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index f53a138..14d4b70 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -3042,10 +3042,6 @@ classify_name (struct parser_state *par_state, const struct block *block,
std::string copy = copy_name (yylval.sval);
- /* Initialize this in case we *don't* use it in this call; that way
- we can refer to it unconditionally below. */
- memset (&is_a_field_of_this, 0, sizeof (is_a_field_of_this));
-
bsym = lookup_symbol (copy.c_str (), block, SEARCH_VFT,
par_state->language ()->name_of_this ()
? &is_a_field_of_this : NULL);
@@ -3396,18 +3392,18 @@ c_parse (struct parser_state *par_state)
c_parse_state cstate;
scoped_restore cstate_restore = make_scoped_restore (&cpstate, &cstate);
- gdb::unique_xmalloc_ptr<struct macro_scope> macro_scope;
+ macro_scope macro_scope;
if (par_state->expression_context_block)
macro_scope
= sal_macro_scope (find_pc_line (par_state->expression_context_pc, 0));
else
macro_scope = default_macro_scope ();
- if (! macro_scope)
+ if (!macro_scope.is_valid ())
macro_scope = user_macro_scope ();
scoped_restore restore_macro_scope
- = make_scoped_restore (&expression_macro_scope, macro_scope.get ());
+ = make_scoped_restore (&expression_macro_scope, &macro_scope);
scoped_restore restore_yydebug = make_scoped_restore (&yydebug,
par_state->debug);
diff --git a/gdb/charset.c b/gdb/charset.c
index 3e37ec9..2593625 100644
--- a/gdb/charset.c
+++ b/gdb/charset.c
@@ -983,9 +983,7 @@ intermediate_encoding (void)
#endif /* USE_INTERMEDIATE_ENCODING_FUNCTION */
-void _initialize_charset ();
-void
-_initialize_charset ()
+INIT_GDB_FILE (charset)
{
/* The first element is always "auto". */
charsets.charsets.push_back (xstrdup ("auto"));
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index 9a5021f..5e887f5 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -952,6 +952,21 @@ shell_command (const char *arg, int from_tty)
shell_escape (arg, from_tty);
}
+/* Completion for the shell command. Currently, this just uses filename
+ completion, but we could, potentially, complete command names from $PATH
+ for the first word, which would make this even more shell like. */
+
+static void
+shell_command_completer (struct cmd_list_element *ignore,
+ completion_tracker &tracker,
+ const char *text, const char * /* word */)
+{
+ tracker.set_use_custom_word_point (true);
+ const char *word
+ = advance_to_filename_maybe_quoted_complete_word_point (tracker, text);
+ filename_maybe_quoted_completer (ignore, tracker, text, word);
+}
+
static void
edit_command (const char *arg, int from_tty)
{
@@ -1178,8 +1193,32 @@ pipe_command_completer (struct cmd_list_element *ignore,
return;
}
- /* We're past the delimiter. What follows is a shell command, which
- we don't know how to complete. */
+ /* We're past the delimiter now, or at least, DELIM points to the
+ delimiter string. Update TEXT to point to the start of whatever
+ appears after the delimiter. */
+ text = skip_spaces (delim + strlen (delimiter));
+
+ /* We really are past the delimiter now, so offer completions. This is
+ like GDB's "shell" command, currently we only offer filename
+ completion, but in the future this could be improved by offering
+ completion of command names from $PATH.
+
+ What we don't do here is offer completions for the empty string. It
+ is assumed that the first word after the delimiter is going to be a
+ command name from $PATH, not a filename, so if the user has typed
+ nothing (yet) and tries to complete, there's no point offering a list
+ of files from the current directory.
+
+ Once the user has started to type something though, then we do start
+ offering filename completions. */
+ if (*text == '\0')
+ return;
+
+ tracker.set_use_custom_word_point (true);
+ tracker.advance_custom_word_point_by (text - org_text);
+ const char *word
+ = advance_to_filename_maybe_quoted_complete_word_point (tracker, text);
+ filename_maybe_quoted_completer (ignore, tracker, text, word);
}
/* Helper for the list_command function. Prints the lines around (and
@@ -2578,9 +2617,7 @@ shell_internal_fn (struct gdbarch *gdbarch,
return value::allocate_optimized_out (int_type);
}
-void _initialize_cli_cmds ();
-void
-_initialize_cli_cmds ()
+INIT_GDB_FILE (cli_cmds)
{
struct cmd_list_element *c;
@@ -2803,7 +2840,7 @@ the previous command number shown."),
= add_com ("shell", class_support, shell_command, _("\
Execute the rest of the line as a shell command.\n\
With no arguments, run an inferior shell."));
- set_cmd_completer (shell_cmd, deprecated_filename_completer);
+ set_cmd_completer_handle_brkchars (shell_cmd, shell_command_completer);
add_com_alias ("!", shell_cmd, class_support, 0);
diff --git a/gdb/cli/cli-dump.c b/gdb/cli/cli-dump.c
index 3055734..afbbea6 100644
--- a/gdb/cli/cli-dump.c
+++ b/gdb/cli/cli-dump.c
@@ -564,9 +564,7 @@ restore_command (const char *args, int from_tty)
}
}
-void _initialize_cli_dump ();
-void
-_initialize_cli_dump ()
+INIT_GDB_FILE (cli_dump)
{
struct cmd_list_element *c;
diff --git a/gdb/cli/cli-interp.c b/gdb/cli/cli-interp.c
index 32ba9d9..d7b73df 100644
--- a/gdb/cli/cli-interp.c
+++ b/gdb/cli/cli-interp.c
@@ -321,9 +321,7 @@ cli_interp_factory (const char *name)
/* Standard gdb initialization hook. */
-void _initialize_cli_interp ();
-void
-_initialize_cli_interp ()
+INIT_GDB_FILE (cli_interp)
{
interp_factory_register (INTERP_CONSOLE, cli_interp_factory);
}
diff --git a/gdb/cli/cli-logging.c b/gdb/cli/cli-logging.c
index d225533..d6eb6c2 100644
--- a/gdb/cli/cli-logging.c
+++ b/gdb/cli/cli-logging.c
@@ -202,9 +202,7 @@ show_logging_enabled (struct ui_file *file, int from_tty,
gdb_printf (file, _("off: Logging is disabled.\n"));
}
-void _initialize_cli_logging ();
-void
-_initialize_cli_logging ()
+INIT_GDB_FILE (cli_logging)
{
static struct cmd_list_element *set_logging_cmdlist, *show_logging_cmdlist;
diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c
index bdbf850..3ea80a5 100644
--- a/gdb/cli/cli-script.c
+++ b/gdb/cli/cli-script.c
@@ -1751,9 +1751,7 @@ show_user_1 (struct cmd_list_element *c, const char *prefix, const char *name,
}
-void _initialize_cli_script ();
-void
-_initialize_cli_script ()
+INIT_GDB_FILE (cli_script)
{
struct cmd_list_element *c;
diff --git a/gdb/cli/cli-style.c b/gdb/cli/cli-style.c
index e644127..d6829f0 100644
--- a/gdb/cli/cli-style.c
+++ b/gdb/cli/cli-style.c
@@ -494,9 +494,7 @@ print_error_prefix (ui_file *file)
gdb_puts (error_prefix.c_str (), file);
}
-void _initialize_cli_style ();
-void
-_initialize_cli_style ()
+INIT_GDB_FILE (cli_style)
{
add_setshow_prefix_cmd ("style", no_class,
_("\
diff --git a/gdb/coff-pe-read.c b/gdb/coff-pe-read.c
index 3a3611e..0061007 100644
--- a/gdb/coff-pe-read.c
+++ b/gdb/coff-pe-read.c
@@ -694,9 +694,7 @@ show_debug_coff_pe_read (struct ui_file *file, int from_tty,
/* Adds "Set/show debug coff_pe_read" commands. */
-void _initialize_coff_pe_read ();
-void
-_initialize_coff_pe_read ()
+INIT_GDB_FILE (coff_pe_read)
{
add_setshow_zuinteger_cmd ("coff-pe-read", class_maintenance,
&debug_coff_pe_read,
diff --git a/gdb/coffread.c b/gdb/coffread.c
index 8a87e9c..db18c43 100644
--- a/gdb/coffread.c
+++ b/gdb/coffread.c
@@ -2248,9 +2248,7 @@ static const struct sym_fns coff_sym_fns =
NULL, /* sym_probe_fns */
};
-void _initialize_coffread ();
-void
-_initialize_coffread ()
+INIT_GDB_FILE (coffread)
{
add_symtab_fns (bfd_target_coff_flavour, &coff_sym_fns);
diff --git a/gdb/compile/compile-c-support.c b/gdb/compile/compile-c-support.c
index 0d32350..ac8888f 100644
--- a/gdb/compile/compile-c-support.c
+++ b/gdb/compile/compile-c-support.c
@@ -185,18 +185,18 @@ static void
write_macro_definitions (const struct block *block, CORE_ADDR pc,
struct ui_file *file)
{
- gdb::unique_xmalloc_ptr<struct macro_scope> scope;
+ macro_scope scope;
if (block != NULL)
scope = sal_macro_scope (find_pc_line (pc, 0));
else
scope = default_macro_scope ();
- if (scope == NULL)
+ if (!scope.is_valid ())
scope = user_macro_scope ();
- if (scope != NULL && scope->file != NULL && scope->file->table != NULL)
+ if (scope.is_valid () && scope.file->table != nullptr)
{
- macro_for_each_in_scope (scope->file, scope->line,
+ macro_for_each_in_scope (scope.file, scope.line,
[&] (const char *name,
const macro_definition *macro,
macro_source_file *source,
diff --git a/gdb/compile/compile-cplus-types.c b/gdb/compile/compile-cplus-types.c
index 56ef033..cf70fe4 100644
--- a/gdb/compile/compile-cplus-types.c
+++ b/gdb/compile/compile-cplus-types.c
@@ -1395,9 +1395,7 @@ gcc_cp_plugin::pop_binding_level (const char *debug_name)
return pop_binding_level ();
}
-void _initialize_compile_cplus_types ();
-void
-_initialize_compile_cplus_types ()
+INIT_GDB_FILE (compile_cplus_types)
{
add_setshow_boolean_cmd ("compile-cplus-types", no_class,
&debug_compile_cplus_types, _("\
diff --git a/gdb/compile/compile.c b/gdb/compile/compile.c
index ab4cb0b..229e155 100644
--- a/gdb/compile/compile.c
+++ b/gdb/compile/compile.c
@@ -868,9 +868,7 @@ compile_command (const char *args, int from_tty)
/* See compile.h. */
cmd_list_element *compile_cmd_element = nullptr;
-void _initialize_compile ();
-void
-_initialize_compile ()
+INIT_GDB_FILE (compile)
{
compile_cmd_element = add_prefix_cmd ("compile", class_obscure,
compile_command,
diff --git a/gdb/complaints.c b/gdb/complaints.c
index 2f58af2..3c7f9bc 100644
--- a/gdb/complaints.c
+++ b/gdb/complaints.c
@@ -188,9 +188,7 @@ test_complaints ()
} /* namespace selftests */
#endif /* GDB_SELF_TEST */
-void _initialize_complaints ();
-void
-_initialize_complaints ()
+INIT_GDB_FILE (complaints)
{
add_setshow_zinteger_cmd ("complaints", class_support,
&stop_whining, _("\
diff --git a/gdb/completer.c b/gdb/completer.c
index 658a0c6..0d68e76 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -3513,9 +3513,7 @@ skip_over_slash_fmt (completion_tracker &tracker, const char **args)
return false;
}
-void _initialize_completer ();
-void
-_initialize_completer ()
+INIT_GDB_FILE (completer)
{
/* Setup some readline completion globals. */
rl_completion_word_break_hook = gdb_completion_word_break_characters;
diff --git a/gdb/config.in b/gdb/config.in
index 426947e..149aeaf 100644
--- a/gdb/config.in
+++ b/gdb/config.in
@@ -39,6 +39,9 @@
/* Define to BFD's default target vector. */
#undef DEFAULT_BFD_VEC
+/* defined if dwarf format was requested. */
+#undef DWARF_FORMAT_AVAILABLE
+
/* Handle .ctf type-info sections */
#undef ENABLE_LIBCTF
@@ -93,6 +96,9 @@
/* Define if amd-dbgapi is being linked in. */
#undef HAVE_AMD_DBGAPI
+/* Define to 1 if you have the <asm/termios.h> header file. */
+#undef HAVE_ASM_TERMIOS_H
+
/* Define to 1 if you have the `btowc' function. */
#undef HAVE_BTOWC
@@ -244,6 +250,9 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
+/* Define to 1 if you have the <IOKit/serial/ioss.h> header file. */
+#undef HAVE_IOKIT_SERIAL_IOSS_H
+
/* Define to 1 if you have the `kinfo_getfile' function. */
#undef HAVE_KINFO_GETFILE
@@ -639,6 +648,9 @@
*/
#undef LT_OBJDIR
+/* defined if mdebug format was requested. */
+#undef MDEBUG_FORMAT_AVAILABLE
+
/* Name of this package. */
#undef PACKAGE
diff --git a/gdb/configure b/gdb/configure
index 5ee1982..8fc3b04 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -932,6 +932,8 @@ with_relocated_sources
with_auto_load_dir
with_auto_load_safe_path
enable_targets
+enable_gdb_mdebug_support
+enable_gdb_dwarf_support
with_amd_dbgapi
enable_tui
enable_gdbtk
@@ -1643,6 +1645,12 @@ Optional Features:
--disable-nls do not use Native Language Support
--enable-targets=TARGETS
alternative target configurations
+ --enable-gdb-mdebug-support
+ Enable support for the mdebug debuginfo format
+ (default 'yes')
+ --enable-gdb-dwarf-support
+ Enable support for the dwarf debuginfo format
+ (default 'yes')
--enable-tui enable full-screen terminal user interface (TUI)
--enable-gdbtk enable gdbtk graphical user interface (GUI)
--enable-profiling enable profiling of GDB
@@ -11499,7 +11507,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11502 "configure"
+#line 11510 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11605,7 +11613,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11608 "configure"
+#line 11616 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -24875,6 +24883,56 @@ fi
+# Check whether to support mdebug/ecoff debug information.
+# Check whether --enable-gdb-mdebug-support was given.
+if test "${enable_gdb_mdebug_support+set}" = set; then :
+ enableval=$enable_gdb_mdebug_support;
+ case $enableval in
+ yes | no)
+ ;;
+ *)
+ as_fn_error $? "bad value $enableval for --enable-gdb-mdebug-support" "$LINENO" 5
+ ;;
+ esac
+
+else
+ enable_gdb_mdebug_support=yes
+fi
+
+
+if test "x${enable_gdb_mdebug_support}" != "xno"; then
+ CONFIG_SRCS="$CONFIG_SRCS mdebugread.c"
+ CONFIG_OBS="$CONFIG_OBS mdebugread.o"
+
+$as_echo "#define MDEBUG_FORMAT_AVAILABLE 1" >>confdefs.h
+
+fi
+
+# Check whether to support dwarf debug information
+# Check whether --enable-gdb-dwarf-support was given.
+if test "${enable_gdb_dwarf_support+set}" = set; then :
+ enableval=$enable_gdb_dwarf_support;
+ case $enableval in
+ yes | no)
+ ;;
+ *)
+ as_fn_error $? "bad value $enableval for --enable-gdb-dwarf-support" "$LINENO" 5
+ ;;
+ esac
+
+else
+ enable_gdb_dwarf_support=yes
+fi
+
+
+if test "x${enable_gdb_dwarf_support}" != "xno"; then
+
+$as_echo "#define DWARF_FORMAT_AVAILABLE 1" >>confdefs.h
+
+ CONFIG_SRCS="$CONFIG_SRCS \$(DWARF2_SRCS)"
+ CONFIG_OBS="$CONFIG_OBS \$(DWARF2_OBS)"
+fi
+
# See whether 64-bit bfd lib has been enabled.
OLD_CPPFLAGS=$CPPFLAGS
# Put the old CPPFLAGS last, in case the user's CPPFLAGS point somewhere
@@ -28167,8 +28225,8 @@ int
main ()
{
- #if PY_MAJOR_VERSION != 3
- # error "We only support Python 3"
+ #if PY_VERSION_HEX < 0x03040000
+ # error "Minimum supported Python version is 3.4"
#endif
Py_Initialize ();
@@ -28944,11 +29002,20 @@ if test "${enable_gdb_compile+set}" = set; then :
esac
else
- enable_gdb_compile=yes
+ enable_gdb_compile=default
fi
-if test "${enable_gdb_compile}" = yes; then
+if test "${enable_gdb_compile}" = "default"; then
+ enable_gdb_compile=${enable_gdb_dwarf_support}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Defaulting compile support to '${enable_gdb_dwarf_support}'" >&5
+$as_echo "$as_me: WARNING: Defaulting compile support to '${enable_gdb_dwarf_support}'" >&2;}
+fi
+
+if test "${enable_gdb_compile}" = "yes"; then
+ if test "${enable_gdb_dwarf_support}" = "no"; then
+ as_fn_error $? "enabling gdb compile requires dwarf support" "$LINENO" 5
+ fi
$as_echo "#define HAVE_COMPILE 1" >>confdefs.h
@@ -29196,6 +29263,8 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.h
fi
for ac_header in \
+ IOKit/serial/ioss.h \
+ asm/termios.h \
machine/reg.h \
nlist.h \
ptrace.h \
@@ -31616,7 +31685,7 @@ if test "$gdb_cv_var_elf" = yes; then
$as_echo "#define HAVE_ELF 1" >>confdefs.h
- # -ldl is provided by bfd/Makfile.am (LIBDL) <PLUGINS>.
+ # -ldl is provided by bfd/Makefile.am (LIBDL) <PLUGINS>.
if test "$plugins" = "yes"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5
$as_echo_n "checking for library containing dlopen... " >&6; }
diff --git a/gdb/configure.ac b/gdb/configure.ac
index 5870a61..226e27e 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -192,6 +192,34 @@ AS_HELP_STRING([--enable-targets=TARGETS], [alternative target configurations]),
esac])
+# Check whether to support mdebug/ecoff debug information.
+AC_ARG_ENABLE(gdb-mdebug-support,
+AS_HELP_STRING([--enable-gdb-mdebug-support],
+ [Enable support for the mdebug debuginfo format (default 'yes')]),
+[GDB_CHECK_YES_NO_VAL([$enableval], [--enable-gdb-mdebug-support])],
+[enable_gdb_mdebug_support=yes])
+
+if test "x${enable_gdb_mdebug_support}" != "xno"; then
+ CONFIG_SRCS="$CONFIG_SRCS mdebugread.c"
+ CONFIG_OBS="$CONFIG_OBS mdebugread.o"
+ AC_DEFINE(MDEBUG_FORMAT_AVAILABLE, 1,
+ [defined if mdebug format was requested.])
+fi
+
+# Check whether to support dwarf debug information
+AC_ARG_ENABLE(gdb-dwarf-support,
+AS_HELP_STRING([--enable-gdb-dwarf-support],
+ [Enable support for the dwarf debuginfo format (default 'yes')]),
+[GDB_CHECK_YES_NO_VAL([$enableval], [--enable-gdb-dwarf-support])],
+[enable_gdb_dwarf_support=yes])
+
+if test "x${enable_gdb_dwarf_support}" != "xno"; then
+ AC_DEFINE(DWARF_FORMAT_AVAILABLE, 1,
+ [defined if dwarf format was requested.])
+ CONFIG_SRCS="$CONFIG_SRCS \$(DWARF2_SRCS)"
+ CONFIG_OBS="$CONFIG_OBS \$(DWARF2_OBS)"
+fi
+
BFD_64_BIT
# Provide defaults for some variables set by the per-host and per-target
@@ -740,8 +768,8 @@ AC_DEFUN([AC_TRY_LIBPYTHON],
found_usable_python=no
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include "Python.h"]],
[[
- #if PY_MAJOR_VERSION != 3
- # error "We only support Python 3"
+ #if PY_VERSION_HEX < 0x03040000
+ # error "Minimum supported Python version is 3.4"
#endif
Py_Initialize ();
]])],
@@ -1220,9 +1248,17 @@ AC_ARG_ENABLE([gdb-compile],
AS_HELP_STRING([--enable-gdb-compile],
[enable support for the compile subsystem, default 'yes']),
[GDB_CHECK_YES_NO_VAL([$enableval], [--enable-gdb-compile])],
- [enable_gdb_compile=yes])
+ [enable_gdb_compile=default])
-if test "${enable_gdb_compile}" = yes; then
+if test "${enable_gdb_compile}" = "default"; then
+ enable_gdb_compile=${enable_gdb_dwarf_support}
+ AC_MSG_WARN([Defaulting compile support to '${enable_gdb_dwarf_support}'])
+fi
+
+if test "${enable_gdb_compile}" = "yes"; then
+ if test "${enable_gdb_dwarf_support}" = "no"; then
+ AC_MSG_ERROR([enabling gdb compile requires dwarf support])
+ fi
AC_DEFINE(HAVE_COMPILE, 1, [Define if compiling support to gdb compile.])
CONFIG_OBS="$CONFIG_OBS \$(SUBDIR_GCC_COMPILE_OBS)"
else
@@ -1321,6 +1357,8 @@ AC_SUBST(SRCHIGH_CFLAGS)
AC_HEADER_STDC
AC_CHECK_HEADERS([ \
+ IOKit/serial/ioss.h \
+ asm/termios.h \
machine/reg.h \
nlist.h \
ptrace.h \
@@ -1922,7 +1960,7 @@ if test "$gdb_cv_var_elf" = yes; then
gcore-elf.o elf-none-tdep.o"
AC_DEFINE(HAVE_ELF, 1,
[Define if ELF support should be included.])
- # -ldl is provided by bfd/Makfile.am (LIBDL) <PLUGINS>.
+ # -ldl is provided by bfd/Makefile.am (LIBDL) <PLUGINS>.
if test "$plugins" = "yes"; then
AC_SEARCH_LIBS(dlopen, dl)
fi
diff --git a/gdb/configure.tgt b/gdb/configure.tgt
index e9b3068..255c77e 100644
--- a/gdb/configure.tgt
+++ b/gdb/configure.tgt
@@ -150,14 +150,15 @@ aarch64*-*-linux*)
arch/aarch64-scalable-linux.o \
arch/arm.o arch/arm-linux.o arch/arm-get-next-pcs.o \
arm-tdep.o arm-linux-tdep.o \
- glibc-tdep.o linux-tdep.o solib-svr4.o svr4-tls-tdep.o \
+ glibc-tdep.o linux-tdep.o solib-svr4.o \
+ solib-svr4-linux.o svr4-tls-tdep.o \
symfile-mem.o linux-record.o"
;;
alpha*-*-linux*)
# Target: Little-endian Alpha running Linux
gdb_target_obs="alpha-mdebug-tdep.o alpha-linux-tdep.o \
- linux-tdep.o solib-svr4.o"
+ linux-tdep.o solib-svr4.o solib-svr4-linux.o"
;;
alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu)
# Target: NetBSD/alpha
@@ -179,7 +180,7 @@ amdgcn*-*-*)
am33_2.0*-*-linux*)
# Target: Matsushita mn10300 (AM33) running Linux
gdb_target_obs="mn10300-tdep.o mn10300-linux-tdep.o linux-tdep.o \
- solib-svr4.o"
+ solib-svr4.o solib-svr4-linux.o"
;;
arc*-*-elf32)
@@ -189,7 +190,8 @@ arc*-*-elf32)
arc*-*-linux*)
# Target: ARC machine running Linux
- gdb_target_obs="arc-linux-tdep.o linux-tdep.o solib-svr4.o"
+ gdb_target_obs="arc-linux-tdep.o linux-tdep.o solib-svr4.o \
+ solib-svr4-linux.o"
;;
arm*-wince-pe | arm*-*-mingw32ce*)
@@ -199,7 +201,8 @@ arm*-wince-pe | arm*-*-mingw32ce*)
arm*-*-linux*)
# Target: ARM based machine running GNU/Linux
gdb_target_obs="arch/arm-linux.o arm-linux-tdep.o glibc-tdep.o \
- solib-svr4.o symfile-mem.o linux-tdep.o linux-record.o"
+ solib-svr4.o solib-svr4-linux.o symfile-mem.o \
+ linux-tdep.o linux-record.o"
;;
arm*-*-freebsd*)
# Target: FreeBSD/arm
@@ -239,13 +242,14 @@ bpf-*-*)
cris*)
# Target: CRIS
- gdb_target_obs="cris-tdep.o cris-linux-tdep.o linux-tdep.o solib-svr4.o"
+ gdb_target_obs="cris-tdep.o cris-linux-tdep.o linux-tdep.o \
+ solib-svr4.o solib-svr4-linux.o"
;;
csky*-*-linux*)
# Target: CSKY running GNU/Linux
gdb_target_obs="csky-tdep.o csky-linux-tdep.o glibc-tdep.o \
- linux-tdep.o solib-svr4.o"
+ linux-tdep.o solib-svr4.o solib-svr4-linux.o"
;;
csky*-*-*)
@@ -270,7 +274,8 @@ h8300-*-*)
hppa*-*-linux*)
# Target: HP PA-RISC running Linux
gdb_target_obs="hppa-linux-tdep.o glibc-tdep.o \
- linux-tdep.o solib-svr4.o symfile-mem.o"
+ linux-tdep.o solib-svr4.o solib-svr4-linux.o \
+ symfile-mem.o"
;;
hppa*-*-netbsd*)
# Target: NetBSD/hppa
@@ -315,7 +320,7 @@ i[34567]86-*-linux*)
# Target: Intel 386 running GNU/Linux
gdb_target_obs="i386-linux-tdep.o \
glibc-tdep.o \
- solib-svr4.o symfile-mem.o \
+ solib-svr4.o solib-svr4-linux.o symfile-mem.o \
linux-tdep.o linux-record.o \
arch/i386-linux-tdesc.o \
arch/x86-linux-tdesc-features.o"
@@ -345,7 +350,7 @@ i[34567]86-*-go32* | i[34567]86-*-msdosdjgpp*)
ia64-*-linux*)
# Target: Intel IA-64 running GNU/Linux
gdb_target_obs="ia64-linux-tdep.o linux-tdep.o \
- solib-svr4.o symfile-mem.o"
+ solib-svr4.o solib-svr4-linux.o symfile-mem.o"
;;
ia64-*-*vms*)
# Target: Intel IA-64 running OpenVMS
@@ -363,7 +368,8 @@ lm32-*-*)
loongarch*-*-linux*)
# Target: LoongArch running Linux
gdb_target_obs="loongarch-linux-tdep.o glibc-tdep.o \
- linux-tdep.o solib-svr4.o linux-record.o"
+ linux-tdep.o solib-svr4.o solib-svr4-linux.o \
+ linux-record.o"
;;
m32c-*-*)
@@ -374,8 +380,8 @@ m32c-*-*)
m32r*-*-linux*)
# Target: Renesas M32R running GNU/Linux
gdb_target_obs="m32r-tdep.o m32r-linux-tdep.o \
- glibc-tdep.o solib-svr4.o symfile-mem.o \
- linux-tdep.o"
+ glibc-tdep.o solib-svr4.o solib-svr4-linux.o \
+ symfile-mem.o linux-tdep.o"
;;
m32r*-*-*)
# Target: Renesas m32r processor
@@ -395,7 +401,8 @@ fido-*-elf*)
m68*-*-linux*)
# Target: Motorola m68k with a.out and ELF
gdb_target_obs="m68k-tdep.o m68k-linux-tdep.o solib-svr4.o \
- linux-tdep.o glibc-tdep.o symfile-mem.o"
+ solib-svr4-linux.o linux-tdep.o glibc-tdep.o \
+ symfile-mem.o"
;;
m68*-*-netbsd* | m68*-*-knetbsd*-gnu)
# Target: NetBSD/m68k
@@ -415,7 +422,7 @@ mep-*-*)
microblaze*-linux-*|microblaze*-*-linux*)
# Target: Xilinx MicroBlaze running Linux
gdb_target_obs="microblaze-tdep.o microblaze-linux-tdep.o solib-svr4.o \
- symfile-mem.o linux-tdep.o"
+ solib-svr4-linux.o symfile-mem.o linux-tdep.o"
;;
microblaze*-*-*)
# Target: Xilinx MicroBlaze running standalone
@@ -425,7 +432,8 @@ microblaze*-*-*)
mips*-*-linux*)
# Target: Linux/MIPS
gdb_target_obs="mips-tdep.o mips-linux-tdep.o glibc-tdep.o \
- solib-svr4.o symfile-mem.o linux-tdep.o"
+ solib-svr4.o solib-svr4-linux.o symfile-mem.o \
+ linux-tdep.o"
;;
mips*-*-netbsd* | mips*-*-knetbsd*-gnu)
# Target: MIPS running NetBSD
@@ -469,7 +477,8 @@ nds32*-*-elf)
or1k*-*-linux*)
# Target: OpenCores OpenRISC 1000 32-bit running Linux
gdb_target_obs="or1k-tdep.o or1k-linux-tdep.o solib-svr4.o \
- symfile-mem.o glibc-tdep.o linux-tdep.o"
+ solib-svr4-linux.o symfile-mem.o glibc-tdep.o \
+ linux-tdep.o"
;;
or1k-*-* | or1knd-*-*)
@@ -503,7 +512,8 @@ powerpc-*-aix* | rs6000-*-* | powerpc64-*-aix*)
powerpc*-*-linux*)
# Target: PowerPC running Linux
gdb_target_obs="rs6000-tdep.o ppc-linux-tdep.o ppc-sysv-tdep.o \
- ppc64-tdep.o solib-svr4.o svr4-tls-tdep.o \
+ ppc64-tdep.o solib-svr4.o solib-svr4-linux.o \
+ svr4-tls-tdep.o \
glibc-tdep.o symfile-mem.o linux-tdep.o \
ravenscar-thread.o ppc-ravenscar-thread.o \
linux-record.o \
@@ -524,6 +534,7 @@ powerpc*-*-*)
s390*-*-linux*)
# Target: S390 running Linux
gdb_target_obs="s390-linux-tdep.o s390-tdep.o solib-svr4.o \
+ solib-svr4-linux.o \
linux-tdep.o linux-record.o symfile-mem.o \
svr4-tls-tdep.o"
;;
@@ -536,7 +547,8 @@ riscv*-*-freebsd*)
riscv*-*-linux*)
# Target: Linux/RISC-V
gdb_target_obs="riscv-linux-tdep.o riscv-canonicalize-syscall-gen.o \
- glibc-tdep.o linux-tdep.o solib-svr4.o symfile-mem.o \
+ glibc-tdep.o linux-tdep.o solib-svr4.o solib-svr4-linux.o \
+ symfile-mem.o \
linux-record.o svr4-tls-tdep.o"
;;
@@ -558,7 +570,7 @@ rx-*-*)
sh*-*-linux*)
# Target: GNU/Linux Super-H
gdb_target_obs="sh-tdep.o sh-linux-tdep.o \
- solib-svr4.o symfile-mem.o \
+ solib-svr4.o solib-svr4-linux.o symfile-mem.o \
glibc-tdep.o linux-tdep.o"
;;
sh*-*-netbsd* | sh*-*-knetbsd*-gnu)
@@ -577,7 +589,8 @@ sh*)
sparc-*-linux*)
# Target: GNU/Linux SPARC
gdb_target_obs="sparc-tdep.o \
- sparc-linux-tdep.o solib-svr4.o symfile-mem.o \
+ sparc-linux-tdep.o solib-svr4.o solib-svr4-linux.o \
+ symfile-mem.o \
linux-tdep.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
if test "x$have_64_bit_bfd" = "xyes"; then
@@ -590,7 +603,8 @@ sparc64-*-linux*)
# Target: GNU/Linux UltraSPARC
gdb_target_obs="sparc64-tdep.o \
sparc64-linux-tdep.o sparc-tdep.o \
- sparc-linux-tdep.o solib-svr4.o linux-tdep.o \
+ sparc-linux-tdep.o solib-svr4.o solib-svr4-linux.o \
+ linux-tdep.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
sparc*-*-freebsd* | sparc*-*-kfreebsd*-gnu)
@@ -658,6 +672,7 @@ tic6x-*-*)
tilegx-*-linux*)
# Target: TILE-Gx
gdb_target_obs="tilegx-tdep.o tilegx-linux-tdep.o solib-svr4.o \
+ solib-svr4-linux.o \
symfile-mem.o glibc-tdep.o linux-tdep.o"
;;
@@ -708,7 +723,8 @@ x86_64-*-linux*)
# Target: GNU/Linux x86-64
gdb_target_obs="amd64-linux-tdep.o ${i386_tobjs} \
i386-linux-tdep.o glibc-tdep.o svr4-tls-tdep.o \
- solib-svr4.o symfile-mem.o linux-tdep.o linux-record.o \
+ solib-svr4.o solib-svr4-linux.o symfile-mem.o \
+ linux-tdep.o linux-record.o \
arch/i386-linux-tdesc.o arch/amd64-linux-tdesc.o \
arch/x86-linux-tdesc-features.o"
;;
diff --git a/gdb/contrib/ari/create-web-ari-in-src.sh b/gdb/contrib/ari/create-web-ari-in-src.sh
index 4ea0398..b479ce5 100644
--- a/gdb/contrib/ari/create-web-ari-in-src.sh
+++ b/gdb/contrib/ari/create-web-ari-in-src.sh
@@ -50,7 +50,7 @@ if [ -z "${tempdir}" ] ; then
fi
fi
-# Default location of generate index.hmtl web page.
+# Default location of generated index.html web page.
if [ -z "${webdir}" ] ; then
# Use 'branch' subdir name if Tag contains branch
if [ -f "${srcdir}/gdb/CVS/Tag" ] ; then
diff --git a/gdb/contrib/ari/gdb_ari.sh b/gdb/contrib/ari/gdb_ari.sh
index f539ed1..e10bbe0 100755
--- a/gdb/contrib/ari/gdb_ari.sh
+++ b/gdb/contrib/ari/gdb_ari.sh
@@ -60,7 +60,7 @@ Options:
-Werror Treat all problems as errors.
-Wall Report all problems.
-Wari Report problems that should be fixed in new code.
- -WCATEGORY Report problems in the specifed category. The category
+ -WCATEGORY Report problems in the specified category. The category
can be prefixed with "no-". Valid categories
are: ${all}
EOF
@@ -159,7 +159,7 @@ BEGIN {
PWD = "'`pwd`'"
}
-# Print the error message for BUG. Append SUPLEMENT if non-empty.
+# Print the error message for BUG. Append SUPPLEMENT if non-empty.
function print_bug(file,line,prefix,category,bug,doc,supplement, suffix,idx) {
if (print_idx) {
idx = bug ": "
diff --git a/gdb/contrib/ari/update-web-ari.sh b/gdb/contrib/ari/update-web-ari.sh
index 6e7b5ff..b9ef184 100644
--- a/gdb/contrib/ari/update-web-ari.sh
+++ b/gdb/contrib/ari/update-web-ari.sh
@@ -176,7 +176,7 @@ fi
# THIS HAS SUFFERED BIT ROT
if ${check_indent_p} && test -d "${srcdir}"
then
- printf "Analizing file indentation:" 1>&2
+ printf "Analyzing file indentation:" 1>&2
( cd "${srcdir}" && /bin/sh ${aridir}/gdb_find.sh ${project} | while read f
do
if /bin/sh ${aridir}/gdb_indent.sh < ${f} 2>/dev/null | cmp -s - ${f}
@@ -550,7 +550,7 @@ function print_heading (nb_file, where, bug_i) {
for (bug_i = 1; bug_i <= nr_bug; bug_i++) {
bug = i2bug[bug_i];
printf "<th>"
- # The title names are offset by one. Otherwize, when the browser
+ # The title names are offset by one. Otherwise, when the browser
# jumps to the name it leaves out half the relevant column.
#printf "<a name=\",%s\">&nbsp;</a>", bug
printf "<a name=\",%s\">&nbsp;</a>", i2bug[bug_i-1]
@@ -851,7 +851,7 @@ EOF
print_toc 0 -1 deprecate Deprecate <<EOF
Mechanisms that are a candidate for being made obsolete. Once core
GDB no longer depends on these mechanisms and/or there is a
-replacement available, these mechanims can be deprecated (adding the
+replacement available, these mechanisms can be deprecated (adding the
deprecated prefix) obsoleted (put into category obsolete) or deleted.
See obsolete and deprecated.
EOF
diff --git a/gdb/contrib/codespell-dictionary.txt b/gdb/contrib/codespell-dictionary.txt
new file mode 100644
index 0000000..09bc309
--- /dev/null
+++ b/gdb/contrib/codespell-dictionary.txt
@@ -0,0 +1 @@
+gdbsever->gdbserver
diff --git a/gdb/contrib/codespell-ignore-words.txt b/gdb/contrib/codespell-ignore-words.txt
index 2d6e13a..881b1d2 100644
--- a/gdb/contrib/codespell-ignore-words.txt
+++ b/gdb/contrib/codespell-ignore-words.txt
@@ -1,2 +1,3 @@
configury
SME
+Synopsys
diff --git a/gdb/contrib/setup.cfg b/gdb/contrib/setup.cfg
index d6be386..5541a01 100644
--- a/gdb/contrib/setup.cfg
+++ b/gdb/contrib/setup.cfg
@@ -4,6 +4,7 @@
skip = */ChangeLog*,*/configure,gdbsupport/Makefile.in,*.dat,*.eps,gdb/features/*.c,gdb/ada-casefold.h,gdb/copying.c,gdb/gdbarch-gen.h,gdb/gdbarch-gen.c,gdb/target-delegates-gen.c
ignore-words = gdb/contrib/codespell-ignore-words.txt
+dictionary = gdb/contrib/codespell-dictionary.txt,-
# Ignore all URLs.
uri-ignore-words-list = *
diff --git a/gdb/copying.c b/gdb/copying.c
index af465e5..a198030 100644
--- a/gdb/copying.c
+++ b/gdb/copying.c
@@ -639,9 +639,7 @@ show_warranty_command (const char *ignore, int from_tty)
gdb_printf ("\n");
}
-void _initialize_copying ();
-void
-_initialize_copying ()
+INIT_GDB_FILE (copying)
{
add_cmd ("copying", no_set_class, show_copying_command,
_("Conditions for redistributing copies of GDB."),
diff --git a/gdb/corefile.c b/gdb/corefile.c
index 9f27f14..a2c75c0 100644
--- a/gdb/corefile.c
+++ b/gdb/corefile.c
@@ -391,9 +391,7 @@ set_gnutarget (const char *newtarget)
set_gnutarget_command (NULL, 0, NULL);
}
-void _initialize_core ();
-void
-_initialize_core ()
+INIT_GDB_FILE (core)
{
cmd_list_element *core_file_cmd
= add_cmd ("core-file", class_files, core_file_command, _("\
diff --git a/gdb/corelow.c b/gdb/corelow.c
index 4518781..24b949b 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -37,7 +37,6 @@
#include "exec.h"
#include "readline/tilde.h"
#include "solib.h"
-#include "solist.h"
#include "filenames.h"
#include "progspace.h"
#include "objfiles.h"
@@ -957,7 +956,7 @@ locate_exec_from_corefile_exec_context (bfd *cbfd,
execbfd = open_and_check_build_id (exec_name);
else
{
- std::string p = (ldirname (bfd_get_filename (cbfd))
+ std::string p = (gdb_ldirname (bfd_get_filename (cbfd))
+ '/'
+ exec_name);
execbfd = open_and_check_build_id (p.c_str ());
@@ -971,7 +970,7 @@ locate_exec_from_corefile_exec_context (bfd *cbfd,
if (execbfd == nullptr)
{
const char *base_name = lbasename (exec_name);
- std::string p = (ldirname (bfd_get_filename (cbfd))
+ std::string p = (gdb_ldirname (bfd_get_filename (cbfd))
+ '/'
+ base_name);
execbfd = open_and_check_build_id (p.c_str ());
@@ -1181,7 +1180,7 @@ core_target_open (const char *arg, int from_tty)
if (current_program_space->exec_bfd () == nullptr)
set_gdbarch_from_file (current_program_space->core_bfd ());
- post_create_inferior (from_tty);
+ post_create_inferior (from_tty, true);
/* Now go through the target stack looking for threads since there
may be a thread_stratum target loaded on top of target core by
@@ -2158,9 +2157,7 @@ core_target_find_mapped_file (const char *filename,
return targ->lookup_mapped_file_info (filename, addr);
}
-void _initialize_corelow ();
-void
-_initialize_corelow ()
+INIT_GDB_FILE (corelow)
{
add_target (core_target_info, core_target_open,
filename_maybe_quoted_completer);
diff --git a/gdb/cp-abi.c b/gdb/cp-abi.c
index 8f2067b..d8cfc08 100644
--- a/gdb/cp-abi.c
+++ b/gdb/cp-abi.c
@@ -384,9 +384,7 @@ show_cp_abi_cmd (const char *args, int from_tty)
uiout->text (").\n");
}
-void _initialize_cp_abi ();
-void
-_initialize_cp_abi ()
+INIT_GDB_FILE (cp_abi)
{
struct cmd_list_element *c;
diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y
index d4ab98c..cafd6b2 100644
--- a/gdb/cp-name-parser.y
+++ b/gdb/cp-name-parser.y
@@ -374,6 +374,22 @@ function
| colon_ext_only function_arglist start_opt
{ $$ = state->fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, $2.comp);
if ($3) $$ = state->fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$, $3); }
+ | colon_ext_only
+ {
+ /* This production is a hack to handle
+ something like "name::operator new[]" --
+ without arguments, this ordinarily would
+ not parse, but canonicalizing it is
+ important. So we infer the "()" and then
+ remove it when converting back to string.
+ Note that this works because this
+ production is terminal. */
+ demangle_component *comp
+ = state->fill_comp (DEMANGLE_COMPONENT_FUNCTION_TYPE,
+ nullptr, nullptr);
+ $$ = state->fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, comp);
+ state->demangle_info->added_parens = true;
+ }
| conversion_op_name start_opt
{ $$ = $1.comp;
@@ -2111,13 +2127,17 @@ canonicalize_tests ()
should_be_the_same ("Foozle<int>::fogey<Empty<int> > (Empty<int>)",
"Foozle<int>::fogey<Empty<int>> (Empty<int>)");
+
+ should_be_the_same ("something :: operator new [ ]",
+ "something::operator new[]");
+ should_be_the_same ("something :: operator new",
+ "something::operator new");
+ should_be_the_same ("operator()", "operator ()");
}
#endif
-void _initialize_cp_name_parser ();
-void
-_initialize_cp_name_parser ()
+INIT_GDB_FILE (cp_name_parser)
{
#if GDB_SELF_TEST
selftests::register_test ("canonicalize", canonicalize_tests);
diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index d285e86..009ea4b 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -1049,9 +1049,7 @@ maintenance_cplus_namespace (const char *args, int from_tty)
gdb_printf (_("The `maint namespace' command was removed.\n"));
}
-void _initialize_cp_namespace ();
-void
-_initialize_cp_namespace ()
+INIT_GDB_FILE (cp_namespace)
{
struct cmd_list_element *cmd;
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index c71b8d9..cab7110 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -573,6 +573,17 @@ replace_typedefs (struct demangle_parse_info *info,
}
}
+/* A helper to strip a trailing "()" from PTR. The string is modified
+ in place. */
+
+static void
+maybe_strip_parens (char *ptr)
+{
+ size_t len = strlen (ptr);
+ if (len > 2 && ptr[len - 2] == '(' && ptr[len - 1] == ')')
+ ptr[len - 2] = '\0';
+}
+
/* Parse STRING and convert it to canonical form, resolving any
typedefs. If parsing fails, or if STRING is already canonical,
return nullptr. Otherwise return the canonical form. If
@@ -599,6 +610,9 @@ cp_canonicalize_string_full (const char *string,
estimated_len);
gdb_assert (us);
+ if (info->added_parens)
+ maybe_strip_parens (us.get ());
+
/* Finally, compare the original string with the computed
name, returning NULL if they are the same. */
if (strcmp (us.get (), string) == 0)
@@ -647,6 +661,9 @@ cp_canonicalize_string (const char *string)
return nullptr;
}
+ if (info->added_parens)
+ maybe_strip_parens (us.get ());
+
if (strcmp (us.get (), string) == 0)
return nullptr;
@@ -2370,9 +2387,7 @@ find_toplevel_char (const char *s, char c)
return 0;
}
-void _initialize_cp_support ();
-void
-_initialize_cp_support ()
+INIT_GDB_FILE (cp_support)
{
cmd_list_element *maintenance_cplus
= add_basic_prefix_cmd ("cplus", class_maintenance,
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index 3ed354c..ffe0ba1 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -63,6 +63,10 @@ struct demangle_parse_info
/* Any memory used during processing. */
auto_obstack obstack;
+ /* True if the parser had to add a dummy '()' at the end of the
+ input text to make it parse. */
+ bool added_parens = false;
+
/* Any other objects referred to by this object, and whose storage
lifetime must be linked. */
std::vector<std::unique_ptr<demangle_parse_info>> infos;
diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
index 2117718..252072b 100644
--- a/gdb/cp-valprint.c
+++ b/gdb/cp-valprint.c
@@ -797,9 +797,7 @@ test_print_fields (gdbarch *arch)
#endif
-void _initialize_cp_valprint ();
-void
-_initialize_cp_valprint ()
+INIT_GDB_FILE (cp_valprint)
{
#if GDB_SELF_TEST
selftests::register_test_foreach_arch ("print-fields", test_print_fields);
diff --git a/gdb/cris-linux-tdep.c b/gdb/cris-linux-tdep.c
index b2ac80d..a39441e 100644
--- a/gdb/cris-linux-tdep.c
+++ b/gdb/cris-linux-tdep.c
@@ -23,6 +23,7 @@
#include "osabi.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "solib-svr4.h"
#include "symtab.h"
#include "gdbarch.h"
@@ -41,14 +42,10 @@ cris_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_fetch_tls_load_module_address (gdbarch,
svr4_fetch_objfile_link_map);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_ilp32_fetch_link_map_offsets);
-
+ set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
}
-void _initialize_cris_linux_tdep ();
-void
-_initialize_cris_linux_tdep ()
+INIT_GDB_FILE (cris_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_cris, 0, GDB_OSABI_LINUX,
cris_linux_init_abi);
diff --git a/gdb/cris-tdep.c b/gdb/cris-tdep.c
index 722c0a4..b49e641 100644
--- a/gdb/cris-tdep.c
+++ b/gdb/cris-tdep.c
@@ -3816,9 +3816,7 @@ static void cris_iterate_over_regset_sections (struct gdbarch *gdbarch,
&cris_regset, NULL, cb_data);
}
-void _initialize_cris_tdep ();
-void
-_initialize_cris_tdep ()
+INIT_GDB_FILE (cris_tdep)
{
gdbarch_register (bfd_arch_cris, cris_gdbarch_init, cris_dump_tdep);
diff --git a/gdb/csky-linux-tdep.c b/gdb/csky-linux-tdep.c
index 2afb358..0651645 100644
--- a/gdb/csky-linux-tdep.c
+++ b/gdb/csky-linux-tdep.c
@@ -22,6 +22,7 @@
#include "osabi.h"
#include "glibc-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "gdbarch.h"
#include "solib-svr4.h"
#include "regset.h"
@@ -407,8 +408,7 @@ csky_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* Shared library handling. */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
/* Enable TLS support. */
set_gdbarch_fetch_tls_load_module_address (gdbarch,
@@ -426,9 +426,7 @@ csky_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
&csky_linux_rt_sigreturn_tramp_frame_kernel_4x);
}
-void _initialize_csky_linux_tdep ();
-void
-_initialize_csky_linux_tdep ()
+INIT_GDB_FILE (csky_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_csky, 0, GDB_OSABI_LINUX,
csky_linux_init_abi);
diff --git a/gdb/csky-tdep.c b/gdb/csky-tdep.c
index 350612f..e6c6e2c 100644
--- a/gdb/csky-tdep.c
+++ b/gdb/csky-tdep.c
@@ -2882,9 +2882,7 @@ csky_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
return gdbarch;
}
-void _initialize_csky_tdep ();
-void
-_initialize_csky_tdep ()
+INIT_GDB_FILE (csky_tdep)
{
gdbarch_register (bfd_arch_csky, csky_gdbarch_init);
diff --git a/gdb/darwin-nat-info.c b/gdb/darwin-nat-info.c
index b5784be..3ec49af 100644
--- a/gdb/darwin-nat-info.c
+++ b/gdb/darwin-nat-info.c
@@ -839,9 +839,7 @@ info_mach_exceptions_command (const char *args, int from_tty)
}
}
-void _initialize_darwin_info_commands ();
-void
-_initialize_darwin_info_commands ()
+INIT_GDB_FILE (darwin_info_commands)
{
add_info ("mach-tasks", info_mach_tasks_command,
_("Get list of tasks in system."));
diff --git a/gdb/darwin-nat.c b/gdb/darwin-nat.c
index 6bc0e4f..7acf639 100644
--- a/gdb/darwin-nat.c
+++ b/gdb/darwin-nat.c
@@ -1853,7 +1853,7 @@ copy_shell_to_cache (const char *shell, const std::string &new_name)
error (_("Could not open shell (%s) for reading: %s"),
shell, safe_strerror (errno));
- std::string new_dir = ldirname (new_name.c_str ());
+ std::string new_dir = gdb_ldirname (new_name.c_str ());
if (!mkdir_recursive (new_dir.c_str ()))
error (_("Could not make cache directory \"%s\": %s"),
new_dir.c_str (), safe_strerror (errno));
@@ -2469,9 +2469,7 @@ darwin_nat_target::supports_multi_process ()
return true;
}
-void _initialize_darwin_nat ();
-void
-_initialize_darwin_nat ()
+INIT_GDB_FILE (darwin_nat)
{
kern_return_t kret;
diff --git a/gdb/dbxread.c b/gdb/dbxread.c
index 8d0ebab..260f583 100644
--- a/gdb/dbxread.c
+++ b/gdb/dbxread.c
@@ -248,9 +248,7 @@ static const struct sym_fns aout_sym_fns =
NULL, /* sym_probe_fns */
};
-void _initialize_dbxread ();
-void
-_initialize_dbxread ()
+INIT_GDB_FILE (dbxread)
{
add_symtab_fns (bfd_target_aout_flavour, &aout_sym_fns);
}
diff --git a/gdb/dcache.c b/gdb/dcache.c
index 2c5484d..7a15278 100644
--- a/gdb/dcache.c
+++ b/gdb/dcache.c
@@ -679,9 +679,7 @@ set_dcache_line_size (const char *args, int from_tty,
target_dcache_invalidate (current_program_space->aspace);
}
-void _initialize_dcache ();
-void
-_initialize_dcache ()
+INIT_GDB_FILE (dcache)
{
add_setshow_boolean_cmd ("remotecache", class_support,
&dcache_enabled_p, _("\
diff --git a/gdb/debuginfod-support.c b/gdb/debuginfod-support.c
index d573b8d..8f28fd5 100644
--- a/gdb/debuginfod-support.c
+++ b/gdb/debuginfod-support.c
@@ -594,9 +594,7 @@ maint_get_debuginfod_download_sections ()
/* Register debuginfod commands. */
-void _initialize_debuginfod ();
-void
-_initialize_debuginfod ()
+INIT_GDB_FILE (debuginfod)
{
/* set/show debuginfod */
add_setshow_prefix_cmd ("debuginfod", class_run,
diff --git a/gdb/defs.h b/gdb/defs.h
index bda4ef6..bb1e119 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -190,8 +190,6 @@ extern std::string relocate_gdb_directory (const char *initial, bool relocatable
/* From top.c */
-typedef void initialize_file_ftype (void);
-
extern char *gdb_readline_wrapper (const char *);
extern const char *command_line_input (std::string &cmd_line_buffer,
@@ -407,4 +405,10 @@ DEF_ENUM_FLAGS_TYPE (enum user_selected_what_flag, user_selected_what);
#include "utils.h"
+/* File initialization macro. This is found by make-init-c and used
+ to construct the gdb initialization function. */
+#define INIT_GDB_FILE(NAME) \
+ extern void _initialize_ ## NAME (); \
+ void _initialize_ ## NAME ()
+
#endif /* GDB_DEFS_H */
diff --git a/gdb/dicos-tdep.c b/gdb/dicos-tdep.c
index 4dfac76..d6bc9a5 100644
--- a/gdb/dicos-tdep.c
+++ b/gdb/dicos-tdep.c
@@ -27,7 +27,7 @@
void
dicos_init_abi (struct gdbarch *gdbarch)
{
- set_gdbarch_so_ops (gdbarch, &solib_target_so_ops);
+ set_gdbarch_make_solib_ops (gdbarch, make_target_solib_ops);
/* Every process, although has its own address space, sees the same
list of shared libraries. There's no "main executable" in DICOS,
diff --git a/gdb/disasm-selftests.c b/gdb/disasm-selftests.c
index 3ccc174..0d06065 100644
--- a/gdb/disasm-selftests.c
+++ b/gdb/disasm-selftests.c
@@ -418,9 +418,7 @@ disassemble_insn (gdbarch *gdbarch, gdb::byte_vector &insn,
} /* namespace selftests */
-void _initialize_disasm_selftests ();
-void
-_initialize_disasm_selftests ()
+INIT_GDB_FILE (disasm_selftests)
{
selftests::register_test_foreach_arch ("print_one_insn",
selftests::print_one_insn_test);
diff --git a/gdb/disasm.c b/gdb/disasm.c
index 2a7a80c..b731192 100644
--- a/gdb/disasm.c
+++ b/gdb/disasm.c
@@ -1470,9 +1470,7 @@ disassembler_options_completer (struct cmd_list_element *ignore,
/* Initialization code. */
-void _initialize_disasm ();
-void
-_initialize_disasm ()
+INIT_GDB_FILE (disasm)
{
/* Add the command that controls the disassembler options. */
set_show_commands set_show_disas_opts
diff --git a/gdb/displaced-stepping.c b/gdb/displaced-stepping.c
index 7df45d6..6699296 100644
--- a/gdb/displaced-stepping.c
+++ b/gdb/displaced-stepping.c
@@ -315,9 +315,7 @@ displaced_step_buffers::restore_in_ptid (ptid_t ptid)
}
}
-void _initialize_displaced_stepping ();
-void
-_initialize_displaced_stepping ()
+INIT_GDB_FILE (displaced_stepping)
{
add_setshow_boolean_cmd ("displaced", class_maintenance,
&debug_displaced, _("\
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 5e5e888..b6d626b 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -3807,7 +3807,7 @@ Thread 1 "main" received signal SIGINT, Interrupt.
@table @code
@anchor{info_threads}
@kindex info threads
-@item info threads @r{[}-gid@r{]} @r{[}@var{thread-id-list}@r{]}
+@item info threads @r{[}-gid@r{]} @r{[}-stopped@r{]} @r{[}-running@r{]} @r{[}@var{thread-id-list}@r{]}
Display information about one or more threads. With no arguments
displays information about all threads. You can specify the list of
@@ -3857,6 +3857,14 @@ If you're debugging multiple inferiors, @value{GDBN} displays thread
IDs using the qualified @var{inferior-num}.@var{thread-num} format.
Otherwise, only @var{thread-num} is shown.
+If you specify the @samp{-stopped} option, @value{GDBN} filters the
+output of the command to print the stopped threads only. Similarly,
+if you specify the @samp{-running} option, @value{GDBN} filters the
+output to print the running threads only. These options can be
+helpful to reduce the output list if there is a large number of
+threads. If you specify both options, @value{GDBN} prints both
+stopped and running threads.
+
If you specify the @samp{-gid} option, @value{GDBN} displays a column
indicating each thread's global thread ID:
@@ -13098,15 +13106,15 @@ environment variable.
@vindex $_active_linker_namespaces@r{, convenience variable}
@item $_active_linker_namespaces
-Number of active linkage namespaces in the inferior. In systems with no
-support for linkage namespaces, this variable will always be set to @samp{1}.
+Number of active linker namespaces in the inferior (@pxref{Files}). In systems
+with no support for linker namespaces, this variable will always be set to
+@samp{1}.
-@vindex $_current_linker_namespace@r{, convenience variable}
-@item $_current_linker_namespace
-The namespace which contains the current location in the inferior. This
-returns GDB's internal identifier for namespaces, which is @samp{[[@var{n}]]}
-where @var{n} is a zero-based namespace number. In systems with no support
-for linkage namespaces, this variable will always be set to @samp{[[0]]}.
+@vindex $_linker_namespace@r{, convenience variable}
+@item $_linker_namespace
+The namespace which contains the current location in the inferior. This returns
+@value{GDBN}'s internal numbering for the namespace. In systems with no support
+for linker namespaces, this variable will always be set to @samp{0}.
@end table
@@ -22234,11 +22242,18 @@ be determined then the address range for the @code{.text} section from
the library will be listed. If the @code{.text} section cannot be
found then no addresses will be listed.
-On systems that support linkage namespaces, the output includes an
+On systems that support linker namespaces, the output includes an
additional column @code{NS} if the inferior has more than one active
-namespace when the command is used. This column the linkage namespace
+namespace when the command is used. This column the linker namespace
that the shared library was loaded into.
+@cindex linker namespaces
+@dfn{Linker namespaces} are a feature of some standard libraries, that allow
+shared objects to be loaded in isolated environment, eliminating the
+possibility that those objects may cross-talk. Each set of isolated
+shared objects is said to belong to a ``namespace'', and linker related
+actions such as relocations do not cross namespace boundaries.
+
@kindex info dll
@item info dll @var{regex}
This is an alias of @code{info sharedlibrary}.
@@ -24767,6 +24782,10 @@ future connections is shown. The available settings are:
@tab @code{vFile:stat}
@tab Host I/O
+@item @code{hostio-lstat-packet}
+@tab @code{vFile:lstat}
+@tab Host I/O
+
@item @code{hostio-setfs-packet}
@tab @code{vFile:setfs}
@tab Host I/O
@@ -26630,8 +26649,9 @@ Show whether AArch64 debugging messages are displayed.
@end table
-@subsubsection AArch64 SVE.
-@cindex AArch64 SVE.
+@subsubsection AArch64 Scalable Vector Extension
+@cindex Scalable Vector Extension, AArch64
+@cindex SVE, AArch64
When @value{GDBN} is debugging the AArch64 architecture, if the Scalable Vector
Extension (SVE) is present, then @value{GDBN} will provide the vector registers
@@ -26670,11 +26690,10 @@ internally by @value{GDBN} and the Linux Kernel.
@end itemize
-@subsubsection AArch64 SME.
+@subsubsection AArch64 Scalable Matrix Extension
@anchor{AArch64 SME}
-@cindex SME
-@cindex AArch64 SME
-@cindex Scalable Matrix Extension
+@cindex Scalable Matrix Extension, AArch64
+@cindex SME, AArch64
The Scalable Matrix Extension (@url{https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/scalable-matrix-extension-armv9-a-architecture, @acronym{SME}})
is an AArch64 architecture extension that expands on the concept of the
@@ -26866,11 +26885,10 @@ incorrect values for SVE registers (when in streaming mode).
This is the same limitation we have for the @acronym{SVE} registers, and there
are plans to address this limitation going forward.
-@subsubsection AArch64 SME2.
+@subsubsection AArch64 Scalable Matrix Extension 2
@anchor{AArch64 SME2}
-@cindex SME2
-@cindex AArch64 SME2
-@cindex Scalable Matrix Extension 2
+@cindex Scalable Matrix Extension 2, AArch64
+@cindex SME2, AArch64
The Scalable Matrix Extension 2 is an AArch64 architecture extension that
further expands the @acronym{SME} extension with the following:
@@ -26910,8 +26928,9 @@ For more information about @acronym{SME2}, please refer to the
official @url{https://developer.arm.com/documentation/ddi0487/latest,
architecture documentation}.
-@subsubsection AArch64 Pointer Authentication.
-@cindex AArch64 Pointer Authentication.
+@subsubsection AArch64 Pointer Authentication
+@cindex Pointer Authentication, AArch64
+@cindex PAC, AArch64
@anchor{AArch64 PAC}
When @value{GDBN} is debugging the AArch64 architecture, and the program is
@@ -26921,8 +26940,9 @@ 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 @code{addr_flags} field.
-@subsubsection AArch64 Memory Tagging Extension.
-@cindex AArch64 Memory Tagging Extension.
+@subsubsection AArch64 Memory Tagging Extension
+@cindex Memory Tagging Extension, AArch64
+@cindex MTE, AArch64
When @value{GDBN} is debugging the AArch64 architecture, the program is
using the v8.5-A feature Memory Tagging Extension (MTE) and there is support
@@ -28003,6 +28023,7 @@ then it will be used.
@item show style sources
Show the current state of source code styling.
+@anchor{warning-prefix}
@item set style warning-prefix
@itemx show style warning-prefix
@itemx set style error-prefix
@@ -31316,138 +31337,13 @@ appropriate @code{set style} commands. @xref{Output Styling}.
@cindex Emacs
@cindex @sc{gnu} Emacs
-A special interface allows you to use @sc{gnu} Emacs to view (and
-edit) the source files for the program you are debugging with
-@value{GDBN}.
-
-To use this interface, use the command @kbd{M-x gdb} in Emacs. Give the
-executable file you want to debug as an argument. This command starts
-@value{GDBN} as a subprocess of Emacs, with input and output through a newly
-created Emacs buffer.
-@c (Do not use the @code{-tui} option to run @value{GDBN} from Emacs.)
-
-Running @value{GDBN} under Emacs can be just like running @value{GDBN} normally except for two
-things:
-
-@itemize @bullet
-@item
-All ``terminal'' input and output goes through an Emacs buffer, called
-the GUD buffer.
-
-This applies both to @value{GDBN} commands and their output, and to the input
-and output done by the program you are debugging.
-
-This is useful because it means that you can copy the text of previous
-commands and input them again; you can even use parts of the output
-in this way.
-
-All the facilities of Emacs' Shell mode are available for interacting
-with your program. In particular, you can send signals the usual
-way---for example, @kbd{C-c C-c} for an interrupt, @kbd{C-c C-z} for a
-stop.
-
-@item
-@value{GDBN} displays source code through Emacs.
-
-Each time @value{GDBN} displays a stack frame, Emacs automatically finds the
-source file for that frame and puts an arrow (@samp{=>}) at the
-left margin of the current line. Emacs uses a separate buffer for
-source display, and splits the screen to show both your @value{GDBN} session
-and the source.
-
-Explicit @value{GDBN} @code{list} or search commands still produce output as
-usual, but you probably have no reason to use them from Emacs.
-@end itemize
-
-We call this @dfn{text command mode}. Emacs 22.1, and later, also uses
-a graphical mode, enabled by default, which provides further buffers
-that can control the execution and describe the state of your program.
-@xref{GDB Graphical Interface,,, Emacs, The @sc{gnu} Emacs Manual}.
-
-If you specify an absolute file name when prompted for the @kbd{M-x
-gdb} argument, then Emacs sets your current working directory to where
-your program resides. If you only specify the file name, then Emacs
-sets your current working directory to the directory associated
-with the previous buffer. In this case, @value{GDBN} may find your
-program by searching your environment's @env{PATH} variable, but on
-some operating systems it might not find the source. So, although the
-@value{GDBN} input and output session proceeds normally, the auxiliary
-buffer does not display the current source and line of execution.
-
-The initial working directory of @value{GDBN} is printed on the top
-line of the GUD buffer and this serves as a default for the commands
-that specify files for @value{GDBN} to operate on. @xref{Files,
-,Commands to Specify Files}.
-
-By default, @kbd{M-x gdb} calls the program called @file{gdb}. If you
-need to call @value{GDBN} by a different name (for example, if you
-keep several configurations around, with different names) you can
-customize the Emacs variable @code{gud-gdb-command-name} to run the
-one you want.
-
-In the GUD buffer, you can use these special Emacs commands in
-addition to the standard Shell mode commands:
-
-@table @kbd
-@item C-h m
-Describe the features of Emacs' GUD Mode.
-
-@item C-c C-s
-Execute to another source line, like the @value{GDBN} @code{step} command; also
-update the display window to show the current file and location.
-@item C-c C-n
-Execute to next source line in this function, skipping all function
-calls, like the @value{GDBN} @code{next} command. Then update the display window
-to show the current file and location.
+In @sc{gnu} Emacs there is a special interface to @value{GDBN}, which
+facilitates viewing the source code for the program you are debugging.
+There is also an IDE-like interface to GDB, with specialized buffers for
+breakpoints, stack frames and other aspects of the debugger state.
-@item C-c C-i
-Execute one instruction, like the @value{GDBN} @code{stepi} command; update
-display window accordingly.
-
-@item C-c C-f
-Execute until exit from the selected stack frame, like the @value{GDBN}
-@code{finish} command.
-
-@item C-c C-r
-Continue execution of your program, like the @value{GDBN} @code{continue}
-command.
-
-@item C-c <
-Go up the number of frames indicated by the numeric argument
-(@pxref{Arguments, , Numeric Arguments, Emacs, The @sc{gnu} Emacs Manual}),
-like the @value{GDBN} @code{up} command.
-
-@item C-c >
-Go down the number of frames indicated by the numeric argument, like the
-@value{GDBN} @code{down} command.
-@end table
-
-In any source file, the Emacs command @kbd{C-x @key{SPC}} (@code{gud-break})
-tells @value{GDBN} to set a breakpoint on the source line point is on.
-
-In text command mode, if you type @kbd{M-x speedbar}, Emacs displays a
-separate frame which shows a backtrace when the GUD buffer is current.
-Move point to any frame in the stack and type @key{RET} to make it
-become the current frame and display the associated source in the
-source buffer. Alternatively, click @kbd{Mouse-2} to make the
-selected frame become the current one. In graphical mode, the
-speedbar displays watch expressions.
-
-If you accidentally delete the source-display buffer, an easy way to get
-it back is to type the command @code{f} in the @value{GDBN} buffer, to
-request a frame display; when you run under Emacs, this recreates
-the source buffer if necessary to show you the context of the current
-frame.
-
-The source files displayed in Emacs are in ordinary Emacs buffers
-which are visiting the source files in the usual way. You can edit
-the files with these buffers if you wish; but keep in mind that @value{GDBN}
-communicates with Emacs in terms of line numbers. If you add or
-delete lines from the text, the line numbers that @value{GDBN} knows cease
-to correspond properly with the code.
-
-A more detailed description of Emacs' interaction with @value{GDBN} is
+A detailed description of Emacs' interaction with @value{GDBN} is
given in the Emacs manual (@pxref{Debuggers,,, Emacs, The @sc{gnu}
Emacs Manual}).
@@ -41458,7 +41354,7 @@ libpython is present and found at configure time.) Python makes
@value{GDBN} scripting much more powerful than the restricted CLI
scripting language. If your host does not have Python installed, you
can find it on @url{http://www.python.org/download/}. The oldest version
-of Python supported by GDB is 3.0.1. The optional argument @var{python}
+of Python supported by GDB is 3.4. The optional argument @var{python}
is used to find the Python headers and libraries. It can be either
the name of a Python executable, or the name of the directory in which
Python is installed.
@@ -42859,6 +42755,23 @@ reports and error and the command is aborted.
@item show watchdog
Show the current setting of the target wait timeout.
+
+@kindex maint set console-translation-mode
+@kindex maint show console-translation-mode
+@item maint set console-translation-mode @r{[}binary|text@r{]}
+@itemx maint show console-translation-mode
+Controls the translation mode of @value{GDBN} stdout/stderr. MS-Windows
+only. Useful for running the @value{GDBN} testsuite.
+
+The translation mode values are as follows:
+@table @code
+@item binary
+No translation.
+@item text
+Translate @samp{\n} (LF, a single Line Feed) into @samp{\r\n} (CR-LF, a
+Carriage Return-Line Feed combination).
+@end table
+
@end table
@node Remote Protocol
@@ -46835,12 +46748,28 @@ 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
+Get information about the file @var{filename} on the target as if from
+a @samp{stat} call. 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}.
+If @var{filename} is a symbolic link, then the information returned is
+about the file the link refers to, this is inline with the @samp{stat}
+library call.
+
+@item vFile:lstat: @var{filename}
+Get information about the file @var{filename} on the target as if from
+an @samp{lstat} call. 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}.
+
+This packet is identical to @samp{vFile:stat}, except if
+@var{filename} is a symbolic link, then this packet returns
+information about the link itself, not the file that the link refers
+to, this is inline with the @samp{lstat} library call.
+
@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/guile.texi b/gdb/doc/guile.texi
index c6d889f..9677229 100644
--- a/gdb/doc/guile.texi
+++ b/gdb/doc/guile.texi
@@ -1772,6 +1772,16 @@ invoking it interactively. If this function throws an exception,
it is turned into a @value{GDBN} @code{error} call.
Otherwise, the return value is ignored.
+For non-prefix commands, @var{invoke} is required. For prefix
+commands @var{invoke} is optional. Only prefix commands that need to
+handle unknown sub-commands should supply @var{invoke}.
+
+For prefix commands that don't supply @var{invoke}, if the prefix
+command is used without a sub-command name then @value{GDBN} will
+display the help text for every sub-command, unless the prefix command
+is a @kbd{show} sub-command, in which case @value{GDBN} will list the
+values of all sub-commands.
+
The argument @var{command-class} is one of the @samp{COMMAND_} constants
defined below. This argument tells @value{GDBN} how to categorize the
new command in the help system. The default is @code{COMMAND_NONE}.
@@ -2098,8 +2108,10 @@ is the @code{<gdb:parameter>} object representing the parameter, and
This function must return a string, and will be displayed to the user.
@value{GDBN} will add a trailing newline.
-The argument @var{doc} is the help text for the new parameter.
-If there is no documentation string, a default value is used.
+The argument @var{doc} is the help text for the new parameter. If
+there is no documentation string, a default value is used. If the
+documentation string is empty, then @value{GDBN} will print just the
+@var{set-doc} and @var{show-doc} strings (see below).
The argument @var{set-doc} is the help text for this parameter's
@code{set} command.
diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index 7bb6503..6fa2285 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -479,7 +479,7 @@ call this function and will automatically direct the output to the
relevant stream.
@end defun
-@defun gdb.flush (@r{[}, stream@r{]})
+@defun gdb.flush (@r{[}stream@r{]})
Flush the buffer of a @value{GDBN} paginated stream so that the
contents are displayed immediately. @value{GDBN} will flush the
contents of a stream automatically when it encounters a newline in the
@@ -509,6 +509,17 @@ Flushing @code{sys.stdout} or @code{sys.stderr} will automatically
call this function for the relevant stream.
@end defun
+@defun gdb.warning (text)
+Print a warning message to @value{GDBN}'s standard output stream. The
+warning message is the warning prefix (@pxref{warning-prefix}), the
+string @w{@samp{warning: }}, and then @var{text}, which must be a
+non-empty string.
+
+Due to the warning prefix, @var{text} should not begin with a capital
+letter (except for proper nouns), and @var{text} should end with a
+period.
+@end defun
+
@defun gdb.target_charset ()
Return the name of the current target character set (@pxref{Character
Sets}). This differs from @code{gdb.parameter('target-charset')} in
@@ -4525,6 +4536,7 @@ You can implement new @value{GDBN} CLI commands in Python. A CLI
command is implemented using an instance of the @code{gdb.Command}
class, most commonly using a subclass.
+@anchor{Command.__init__}
@defun Command.__init__ (name, command_class @r{[}, completer_class @r{[}, prefix@r{]]})
The object initializer for @code{Command} registers the new command
with @value{GDBN}. This initializer is normally invoked from the
@@ -4558,6 +4570,7 @@ documentation string is provided, the default value @samp{This command
is not documented.} is used.
@end defun
+@anchor{Command.dont_repeat}
@cindex don't repeat Python command
@defun Command.dont_repeat ()
By default, a @value{GDBN} command is repeated when the user enters a
@@ -4568,6 +4581,7 @@ exception). This is similar to the user command @code{dont-repeat},
see @ref{Define, dont-repeat}.
@end defun
+@anchor{Command.invoke}
@defun Command.invoke (argument, from_tty)
This method is called by @value{GDBN} when this command is invoked.
@@ -4581,6 +4595,17 @@ that the command came from elsewhere.
If this method throws an exception, it is turned into a @value{GDBN}
@code{error} call. Otherwise, the return value is ignored.
+For non-prefix commands (@pxref{Command.__init__}), the @code{invoke}
+method is required. For prefix commands the @code{invoke} method is
+optional. Only prefix commands that need to handle unknown
+sub-commands should implement the @code{invoke} method.
+
+For prefix commands that don't implement @code{invoke}, if the prefix
+command is used without a sub-command name then @value{GDBN} will
+display the help text for every sub-command, unless the prefix command
+is a @kbd{show} sub-command, in which case @value{GDBN} will list the
+values of all sub-commands.
+
@findex gdb.string_to_argv
To break @var{argument} up into an argv-like string use
@code{gdb.string_to_argv}. This function behaves identically to
@@ -5079,7 +5104,9 @@ string from the parameter's class, if there is one. If there is no
documentation string, a default value is used. The documentation
string is included in the output of the parameters @code{help set} and
@code{help show} commands, and should be written taking this into
-account.
+account. If the documentation string for the parameter's class is the
+empty string then @value{GDBN} will only use @code{Parameter.set_doc}
+or @code{Parameter.show_doc} (see below) in the @kbd{help} output.
@end defun
@defvar Parameter.set_doc
@@ -5258,6 +5285,99 @@ constants provided when the parameter is created.
The value is @code{gdb.Color} instance.
@end table
+When creating multiple new parameters using @code{gdb.Parameter}, it
+is often desirable to create a prefix command that can be used to
+group related parameters together, for example, if you wished to add
+the parameters @kbd{plugin-name feature-1} and @kbd{plugin-name
+feature-2}, then the @kbd{plugin-name} would need to be a prefix
+command (@pxref{CLI Commands In Python}).
+
+However, when creating parameters, you will almost always need to
+create two prefix commands, one as a @kbd{set} sub-command, and one as
+a @kbd{show} sub-command. @value{GDBN} provides the
+@code{gdb.ParameterPrefix} helper class to make creation of these two
+prefixes easier.
+
+@defun ParameterPrefix.__init__ (name, command_class, doc = @code{None})
+The object initializer for @code{ParameterPrefix} registers two new
+@code{gdb.Command} prefixes, one as a @kbd{set} sub-command, and the
+other as a @kbd{show} sub-command.
+
+@var{name}, a string, is the name of the new prefix, without either
+@kbd{set} or @kbd{show}, similar to the @var{name} passed to
+@code{gdb.Parameter} (@pxref{Parameters In Python}). For example, to
+create the prefixes @kbd{set plugin-name} and @kbd{show plugin-name},
+you would pass the string @kbd{plugin-name}.
+
+@var{command_class} should be one of the @samp{COMMAND_} constants
+(@pxref{CLI Commands In Python}). This argument tells @value{GDBN} how to
+categorize the new parameter prefixes in the help system.
+
+There are a number of ways in which the help text for the two new
+prefix commands can be provided. If the @var{doc} parameter is not
+@code{None}, then this will be used as the documentation string for
+both prefix commands.
+
+If @var{doc} is @code{None}, but @code{gdb.ParameterPrefix} has been
+sub-classed, then the prefix command documentation will be taken from
+sub-classes documentation string (i.e., the @code{__doc__} attribute).
+
+If @var{doc} is @code{None}, and there is no @code{__doc__} string,
+then the default value @samp{This command is not documented.} is used.
+
+When writing the help text, keep in mind that the same text is used
+for both the @kbd{set} and @kbd{show} prefix commands.
+@end defun
+
+@defun ParameterPrefix.invoke_set (argument, from_tty)
+If a sub-class defines this method, then @value{GDBN} will call this
+when the prefix command is used with an unknown sub-command. The
+@var{argument} and @var{from_tty} parameters are the same as for
+@code{gdb.Command.invoke} (@pxref{Command.invoke}).
+
+If this method throws an exception, it is turned into a @value{GDBN}
+@code{error} call. Otherwise, the return value is ignored.
+
+It is not required that a @code{ParameterPrefix} sub-class override
+this method. Usually, a parameter prefix only exists as a means to
+group related parameters together. @value{GDBN} handles this use case
+automatically with no need to implement @code{invoke_set}.
+@end defun
+
+@defun ParameterPrefix.invoke_show (argument, from_tty)
+This is like the @code{invoke_set} method, but for the @kbd{show}
+prefix command. As with @code{invoke_set}, implementation of this
+method is optional, and usually not required.
+@end defun
+
+@cindex don't repeat Python command
+@defun ParameterPrefix.dont_repeat ()
+Like @code{Command.dont_repeat} (@pxref{Command.dont_repeat}), this
+can be called from @code{ParameterPrefix.invoke_set} or
+@code{ParameterPrefix.invoke_show} to prevent the prefix commands from
+being repeated.
+@end defun
+
+Here is a small example that uses @code{gdb.ParameterPrefix} along
+with @code{gdb.Parameter} to create two new parameters
+@kbd{plugin-name feature-1} and @kbd{plugin-name feature-2}. As
+neither @code{invoke_set} or @code{invoke_show} is needed, this
+example does not sub-class @code{gdb.ParameterPrefix}:
+
+@smallexample
+class ExampleParam(gdb.Parameter):
+ def __init__ (self, name):
+ super ().__init__ (name, gdb.COMMAND_DATA, gdb.PARAM_BOOLEAN)
+ self.value = True
+
+gdb.ParameterPrefix("plugin-name", gdb.COMMAND_NONE,
+ """An example parameter prefix.
+
+ This groups together some parameters.""")
+ExampleParam("plugin-name feature-1")
+ExampleParam("plugin-name feature-2")
+@end smallexample
+
@node Functions In Python
@subsubsection Writing new convenience functions
diff --git a/gdb/dtrace-probe.c b/gdb/dtrace-probe.c
index fa60c34..c663571 100644
--- a/gdb/dtrace-probe.c
+++ b/gdb/dtrace-probe.c
@@ -889,9 +889,7 @@ info_probes_dtrace_command (const char *arg, int from_tty)
info_probes_for_spops (arg, from_tty, &dtrace_static_probe_ops);
}
-void _initialize_dtrace_probe ();
-void
-_initialize_dtrace_probe ()
+INIT_GDB_FILE (dtrace_probe)
{
all_static_probe_ops.push_back (&dtrace_static_probe_ops);
diff --git a/gdb/dummy-frame.c b/gdb/dummy-frame.c
index f8440b3..445a7b4 100644
--- a/gdb/dummy-frame.c
+++ b/gdb/dummy-frame.c
@@ -425,9 +425,7 @@ maintenance_print_dummy_frames (const char *args, int from_tty)
}
}
-void _initialize_dummy_frame ();
-void
-_initialize_dummy_frame ()
+INIT_GDB_FILE (dummy_frame)
{
add_cmd ("dummy-frames", class_maintenance, maintenance_print_dummy_frames,
_("Print the contents of the internal dummy-frame stack."),
diff --git a/gdb/dwarf2/attribute.c b/gdb/dwarf2/attribute.c
index 8ff0353..d2b5364 100644
--- a/gdb/dwarf2/attribute.c
+++ b/gdb/dwarf2/attribute.c
@@ -216,6 +216,22 @@ attribute::signed_constant () const
/* See attribute.h. */
+std::optional<LONGEST>
+attribute::confused_constant () const
+{
+ if (form_is_strictly_signed ())
+ return u.snd;
+ else if (form_is_constant ())
+ return u.unsnd;
+
+ /* For DW_FORM_data16 see attribute::form_is_constant. */
+ complaint (_("Attribute value is not a constant (%s)"),
+ dwarf_form_name (form));
+ return {};
+}
+
+/* See attribute.h. */
+
bool
attribute::form_is_unsigned () const
{
diff --git a/gdb/dwarf2/attribute.h b/gdb/dwarf2/attribute.h
index 31ff018..234de4e 100644
--- a/gdb/dwarf2/attribute.h
+++ b/gdb/dwarf2/attribute.h
@@ -123,6 +123,25 @@ struct attribute
empty value is returned. */
std::optional<LONGEST> signed_constant () const;
+ /* Return a signed constant value. However, for narrow forms like
+ DW_FORM_data1, sign extension is not done.
+
+ DWARF advises compilers to generally use DW_FORM_[su]data to
+ avoid ambiguity. However, both GCC and LLVM ignore this for
+ certain attributes. Furthermore in DWARF, whether a narrower
+ form causes sign-extension depends on the attribute -- for
+ attributes that can only assume non-negative values, sign
+ extension is not done.
+
+ Unfortunately, both compilers also emit certain attributes in a
+ "confused" way, using DW_FORM_sdata for signed values, and
+ possibly choosing a narrow form (e.g., DW_FORM_data1) otherwise
+ -- assuming that sign-extension will not be done.
+
+ This method should only be called when this "confused" treatment
+ is necessary. */
+ std::optional<LONGEST> confused_constant () const;
+
/* Return non-zero if ATTR's value falls in the 'constant' class, or
zero otherwise. When this function returns true, you can apply
the constant_value method to it.
diff --git a/gdb/dwarf2/call-site.h b/gdb/dwarf2/call-site.h
index e02cc5e..2cc4883 100644
--- a/gdb/dwarf2/call-site.h
+++ b/gdb/dwarf2/call-site.h
@@ -198,7 +198,7 @@ struct call_site
struct call_site *tail_call_next = nullptr;
/* * Describe DW_AT_call_target. Missing attribute uses
- FIELD_LOC_KIND_DWARF_BLOCK with FIELD_DWARF_BLOCK == NULL. */
+ m_loc_kind == DWARF_BLOCK with m_loc.dwarf_block == nullptr. */
struct call_site_target target {};
diff --git a/gdb/dwarf2/cooked-index-entry.c b/gdb/dwarf2/cooked-index-entry.c
index 52db851..863ddd6 100644
--- a/gdb/dwarf2/cooked-index-entry.c
+++ b/gdb/dwarf2/cooked-index-entry.c
@@ -33,6 +33,7 @@ to_string (cooked_index_flag flags)
MAP_ENUM_FLAG (IS_LINKAGE),
MAP_ENUM_FLAG (IS_TYPE_DECLARATION),
MAP_ENUM_FLAG (IS_PARENT_DEFERRED),
+ MAP_ENUM_FLAG (IS_SYNTHESIZED),
};
return flags.to_string (mapping);
@@ -233,8 +234,7 @@ cooked_index_entry::write_scope (struct obstack *storage,
obstack_grow (storage, sep, strlen (sep));
}
-void _initialize_dwarf2_entry ();
-void _initialize_dwarf2_entry ()
+INIT_GDB_FILE (dwarf2_entry)
{
#if GDB_SELF_TEST
selftests::register_test ("cooked_index_entry::compare", test_compare);
diff --git a/gdb/dwarf2/cooked-index-worker.c b/gdb/dwarf2/cooked-index-worker.c
index 5d7fc46..09d80ef 100644
--- a/gdb/dwarf2/cooked-index-worker.c
+++ b/gdb/dwarf2/cooked-index-worker.c
@@ -246,7 +246,7 @@ void
cooked_index_worker::done_reading ()
{
{
- scoped_time_it time_it ("DWARF add parent map");
+ scoped_time_it time_it ("DWARF add parent map", m_per_command_time);
for (auto &one_result : m_results)
m_all_parents_map.add_map (*one_result.get_parent_map ());
diff --git a/gdb/dwarf2/cooked-index-worker.h b/gdb/dwarf2/cooked-index-worker.h
index df5c31d..8b9766c 100644
--- a/gdb/dwarf2/cooked-index-worker.h
+++ b/gdb/dwarf2/cooked-index-worker.h
@@ -25,6 +25,8 @@
#include "dwarf2/cooked-index-shard.h"
#include "dwarf2/types.h"
#include "dwarf2/read.h"
+#include "maint.h"
+#include "run-on-main-thread.h"
#if CXX_STD_THREAD
#include <mutex>
@@ -107,11 +109,20 @@ public:
return &m_parent_map;
}
- /* Add an exception to the list of exceptions caught while reading.
- These are passed forward and printed by the main thread. */
- void note_error (gdb_exception &&except)
+ /* Catch exceptions from calling F (), and add them to the list of caught
+ exceptions. These are passed forward and printed by the main thread. */
+ template <typename F>
+ void
+ catch_error (F &&f)
{
- m_exceptions.push_back (std::move (except));
+ try
+ {
+ f ();
+ }
+ catch (gdb_exception &ex)
+ {
+ m_exceptions.push_back (std::move (ex));
+ }
}
/* Called when the thread using this object is done with its work.
@@ -207,8 +218,12 @@ public:
explicit cooked_index_worker (dwarf2_per_objfile *per_objfile)
: m_per_objfile (per_objfile),
- m_cache_store (global_index_cache, per_objfile->per_bfd)
- { }
+ m_cache_store (global_index_cache, per_objfile->per_bfd),
+ m_per_command_time (per_command_time)
+ {
+ /* Make sure we capture per_command_time from the main thread. */
+ gdb_assert (is_main_thread ());
+ }
virtual ~cooked_index_worker ()
{ }
DISABLE_COPY_AND_ASSIGN (cooked_index_worker);
@@ -298,6 +313,9 @@ protected:
std::optional<gdb_exception> m_failed;
/* An object used to write to the index cache. */
index_cache_store_context m_cache_store;
+
+ /* Captured value of per_command_time. */
+ bool m_per_command_time;
};
using cooked_index_worker_up = std::unique_ptr<cooked_index_worker>;
diff --git a/gdb/dwarf2/cooked-index.c b/gdb/dwarf2/cooked-index.c
index 2c7e31e..6209590 100644
--- a/gdb/dwarf2/cooked-index.c
+++ b/gdb/dwarf2/cooked-index.c
@@ -104,7 +104,8 @@ cooked_index::set_contents ()
const parent_map_map *parent_maps = m_state->get_parent_map_map ();
finalizers.add_task ([=] ()
{
- scoped_time_it time_it ("DWARF finalize worker");
+ scoped_time_it time_it ("DWARF finalize worker",
+ m_state->m_per_command_time);
this_shard->finalize (parent_maps);
});
}
@@ -326,9 +327,7 @@ maintenance_wait_for_index_cache (const char *args, int from_tty)
wait_for_index_cache (0);
}
-void _initialize_cooked_index ();
-void
-_initialize_cooked_index ()
+INIT_GDB_FILE (cooked_index)
{
add_cmd ("wait-for-index-cache", class_maintenance,
maintenance_wait_for_index_cache, _("\
diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h
index 9f76789..69f396c 100644
--- a/gdb/dwarf2/cu.h
+++ b/gdb/dwarf2/cu.h
@@ -27,8 +27,6 @@
#include "gdbsupport/unordered_set.h"
#include "dwarf2/die.h"
-struct field_info;
-
/* Type used for delaying computation of method physnames.
See comments for compute_delayed_physnames. */
struct delayed_method_info
@@ -371,7 +369,7 @@ public:
right place. And since the DW_TAG_compile_unit DIE in the split-unit can't
have a DW_AT_ranges attribute, we can use the
- die->tag != DW_AT_compile_unit
+ die->tag != DW_TAG_compile_unit
to determine whether the base should be added or not. */
ULONGEST gnu_ranges_base = 0;
@@ -401,15 +399,6 @@ public:
.debug_str_offsets section (8 or 4, depending on the address size). */
std::optional<ULONGEST> str_offsets_base;
- /* We may encounter a DIE where a property refers to a field in some
- outer type. For example, in Ada, an array length may depend on a
- field in some outer record. In this case, we need to be able to
- stash a pointer to the 'struct field' into the appropriate
- dynamic property baton. However, the fields aren't created until
- the type has been fully processed, so we need a temporary
- back-link to this object. */
- struct field_info *field_info = nullptr;
-
/* Mark used when releasing cached dies. */
bool m_mark : 1;
diff --git a/gdb/dwarf2/dwz.c b/gdb/dwarf2/dwz.c
index 583103b..1aa0d03 100644
--- a/gdb/dwarf2/dwz.c
+++ b/gdb/dwarf2/dwz.c
@@ -56,35 +56,37 @@ dwz_file::read_string (struct objfile *objfile, LONGEST str_offset)
/* A helper function to find the sections for a .dwz file. */
static void
-locate_dwz_sections (struct objfile *objfile, bfd *abfd, asection *sectp,
- dwz_file *dwz_file)
+locate_dwz_sections (objfile *objfile, dwz_file &dwz_file)
{
- dwarf2_section_info *sect = nullptr;
+ for (asection *sec : gdb_bfd_sections (dwz_file.dwz_bfd))
+ {
+ dwarf2_section_info *sect = nullptr;
- /* Note that we only support the standard ELF names, because .dwz
+ /* Note that we only support the standard ELF names, because .dwz
is ELF-only (at the time of writing). */
- if (dwarf2_elf_names.abbrev.matches (sectp->name))
- sect = &dwz_file->abbrev;
- else if (dwarf2_elf_names.info.matches (sectp->name))
- sect = &dwz_file->info;
- else if (dwarf2_elf_names.str.matches (sectp->name))
- sect = &dwz_file->str;
- else if (dwarf2_elf_names.line.matches (sectp->name))
- sect = &dwz_file->line;
- else if (dwarf2_elf_names.macro.matches (sectp->name))
- sect = &dwz_file->macro;
- else if (dwarf2_elf_names.gdb_index.matches (sectp->name))
- sect = &dwz_file->gdb_index;
- else if (dwarf2_elf_names.debug_names.matches (sectp->name))
- sect = &dwz_file->debug_names;
- else if (dwarf2_elf_names.types.matches (sectp->name))
- sect = &dwz_file->types;
-
- if (sect != nullptr)
- {
- sect->s.section = sectp;
- sect->size = bfd_section_size (sectp);
- sect->read (objfile);
+ if (dwarf2_elf_names.abbrev.matches (sec->name))
+ sect = &dwz_file.abbrev;
+ else if (dwarf2_elf_names.info.matches (sec->name))
+ sect = &dwz_file.info;
+ else if (dwarf2_elf_names.str.matches (sec->name))
+ sect = &dwz_file.str;
+ else if (dwarf2_elf_names.line.matches (sec->name))
+ sect = &dwz_file.line;
+ else if (dwarf2_elf_names.macro.matches (sec->name))
+ sect = &dwz_file.macro;
+ else if (dwarf2_elf_names.gdb_index.matches (sec->name))
+ sect = &dwz_file.gdb_index;
+ else if (dwarf2_elf_names.debug_names.matches (sec->name))
+ sect = &dwz_file.debug_names;
+ else if (dwarf2_elf_names.types.matches (sec->name))
+ sect = &dwz_file.types;
+
+ if (sect != nullptr)
+ {
+ sect->s.section = sec;
+ sect->size = bfd_section_size (sec);
+ sect->read (objfile);
+ }
}
}
@@ -341,7 +343,7 @@ dwz_file::read_dwz_file (dwarf2_per_objfile *per_objfile)
{
gdb::unique_xmalloc_ptr<char> abs = gdb_realpath (per_bfd->filename ());
- filename = ldirname (abs.get ()) + SLASH_STRING + filename;
+ filename = gdb_ldirname (abs.get ()) + SLASH_STRING + filename;
}
/* First try the file name given in the section. If that doesn't
@@ -392,9 +394,7 @@ dwz_file::read_dwz_file (dwarf2_per_objfile *per_objfile)
dwz_file_up result (new dwz_file (std::move (dwz_bfd)));
- for (asection *sec : gdb_bfd_sections (result->dwz_bfd))
- locate_dwz_sections (per_objfile->objfile, result->dwz_bfd.get (),
- sec, result.get ());
+ locate_dwz_sections (per_objfile->objfile, *result);
gdb_bfd_record_inclusion (per_bfd->obfd, result->dwz_bfd.get ());
bfd_cache_close (result->dwz_bfd.get ());
diff --git a/gdb/dwarf2/frame-tailcall.c b/gdb/dwarf2/frame-tailcall.c
index 6464ffb..e31ae10 100644
--- a/gdb/dwarf2/frame-tailcall.c
+++ b/gdb/dwarf2/frame-tailcall.c
@@ -478,9 +478,7 @@ const struct frame_unwind_legacy dwarf2_tailcall_frame_unwind (
tailcall_frame_prev_arch
);
-void _initialize_tailcall_frame ();
-void
-_initialize_tailcall_frame ()
+INIT_GDB_FILE (tailcall_frame)
{
cache_htab = htab_create_alloc (50, cache_hash, cache_eq, NULL, xcalloc,
xfree);
diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c
index 1b4de0d..7a37285 100644
--- a/gdb/dwarf2/frame.c
+++ b/gdb/dwarf2/frame.c
@@ -2247,9 +2247,7 @@ dwarf2_build_frame_info (struct objfile *objfile)
set_comp_unit (objfile, unit.release ());
}
-void _initialize_dwarf2_frame ();
-void
-_initialize_dwarf2_frame ()
+INIT_GDB_FILE (dwarf2_frame)
{
#if GDB_SELF_TEST
selftests::register_test_foreach_arch ("execute_cfa_program",
diff --git a/gdb/dwarf2/frame.h b/gdb/dwarf2/frame.h
index f8fd8e8..9357cc1 100644
--- a/gdb/dwarf2/frame.h
+++ b/gdb/dwarf2/frame.h
@@ -198,6 +198,15 @@ struct dwarf2_frame_state
bool armcc_cfa_offsets_reversed = false;
};
+/* If DWARF supoprt was requested, create the real prototype for the
+ append_unwinders function. Otherwise, create a fake inline function.
+
+ There is no need to emit a warning for some of these, because they aren't
+ actively reading DWARF when this is called, they're just initializing GDB.
+
+ These should probably be moved to dwarf2/public.h. */
+#if defined(DWARF_FORMAT_AVAILABLE)
+
/* Set the architecture-specific register state initialization
function for GDBARCH to INIT_REG. */
@@ -287,4 +296,56 @@ extern void *dwarf2_frame_get_fn_data (const frame_info_ptr &this_frame,
void **this_cache,
fn_prev_register cookie);
+#else /* DWARF_FORMAT_AVAILABLE */
+
+static inline void dwarf2_append_unwinders (struct gdbarch *gdbarch) { }
+
+static inline void dwarf2_frame_set_init_reg (
+ gdbarch *gdbarch, void (*init_reg) (struct gdbarch *,int,
+ dwarf2_frame_state_reg *,
+ const frame_info_ptr &)) { }
+
+static inline const struct frame_base *
+ dwarf2_frame_base_sniffer (const frame_info_ptr &this_frame)
+{
+ warning (_("No dwarf support available."));
+ return nullptr;
+}
+
+static inline void dwarf2_frame_set_signal_frame_p
+ (gdbarch *gdbarch, int (*signal_frame_p) (struct gdbarch *,
+ const frame_info_ptr &)) { }
+
+static inline void *dwarf2_frame_get_fn_data (const frame_info_ptr &this_frame,
+ void **this_cache,
+ fn_prev_register cookie)
+{
+ return nullptr;
+}
+
+static inline void *dwarf2_frame_allocate_fn_data
+ (const frame_info_ptr &this_frame, void **this_cache,
+ fn_prev_register cookie, unsigned long size)
+{
+ return nullptr;
+}
+
+static inline int dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc,
+ struct dwarf2_per_cu_data *data,
+ int *regnum_out, LONGEST *offset_out,
+ CORE_ADDR *text_offset_out,
+ const gdb_byte **cfa_start_out,
+ const gdb_byte **cfa_end_out)
+{
+ return 0;
+}
+
+static inline void
+ dwarf2_frame_set_adjust_regnum (struct gdbarch *gdbarch,
+ int (*adjust_regnum) (struct gdbarch *,
+ int, int))
+{}
+
+#endif /* DWARF_FORMAT_AVAILABLE */
+
#endif /* GDB_DWARF2_FRAME_H */
diff --git a/gdb/dwarf2/index-cache.c b/gdb/dwarf2/index-cache.c
index 1715beb..cfe8ce9 100644
--- a/gdb/dwarf2/index-cache.c
+++ b/gdb/dwarf2/index-cache.c
@@ -342,9 +342,7 @@ show_index_cache_stats_command (const char *arg, int from_tty)
indent, global_index_cache.n_misses ());
}
-void _initialize_index_cache ();
-void
-_initialize_index_cache ()
+INIT_GDB_FILE (index_cache)
{
/* Set the default index cache directory. */
std::string cache_dir = get_standard_cache_dir ();
diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c
index 614bdcd..0a3b9d0 100644
--- a/gdb/dwarf2/index-write.c
+++ b/gdb/dwarf2/index-write.c
@@ -1768,9 +1768,7 @@ gdb_index ()
} /* selftests namespace. */
#endif
-void _initialize_dwarf_index_write ();
-void
-_initialize_dwarf_index_write ()
+INIT_GDB_FILE (dwarf_index_write)
{
#if GDB_SELF_TEST
selftests::register_test ("gdb_index", selftests::gdb_index);
diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
index fa1b4eb..37c85d8 100644
--- a/gdb/dwarf2/loc.c
+++ b/gdb/dwarf2/loc.c
@@ -1747,7 +1747,7 @@ dwarf2_evaluate_property (const dynamic_prop *prop,
if (pinfo == NULL)
error (_("cannot find reference address for offset property"));
- struct field resolved_field = *baton->field;
+ struct field resolved_field = baton->field;
resolve_dynamic_field (resolved_field, pinfo, initial_frame);
/* Storage for memory if we need to read it. */
@@ -4154,9 +4154,7 @@ const struct symbol_computed_ops dwarf2_loclist_funcs = {
loclist_generate_c_location
};
-void _initialize_dwarf2loc ();
-void
-_initialize_dwarf2loc ()
+INIT_GDB_FILE (dwarf2loc)
{
add_setshow_zuinteger_cmd ("entry-values", class_maintenance,
&entry_values_debug,
diff --git a/gdb/dwarf2/loc.h b/gdb/dwarf2/loc.h
index ebe5c31..c672320 100644
--- a/gdb/dwarf2/loc.h
+++ b/gdb/dwarf2/loc.h
@@ -20,6 +20,7 @@
#ifndef GDB_DWARF2_LOC_H
#define GDB_DWARF2_LOC_H
+#include "gdbtypes.h"
#include "dwarf2/expr.h"
struct symbol_computed_ops;
@@ -102,28 +103,6 @@ struct property_addr_info
const property_addr_info *next;
};
-/* Converts a dynamic property into a static one. FRAME is the frame in which
- the property is evaluated; if NULL, the selected frame (if any) is used
- instead.
-
- ADDR_STACK is the stack of addresses that might be needed to evaluate the
- property. When evaluating a property that is not related to a type, it can
- be NULL.
-
- Returns true if PROP could be converted and the static value is passed
- back into VALUE, otherwise returns false.
-
- Any values in PUSH_VALUES will be pushed before evaluating the location
- expression, PUSH_VALUES[0] will be pushed first, then PUSH_VALUES[1],
- etc. This means the during evaluation PUSH_VALUES[0] will be at the
- bottom of the stack. */
-
-bool dwarf2_evaluate_property (const struct dynamic_prop *prop,
- const frame_info_ptr &frame,
- const property_addr_info *addr_stack,
- CORE_ADDR *value,
- gdb::array_view<CORE_ADDR> push_values = {});
-
/* A helper for the compiler interface that compiles a single dynamic
property to C code.
@@ -245,7 +224,7 @@ struct dwarf2_property_baton
struct dwarf2_loclist_baton loclist;
/* The location is stored in a field of PROPERTY_TYPE. */
- struct field *field;
+ struct field field;
};
};
@@ -310,8 +289,53 @@ extern struct value *indirect_synthetic_pointer
Function always returns non-NULL value. It throws NO_ENTRY_VALUE_ERROR if
it cannot resolve the parameter for any reason. */
+#if defined(DWARF_FORMAT_AVAILABLE)
+
+/* Converts a dynamic property into a static one. FRAME is the frame in which
+ the property is evaluated; if NULL, the selected frame (if any) is used
+ instead.
+
+ ADDR_STACK is the stack of addresses that might be needed to evaluate the
+ property. When evaluating a property that is not related to a type, it can
+ be NULL.
+
+ Returns true if PROP could be converted and the static value is passed
+ back into VALUE, otherwise returns false.
+
+ Any values in PUSH_VALUES will be pushed before evaluating the location
+ expression, PUSH_VALUES[0] will be pushed first, then PUSH_VALUES[1],
+ etc. This means the during evaluation PUSH_VALUES[0] will be at the
+ bottom of the stack. */
+
+bool dwarf2_evaluate_property (const struct dynamic_prop *prop,
+ const frame_info_ptr &frame,
+ const property_addr_info *addr_stack,
+ CORE_ADDR *value,
+ gdb::array_view<CORE_ADDR> push_values = {});
+
extern struct value *value_of_dwarf_reg_entry (struct type *type,
const frame_info_ptr &frame,
enum call_site_parameter_kind kind,
union call_site_parameter_u kind_u);
+
+#else /* DWARF_FORMAT_AVAILABLE */
+
+static inline bool
+dwarf2_evaluate_property (const struct dynamic_prop *, const frame_info_ptr &,
+ const property_addr_info *, CORE_ADDR *,
+ gdb::array_view<CORE_ADDR> = {})
+{
+ return false;
+}
+
+static inline struct value *
+value_of_dwarf_reg_entry (struct type *type, const frame_info_ptr &frame,
+ enum call_site_parameter_kind kind,
+ union call_site_parameter_u kind_u)
+{
+ error (_("No dwarf support available."));
+}
+
+#endif /* DWARF_FORMAT_AVAILABLE */
+
#endif /* GDB_DWARF2_LOC_H */
diff --git a/gdb/dwarf2/public.h b/gdb/dwarf2/public.h
index ed504c6..f9e7488 100644
--- a/gdb/dwarf2/public.h
+++ b/gdb/dwarf2/public.h
@@ -30,6 +30,8 @@ enum class dw_index_kind
DEBUG_NAMES,
};
+#if defined(DWARF_FORMAT_AVAILABLE)
+
/* Try to locate the sections we need for DWARF 2 debugging
information. If these are found, begin reading the DWARF and
return true. Otherwise, return false. NAMES points to the dwarf2
@@ -44,4 +46,27 @@ extern bool dwarf2_initialize_objfile
extern void dwarf2_build_frame_info (struct objfile *);
+/* Append the DWARF-2 frame unwinders to GDBARCH's list. */
+
+void dwarf2_append_unwinders (struct gdbarch *gdbarch);
+
+#else /* DWARF_FORMAT_AVAILABLE */
+
+static inline bool
+dwarf2_initialize_objfile (struct objfile *,
+ const struct dwarf2_debug_sections * = nullptr,
+ bool = false)
+{
+ warning (_("No dwarf support available."));
+ return false;
+}
+
+static inline void
+dwarf2_build_frame_info (struct objfile *)
+{
+ warning (_("No dwarf support available."));
+}
+
+#endif /* DWARF_FORMAT_AVAILABLE */
+
#endif /* GDB_DWARF2_PUBLIC_H */
diff --git a/gdb/dwarf2/read-debug-names.c b/gdb/dwarf2/read-debug-names.c
index 11de986..4b3f385 100644
--- a/gdb/dwarf2/read-debug-names.c
+++ b/gdb/dwarf2/read-debug-names.c
@@ -241,7 +241,7 @@ mapped_debug_names_reader::scan_one_entry (const char *name,
continue;
}
}
- per_cu = per_objfile->per_bfd->get_cu (ull);
+ per_cu = per_objfile->per_bfd->get_unit (ull);
break;
case DW_IDX_type_unit:
/* Don't crash on bad data. */
@@ -255,7 +255,7 @@ mapped_debug_names_reader::scan_one_entry (const char *name,
}
{
int nr_cus = per_objfile->per_bfd->all_comp_units.size ();
- per_cu = per_objfile->per_bfd->get_cu (nr_cus + ull);
+ per_cu = per_objfile->per_bfd->get_unit (nr_cus + ull);
}
break;
case DW_IDX_die_offset:
@@ -263,7 +263,7 @@ mapped_debug_names_reader::scan_one_entry (const char *name,
/* In a per-CU index (as opposed to a per-module index), index
entries without CU attribute implicitly refer to the single CU. */
if (per_cu == NULL)
- per_cu = per_objfile->per_bfd->get_cu (0);
+ per_cu = per_objfile->per_bfd->get_unit (0);
break;
case DW_IDX_parent:
parent = ull;
@@ -416,15 +416,11 @@ cooked_index_worker_debug_names::do_reading ()
{
complaint_interceptor complaint_handler;
- try
+ /* Arbitrarily put all exceptions into the first result. */
+ m_map.indices[0].catch_error ([&] ()
{
m_map.scan_all_names ();
- }
- catch (gdb_exception &exc)
- {
- /* Arbitrarily put all exceptions into the first result. */
- m_map.indices[0].note_error (std::move (exc));
- }
+ });
bool first = true;
for (auto &iter : m_map.indices)
@@ -470,7 +466,7 @@ check_signatured_type_table_from_debug_names
bool found = false;
for (; j < nr_cus_tus; j++)
- if (per_bfd->get_cu (j)->sect_off == sect_off)
+ if (per_bfd->get_unit (j)->sect_off == sect_off)
{
found = true;
break;
@@ -481,7 +477,7 @@ check_signatured_type_table_from_debug_names
" ignoring .debug_names."));
return false;
}
- per_bfd->all_comp_units_index_tus.push_back (per_bfd->get_cu (j));
+ per_bfd->all_comp_units_index_tus.push_back (per_bfd->get_unit (j));
}
return true;
}
@@ -723,7 +719,7 @@ check_cus_from_debug_names_list (dwarf2_per_bfd *per_bfd,
map.dwarf5_byte_order));
bool found = false;
for (; j < nr_cus; j++)
- if (per_bfd->get_cu (j)->sect_off == sect_off)
+ if (per_bfd->get_unit (j)->sect_off == sect_off)
{
found = true;
break;
@@ -734,7 +730,7 @@ check_cus_from_debug_names_list (dwarf2_per_bfd *per_bfd,
" ignoring .debug_names."));
return false;
}
- per_bfd->all_comp_units_index_cus.push_back (per_bfd->get_cu (j));
+ per_bfd->all_comp_units_index_cus.push_back (per_bfd->get_unit (j));
}
return true;
}
@@ -753,7 +749,7 @@ check_cus_from_debug_names_list (dwarf2_per_bfd *per_bfd,
(map.cu_table_reordered + i * map.offset_size,
map.offset_size,
map.dwarf5_byte_order));
- if (sect_off != per_bfd->get_cu (i)->sect_off)
+ if (sect_off != per_bfd->get_unit (i)->sect_off)
{
warning (_("Section .debug_names has incorrect entry in CU table,"
" ignoring .debug_names."));
diff --git a/gdb/dwarf2/read-gdb-index.c b/gdb/dwarf2/read-gdb-index.c
index 2029c3e..464fbdd 100644
--- a/gdb/dwarf2/read-gdb-index.c
+++ b/gdb/dwarf2/read-gdb-index.c
@@ -1113,7 +1113,7 @@ dw2_expand_marked_cus (dwarf2_per_objfile *per_objfile, offset_type idx,
continue;
}
- dwarf2_per_cu *per_cu = per_objfile->per_bfd->get_cu (cu_index);
+ dwarf2_per_cu *per_cu = per_objfile->per_bfd->get_unit (cu_index);
if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile, file_matcher,
expansion_notify, lang_matcher))
@@ -1426,7 +1426,7 @@ create_addrmap_from_gdb_index (dwarf2_per_objfile *per_objfile,
continue;
}
- mutable_map.set_empty (lo, hi - 1, per_bfd->get_cu (cu_index));
+ mutable_map.set_empty (lo, hi - 1, per_bfd->get_unit (cu_index));
}
index->index_addrmap
@@ -1562,10 +1562,7 @@ dwarf2_read_gdb_index
return true;
}
-void _initialize_read_gdb_index ();
-
-void
-_initialize_read_gdb_index ()
+INIT_GDB_FILE (read_gdb_index)
{
add_setshow_boolean_cmd ("use-deprecated-index-sections",
no_class, &use_deprecated_index_sections, _("\
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 71fa793..5e18e45 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -289,24 +289,29 @@ struct dwo_sections
struct dwo_unit
{
/* Backlink to the containing struct dwo_file. */
- struct dwo_file *dwo_file;
+ struct dwo_file *dwo_file = nullptr;
/* The "id" that distinguishes this CU/TU.
.debug_info calls this "dwo_id", .debug_types calls this "signature".
Since signatures came first, we stick with it for consistency. */
- ULONGEST signature;
+ ULONGEST signature = 0;
/* The section this CU/TU lives in, in the DWO file. */
- struct dwarf2_section_info *section;
+ dwarf2_section_info *section = nullptr;
+
+ /* This is set if SECTION is owned by this dwo_unit. */
+ dwarf2_section_info_up section_holder;
/* Same as dwarf2_per_cu::{sect_off,length} but in the DWO section. */
- sect_offset sect_off;
- unsigned int length;
+ sect_offset sect_off {};
+ unsigned int length = 0;
/* For types, offset in the type's DIE of the type defined by this TU. */
cu_offset type_offset_in_tu;
};
+using dwo_unit_up = std::unique_ptr<dwo_unit>;
+
/* Hash function for dwo_unit objects, based on the signature. */
struct dwo_unit_hash
@@ -316,7 +321,7 @@ struct dwo_unit_hash
std::size_t operator() (ULONGEST signature) const noexcept
{ return signature; }
- std::size_t operator() (const dwo_unit *unit) const noexcept
+ std::size_t operator() (const dwo_unit_up &unit) const noexcept
{ return (*this) (unit->signature); }
};
@@ -330,16 +335,16 @@ struct dwo_unit_eq
{
using is_transparent = void;
- bool operator() (ULONGEST sig, const dwo_unit *unit) const noexcept
+ bool operator() (ULONGEST sig, const dwo_unit_up &unit) const noexcept
{ return sig == unit->signature; }
- bool operator() (const dwo_unit *a, const dwo_unit *b) const noexcept
+ bool operator() (const dwo_unit_up &a, const dwo_unit_up &b) const noexcept
{ return (*this) (a->signature, b); }
};
/* Set of dwo_unit object, using their signature as identity. */
-using dwo_unit_set = gdb::unordered_set<dwo_unit *, dwo_unit_hash, dwo_unit_eq>;
+using dwo_unit_set = gdb::unordered_set<dwo_unit_up, dwo_unit_hash, dwo_unit_eq>;
/* include/dwarf2.h defines the DWP section codes.
It defines a max value but it doesn't define a min value, which we
@@ -599,6 +604,11 @@ struct dwp_file
dwo_unit_set loaded_cus;
dwo_unit_set loaded_tus;
+#if CXX_STD_THREAD
+ /* Mutex to synchronize access to LOADED_CUS and LOADED_TUS. */
+ std::mutex loaded_cutus_lock;
+#endif
+
/* Table to map ELF section numbers to their sections.
This is only needed for the DWP V1 file format. */
unsigned int num_sections = 0;
@@ -698,12 +708,6 @@ struct field_info
we're reading. */
std::vector<variant_part_builder> variant_parts;
- /* All the field batons that must be updated. This is only used
- when a type's property depends on a field of this structure; for
- example in Ada when an array's length may come from a field of an
- enclosing record. */
- gdb::unordered_map<dwarf2_property_baton *, sect_offset> field_batons;
-
/* Return the total number of fields (including baseclasses). */
int nfields () const
{
@@ -1897,13 +1901,13 @@ dwarf2_base_index_functions::print_stats (struct objfile *objfile,
for (int i = 0; i < total; ++i)
{
- dwarf2_per_cu *per_cu = per_objfile->per_bfd->get_cu (i);
+ dwarf2_per_cu *per_cu = per_objfile->per_bfd->get_unit (i);
if (!per_objfile->symtab_set_p (per_cu))
++count;
}
- gdb_printf (_(" Number of read CUs: %d\n"), total - count);
- gdb_printf (_(" Number of unread CUs: %d\n"), count);
+ gdb_printf (_(" Number of read units: %d\n"), total - count);
+ gdb_printf (_(" Number of unread units: %d\n"), count);
}
void
@@ -2493,7 +2497,7 @@ lookup_dwo_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
if (it == dwo_file->tus.end ())
return nullptr;
- dwo_unit *dwo_entry = *it;
+ dwo_unit *dwo_entry = it->get ();
/* If the global table doesn't have an entry for this TU, add one. */
if (sig_type_it == per_bfd->signatured_types.end ())
@@ -2783,13 +2787,6 @@ dwo_unit *
cutu_reader::lookup_dwo_unit (dwarf2_cu *cu, die_info *comp_unit_die,
const char *dwo_name)
{
-#if CXX_STD_THREAD
- /* We need a lock here to handle the DWO hash table. */
- static std::mutex dwo_lock;
-
- std::lock_guard<std::mutex> guard (dwo_lock);
-#endif
-
dwarf2_per_cu *per_cu = cu->per_cu;
struct dwo_unit *dwo_unit;
const char *comp_dir;
@@ -3428,7 +3425,10 @@ cooked_index_worker_debug_info::process_type_units
abbrev_table.get (), nullptr, false,
language_minimal);
if (!reader.is_dummy ())
- process_type_unit (&reader, storage);
+ storage->catch_error ([&] ()
+ {
+ process_type_unit (&reader, storage);
+ });
}
}
@@ -3464,13 +3464,16 @@ void
cooked_index_worker_debug_info::process_skeletonless_type_units
(dwarf2_per_objfile *per_objfile, cooked_index_worker_result *storage)
{
- scoped_time_it time_it ("DWARF skeletonless type units");
+ scoped_time_it time_it ("DWARF skeletonless type units", m_per_command_time);
/* Skeletonless TUs in DWP files without .gdb_index is not supported yet. */
if (per_objfile->per_bfd->dwp_file == nullptr)
for (const dwo_file_up &file : per_objfile->per_bfd->dwo_files)
- for (dwo_unit *unit : file->tus)
- process_skeletonless_type_unit (unit, per_objfile, storage);
+ for (const dwo_unit_up &unit : file->tus)
+ storage->catch_error ([&] ()
+ {
+ process_skeletonless_type_unit (unit.get (), per_objfile, storage);
+ });
}
void
@@ -3489,14 +3492,10 @@ cooked_index_worker_debug_info::process_units (size_t task_number,
{
dwarf2_per_cu *per_cu = inner->get ();
- try
+ thread_storage.catch_error ([&] ()
{
process_unit (per_cu, m_per_objfile, &thread_storage);
- }
- catch (gdb_exception &except)
- {
- thread_storage.note_error (std::move (except));
- }
+ });
}
thread_storage.done_reading (complaint_handler.release ());
@@ -3574,7 +3573,7 @@ cooked_index_worker_debug_info::do_reading ()
gdb_assert (iter != last);
workers.add_task ([this, task_count, iter, last] ()
{
- scoped_time_it time_it ("DWARF indexing worker");
+ scoped_time_it time_it ("DWARF indexing worker", m_per_command_time);
process_units (task_count, iter, last);
});
@@ -5859,7 +5858,7 @@ find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu)
&& res.get_name () != nullptr
&& IS_ABSOLUTE_PATH (res.get_name ()))
{
- res.set_comp_dir (ldirname (res.get_name ()));
+ res.set_comp_dir (gdb_ldirname (res.get_name ()));
res.set_name (make_unique_xstrdup (lbasename (res.get_name ())));
}
@@ -6206,11 +6205,33 @@ static dwo_file *
lookup_dwo_file (dwarf2_per_bfd *per_bfd, const char *dwo_name,
const char *comp_dir)
{
+#if CXX_STD_THREAD
+ std::lock_guard<std::mutex> guard (per_bfd->dwo_files_lock);
+#endif
+
auto it = per_bfd->dwo_files.find (dwo_file_search {dwo_name, comp_dir});
return it != per_bfd->dwo_files.end () ? it->get() : nullptr;
}
+/* Add DWO_FILE to the per-BFD DWO file hash table.
+
+ Return the dwo_file actually kept in the hash table.
+
+ If another thread raced with this one, opening the exact same DWO file and
+ inserting it first in the hash table, then keep that other thread's copy
+ and DWO_FILE gets freed. */
+
+static dwo_file *
+add_dwo_file (dwarf2_per_bfd *per_bfd, dwo_file_up dwo_file)
+{
+#if CXX_STD_THREAD
+ std::lock_guard<std::mutex> lock (per_bfd->dwo_files_lock);
+#endif
+
+ return per_bfd->dwo_files.emplace (std::move (dwo_file)).first->get ();
+}
+
void
cutu_reader::create_dwo_unit_hash_tables (dwo_file &dwo_file,
dwarf2_cu &skeleton_cu,
@@ -6289,7 +6310,7 @@ cutu_reader::create_dwo_unit_hash_tables (dwo_file &dwo_file,
else
signature = header.signature;
- dwo_unit *dwo_unit = OBSTACK_ZALLOC (&per_bfd.obstack, struct dwo_unit);
+ auto dwo_unit = std::make_unique<struct dwo_unit> ();
/* Set the fields common to compile and type units. */
dwo_unit->dwo_file = &dwo_file;
@@ -6307,7 +6328,7 @@ cutu_reader::create_dwo_unit_hash_tables (dwo_file &dwo_file,
sect_offset_str (sect_off),
hex_string (dwo_unit->signature));
- auto [it, inserted] = dwo_file.cus.emplace (dwo_unit);
+ auto [it, inserted] = dwo_file.cus.emplace (std::move (dwo_unit));
if (!inserted)
complaint (_("debug cu entry at offset %s is duplicate to"
" the entry at offset %s, signature %s"),
@@ -6326,7 +6347,7 @@ cutu_reader::create_dwo_unit_hash_tables (dwo_file &dwo_file,
sect_offset_str (sect_off),
hex_string (dwo_unit->signature));
- auto [it, inserted] = dwo_file.tus.emplace (dwo_unit);
+ auto [it, inserted] = dwo_file.tus.emplace (std::move (dwo_unit));
if (!inserted)
complaint (_("debug type entry at offset %s is duplicate to"
" the entry at offset %s, signature %s"),
@@ -6807,7 +6828,7 @@ locate_v1_virtual_dwo_sections (asection *sectp,
COMP_DIR is the DW_AT_comp_dir attribute of the referencing CU.
This is for DWP version 1 files. */
-static struct dwo_unit *
+static dwo_unit_up
create_dwo_unit_in_dwp_v1 (dwarf2_per_bfd *per_bfd,
struct dwp_file *dwp_file,
uint32_t unit_index,
@@ -6930,19 +6951,17 @@ create_dwo_unit_in_dwp_v1 (dwarf2_per_bfd *per_bfd,
types we'll grow the vector and eventually have to reallocate space
for it, invalidating all copies of pointers into the previous
contents. */
- auto [it, inserted]
- = per_bfd->dwo_files.emplace (std::move (new_dwo_file));
- gdb_assert (inserted);
- dwo_file = it->get ();
+ dwo_file = add_dwo_file (per_bfd, std::move (new_dwo_file));
}
else
dwarf_read_debug_printf ("Using existing virtual DWO: %s",
virtual_dwo_name.c_str ());
- dwo_unit *dwo_unit = OBSTACK_ZALLOC (&per_bfd->obstack, struct dwo_unit);
+ auto dwo_unit = std::make_unique<struct dwo_unit> ();
dwo_unit->dwo_file = dwo_file;
dwo_unit->signature = signature;
- dwo_unit->section = XOBNEW (&per_bfd->obstack, struct dwarf2_section_info);
+ dwo_unit->section_holder = std::make_unique<dwarf2_section_info> ();
+ dwo_unit->section = dwo_unit->section_holder.get ();
*dwo_unit->section = sections.info_or_types;
/* dwo_unit->{offset,length,type_offset_in_tu} are set later. */
@@ -7000,7 +7019,7 @@ create_dwp_v2_or_v5_section (dwarf2_per_bfd *per_bfd,
COMP_DIR is the DW_AT_comp_dir attribute of the referencing CU.
This is for DWP version 2 files. */
-static struct dwo_unit *
+static dwo_unit_up
create_dwo_unit_in_dwp_v2 (dwarf2_per_bfd *per_bfd,
struct dwp_file *dwp_file,
uint32_t unit_index,
@@ -7135,19 +7154,17 @@ create_dwo_unit_in_dwp_v2 (dwarf2_per_bfd *per_bfd,
types we'll grow the vector and eventually have to reallocate space
for it, invalidating all copies of pointers into the previous
contents. */
- auto [it, inserted]
- = per_bfd->dwo_files.emplace (std::move (new_dwo_file));
- gdb_assert (inserted);
- dwo_file = it->get ();
+ dwo_file = add_dwo_file (per_bfd, std::move (new_dwo_file));
}
else
dwarf_read_debug_printf ("Using existing virtual DWO: %s",
virtual_dwo_name.c_str ());
- dwo_unit *dwo_unit = OBSTACK_ZALLOC (&per_bfd->obstack, struct dwo_unit);
+ auto dwo_unit = std::make_unique<struct dwo_unit> ();
dwo_unit->dwo_file = dwo_file;
dwo_unit->signature = signature;
- dwo_unit->section = XOBNEW (&per_bfd->obstack, struct dwarf2_section_info);
+ dwo_unit->section_holder = std::make_unique<dwarf2_section_info> ();
+ dwo_unit->section = dwo_unit->section_holder.get ();
*dwo_unit->section = create_dwp_v2_or_v5_section
(per_bfd,
is_debug_types
@@ -7165,7 +7182,7 @@ create_dwo_unit_in_dwp_v2 (dwarf2_per_bfd *per_bfd,
COMP_DIR is the DW_AT_comp_dir attribute of the referencing CU.
This is for DWP version 5 files. */
-static struct dwo_unit *
+static dwo_unit_up
create_dwo_unit_in_dwp_v5 (dwarf2_per_bfd *per_bfd,
struct dwp_file *dwp_file,
uint32_t unit_index,
@@ -7305,16 +7322,13 @@ create_dwo_unit_in_dwp_v5 (dwarf2_per_bfd *per_bfd,
types we'll grow the vector and eventually have to reallocate space
for it, invalidating all copies of pointers into the previous
contents. */
- auto [it, inserted]
- = per_bfd->dwo_files.emplace (std::move (new_dwo_file));
- gdb_assert (inserted);
- dwo_file = it->get ();
+ dwo_file = add_dwo_file (per_bfd, std::move (new_dwo_file));
}
else
dwarf_read_debug_printf ("Using existing virtual DWO: %s",
virtual_dwo_name.c_str ());
- dwo_unit *dwo_unit = OBSTACK_ZALLOC (&per_bfd->obstack, struct dwo_unit);
+ auto dwo_unit = std::make_unique<struct dwo_unit> ();
dwo_unit->dwo_file = dwo_file;
dwo_unit->signature = signature;
dwo_unit->section
@@ -7345,9 +7359,15 @@ lookup_dwo_unit_in_dwp (dwarf2_per_bfd *per_bfd,
auto &dwo_unit_set
= is_debug_types ? dwp_file->loaded_tus : dwp_file->loaded_cus;
- if (auto it = dwo_unit_set.find (signature);
- it != dwo_unit_set.end ())
- return *it;
+ {
+#if CXX_STD_THREAD
+ std::lock_guard<std::mutex> guard (dwp_file->loaded_cutus_lock);
+#endif
+
+ if (auto it = dwo_unit_set.find (signature);
+ it != dwo_unit_set.end ())
+ return it->get ();
+ }
/* Use a for loop so that we don't loop forever on bad debug info. */
for (unsigned int i = 0; i < dwp_htab->nr_slots; ++i)
@@ -7361,7 +7381,7 @@ lookup_dwo_unit_in_dwp (dwarf2_per_bfd *per_bfd,
uint32_t unit_index =
read_4_bytes (dbfd,
dwp_htab->unit_table + hash * sizeof (uint32_t));
- dwo_unit *dwo_unit;
+ dwo_unit_up dwo_unit;
if (dwp_file->version == 1)
dwo_unit
@@ -7376,9 +7396,14 @@ lookup_dwo_unit_in_dwp (dwarf2_per_bfd *per_bfd,
= create_dwo_unit_in_dwp_v5 (per_bfd, dwp_file, unit_index,
comp_dir, signature, is_debug_types);
- auto [it, inserted] = dwo_unit_set.emplace (dwo_unit);
- gdb_assert (inserted);
- return *it;
+ /* If another thread raced with this one, opening the exact same
+ DWO unit, then we'll keep that other thread's copy. */
+#if CXX_STD_THREAD
+ std::lock_guard<std::mutex> guard (dwp_file->loaded_cutus_lock);
+#endif
+
+ auto it = dwo_unit_set.emplace (std::move (dwo_unit)).first;
+ return it->get ();
}
if (signature_in_table == 0)
@@ -7434,7 +7459,7 @@ try_open_dwop_file (dwarf2_per_bfd *per_bfd, const char *file_name, int is_dwp,
search_path = per_bfd->captured_debug_dir.c_str ();
/* Add the path for the executable binary to the list of search paths. */
- std::string objfile_dir = ldirname (per_bfd->filename ());
+ std::string objfile_dir = gdb_ldirname (per_bfd->filename ());
search_path_holder.reset (concat (objfile_dir.c_str (),
dirname_separator_string,
search_path, nullptr));
@@ -7455,14 +7480,23 @@ try_open_dwop_file (dwarf2_per_bfd *per_bfd, const char *file_name, int is_dwp,
if (sym_bfd == NULL)
return NULL;
- if (!bfd_check_format (sym_bfd.get (), bfd_object))
- return NULL;
+ {
+#if CXX_STD_THREAD
+ /* The operations below are not thread-safe, use a lock to synchronize
+ concurrent accesses. */
+ static std::mutex mutex;
+ std::lock_guard<std::mutex> lock (mutex);
+#endif
+
+ if (!bfd_check_format (sym_bfd.get (), bfd_object))
+ return NULL;
- /* Success. Record the bfd as having been included by the objfile's bfd.
+ /* Success. Record the bfd as having been included by the objfile's bfd.
This is important because things like demangled_names_hash lives in the
objfile's per_bfd space and may have references to things like symbol
names that live in the DWO/DWP file's per_bfd space. PR 16426. */
- gdb_bfd_record_inclusion (per_bfd->obfd, sym_bfd.get ());
+ gdb_bfd_record_inclusion (per_bfd->obfd, sym_bfd.get ());
+ }
return sym_bfd;
}
@@ -7512,45 +7546,66 @@ cutu_reader::open_dwo_file (dwarf2_per_bfd *per_bfd, const char *file_name,
size of each of the DWO debugging sections we are interested in. */
void
-cutu_reader::locate_dwo_sections (struct objfile *objfile, bfd *abfd,
- asection *sectp, dwo_sections *dwo_sections)
+cutu_reader::locate_dwo_sections (objfile *objfile, dwo_file &dwo_file)
{
const struct dwop_section_names *names = &dwop_section_names;
+ dwo_sections &dwo_sections = dwo_file.sections;
+ bool complained_about_macro_already = false;
+
+ for (asection *sec : gdb_bfd_sections (dwo_file.dbfd))
+ {
+ struct dwarf2_section_info *dw_sect = nullptr;
+
+ if (names->abbrev_dwo.matches (sec->name))
+ dw_sect = &dwo_sections.abbrev;
+ else if (names->info_dwo.matches (sec->name))
+ dw_sect = &dwo_sections.infos.emplace_back (dwarf2_section_info {});
+ else if (names->line_dwo.matches (sec->name))
+ dw_sect = &dwo_sections.line;
+ else if (names->loc_dwo.matches (sec->name))
+ dw_sect = &dwo_sections.loc;
+ else if (names->loclists_dwo.matches (sec->name))
+ dw_sect = &dwo_sections.loclists;
+ else if (names->macinfo_dwo.matches (sec->name))
+ dw_sect = &dwo_sections.macinfo;
+ else if (names->macro_dwo.matches (sec->name))
+ {
+ /* gcc versions <= 13 generate multiple .debug_macro.dwo sections with
+ some unresolved links between them. It's not usable, so do as if
+ there were not there. */
+ if (!complained_about_macro_already)
+ {
+ if (dwo_sections.macro.s.section == nullptr)
+ dw_sect = &dwo_sections.macro;
+ else
+ {
+ warning (_("Multiple .debug_macro.dwo sections found in "
+ "%s, ignoring them."), dwo_file.dbfd->filename);
- struct dwarf2_section_info *dw_sect = nullptr;
-
- if (names->abbrev_dwo.matches (sectp->name))
- dw_sect = &dwo_sections->abbrev;
- else if (names->info_dwo.matches (sectp->name))
- dw_sect = &dwo_sections->infos.emplace_back (dwarf2_section_info {});
- else if (names->line_dwo.matches (sectp->name))
- dw_sect = &dwo_sections->line;
- else if (names->loc_dwo.matches (sectp->name))
- dw_sect = &dwo_sections->loc;
- else if (names->loclists_dwo.matches (sectp->name))
- dw_sect = &dwo_sections->loclists;
- else if (names->macinfo_dwo.matches (sectp->name))
- dw_sect = &dwo_sections->macinfo;
- else if (names->macro_dwo.matches (sectp->name))
- dw_sect = &dwo_sections->macro;
- else if (names->rnglists_dwo.matches (sectp->name))
- dw_sect = &dwo_sections->rnglists;
- else if (names->str_dwo.matches (sectp->name))
- dw_sect = &dwo_sections->str;
- else if (names->str_offsets_dwo.matches (sectp->name))
- dw_sect = &dwo_sections->str_offsets;
- else if (names->types_dwo.matches (sectp->name))
- dw_sect = &dwo_sections->types.emplace_back (dwarf2_section_info {});
-
- if (dw_sect != nullptr)
- {
- /* Make sure we don't overwrite a section info that has been filled in
+ dwo_sections.macro = dwarf2_section_info {};
+ complained_about_macro_already = true;
+ }
+ }
+ }
+ else if (names->rnglists_dwo.matches (sec->name))
+ dw_sect = &dwo_sections.rnglists;
+ else if (names->str_dwo.matches (sec->name))
+ dw_sect = &dwo_sections.str;
+ else if (names->str_offsets_dwo.matches (sec->name))
+ dw_sect = &dwo_sections.str_offsets;
+ else if (names->types_dwo.matches (sec->name))
+ dw_sect = &dwo_sections.types.emplace_back (dwarf2_section_info {});
+
+ if (dw_sect != nullptr)
+ {
+ /* Make sure we don't overwrite a section info that has been filled in
already. */
- gdb_assert (!dw_sect->readin);
+ gdb_assert (!dw_sect->readin);
- dw_sect->s.section = sectp;
- dw_sect->size = bfd_section_size (sectp);
- dw_sect->read (objfile);
+ dw_sect->s.section = sec;
+ dw_sect->size = bfd_section_size (sec);
+ dw_sect->read (objfile);
+ }
}
}
@@ -7578,15 +7633,8 @@ cutu_reader::open_and_init_dwo_file (dwarf2_cu *cu, const char *dwo_name,
dwo_file->comp_dir = comp_dir;
dwo_file->dbfd = std::move (dbfd);
- for (asection *sec : gdb_bfd_sections (dwo_file->dbfd))
- this->locate_dwo_sections (per_objfile->objfile, dwo_file->dbfd.get (), sec,
- &dwo_file->sections);
+ this->locate_dwo_sections (per_objfile->objfile, *dwo_file);
- /* There is normally just one .debug_info.dwo section in a DWO file. But when
- building with -fdebug-types-section, gcc produces multiple .debug_info.dwo
- sections. One for each produced type unit and one for the compile unit.
- This is not expected, but we can easily enough deal with what gcc
- produces. This behavior has been observed with gcc 14.2.1. */
for (dwarf2_section_info &section : dwo_file->sections.infos)
create_dwo_unit_hash_tables (*dwo_file, *cu, section, ruh_kind::COMPILE);
@@ -7788,7 +7836,7 @@ open_and_init_dwp_file (dwarf2_per_objfile *per_objfile)
struct objfile *backlink = objfile->separate_debug_objfile_backlink;
const char *backlink_basename = lbasename (backlink->original_name);
- dwp_name = ldirname (objfile->original_name) + SLASH_STRING + backlink_basename;
+ dwp_name = gdb_ldirname (objfile->original_name) + SLASH_STRING + backlink_basename;
}
else
dwp_name = objfile->original_name;
@@ -7938,12 +7986,7 @@ cutu_reader::lookup_dwo_cutu (dwarf2_cu *cu, const char *dwo_name,
= open_and_init_dwo_file (cu, dwo_name, comp_dir);
if (new_dwo_file != nullptr)
- {
- auto [it, inserted]
- = per_bfd->dwo_files.emplace (std::move (new_dwo_file));
- gdb_assert (inserted);
- dwo_file = (*it).get ();
- }
+ dwo_file = add_dwo_file (per_bfd, std::move (new_dwo_file));
}
if (dwo_file != NULL)
@@ -7954,13 +7997,13 @@ cutu_reader::lookup_dwo_cutu (dwarf2_cu *cu, const char *dwo_name,
{
if (auto it = dwo_file->tus.find (signature);
it != dwo_file->tus.end ())
- dwo_cutu = *it;
+ dwo_cutu = it->get ();
}
else if (!is_debug_types && !dwo_file->cus.empty ())
{
if (auto it = dwo_file->cus.find (signature);
it != dwo_file->cus.end ())
- dwo_cutu = *it;
+ dwo_cutu = it->get ();
}
if (dwo_cutu != NULL)
@@ -8067,8 +8110,8 @@ queue_and_load_all_dwo_tus (dwarf2_cu *cu)
dwo_file = dwo_unit->dwo_file;
- for (struct dwo_unit *unit : dwo_file->tus)
- queue_and_load_dwo_tu (unit, cu);
+ for (const dwo_unit_up &unit : dwo_file->tus)
+ queue_and_load_dwo_tu (unit.get (), cu);
}
/* Read in various DIEs. */
@@ -9888,7 +9931,7 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu,
if (attr2 != nullptr && attr2->form_is_constant ())
{
has_bit_offset = true;
- bit_offset = attr2->unsigned_constant ().value_or (0);
+ bit_offset = attr2->confused_constant ().value_or (0);
attr2 = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr2 != nullptr && attr2->form_is_constant ())
{
@@ -9901,7 +9944,7 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu,
if (attr->form_is_constant ())
{
- LONGEST offset = attr->unsigned_constant ().value_or (0);
+ LONGEST offset = attr->confused_constant ().value_or (0);
/* Work around this GCC 11 bug, where it would erroneously use -1
data member locations, instead of 0:
@@ -9951,7 +9994,7 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu,
dlbaton->per_objfile = per_objfile;
dlbaton->per_cu = cu->per_cu;
- field->set_loc_dwarf_block (dlbaton);
+ field->set_loc_dwarf_block_addr (dlbaton);
}
}
else
@@ -9962,10 +10005,54 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu,
{
attr = dwarf2_attr (die, DW_AT_data_bit_offset, cu);
if (attr != nullptr)
- field->set_loc_bitpos (attr->unsigned_constant ().value_or (0));
+ {
+ if (attr->form_is_constant ())
+ field->set_loc_bitpos (attr->unsigned_constant ().value_or (0));
+ else if (attr->form_is_block ())
+ {
+ /* This is a DWARF extension. See
+ https://dwarfstd.org/issues/250501.1.html. */
+ dwarf2_per_objfile *per_objfile = cu->per_objfile;
+ dwarf2_locexpr_baton *dlbaton
+ = OBSTACK_ZALLOC (&per_objfile->objfile->objfile_obstack,
+ dwarf2_locexpr_baton);
+ dlbaton->data = attr->as_block ()->data;
+ dlbaton->size = attr->as_block ()->size;
+ dlbaton->per_objfile = per_objfile;
+ dlbaton->per_cu = cu->per_cu;
+
+ field->set_loc_dwarf_block_bitpos (dlbaton);
+ }
+ else
+ complaint (_("Unsupported form %s for DW_AT_data_bit_offset"),
+ dwarf_form_name (attr->form));
+ }
}
}
+/* A helper that computes the location of a field. The CU and the
+ DW_TAG_member DIE are passed in. The results are stored in
+ *FP. */
+
+static void
+compute_field_location (dwarf2_cu *cu, die_info *die, field *fp)
+{
+ /* Get type of field. */
+ fp->set_type (die_type (die, cu));
+
+ fp->set_loc_bitpos (0);
+
+ /* Get bit size of field (zero if none). */
+ attribute *attr = dwarf2_attr (die, DW_AT_bit_size, cu);
+ if (attr != nullptr)
+ fp->set_bitsize (attr->unsigned_constant ().value_or (0));
+ else
+ fp->set_bitsize (0);
+
+ /* Get bit offset of field. */
+ handle_member_location (die, cu, fp);
+}
+
/* Add an aggregate field to the field list. */
static void
@@ -10021,20 +10108,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
}
/* Data member other than a C++ static data member. */
- /* Get type of field. */
- fp->set_type (die_type (die, cu));
-
- fp->set_loc_bitpos (0);
-
- /* Get bit size of field (zero if none). */
- attr = dwarf2_attr (die, DW_AT_bit_size, cu);
- if (attr != nullptr)
- fp->set_bitsize (attr->unsigned_constant ().value_or (0));
- else
- fp->set_bitsize (0);
-
- /* Get bit offset of field. */
- handle_member_location (die, cu, fp);
+ compute_field_location (cu, die, fp);
/* Get name of field. */
fieldname = dwarf2_name (die, cu);
@@ -11213,54 +11287,19 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
handle_variant (child_die, type, fi, template_args, cu);
}
-/* Create a property baton for a field of the struct type currently
- being processed. OFFSET is the DIE offset of the field in the
- structure. If OFFSET is found among the fields that have already
- been seen, then a new property baton is allocated on the objfile
- obstack and returned. The baton isn't fully filled in -- it will
- be post-processed once the fields are finally created; see
- update_field_batons. If OFFSET is not found, NULL is returned. */
+/* Create a property baton for a field. DIE is the field's DIE. The
+ baton's "field" member is filled in, but the other members of the
+ baton are not. The new property baton is returned. */
static dwarf2_property_baton *
-find_field_create_baton (dwarf2_cu *cu, sect_offset offset)
+find_field_create_baton (dwarf2_cu *cu, die_info *die)
{
- field_info *fi = cu->field_info;
- /* Defensive programming in case we see unusual DWARF. */
- if (fi == nullptr)
- return nullptr;
- for (const auto &fld : fi->fields)
- if (fld.offset == offset)
- {
- dwarf2_property_baton *result
- = XOBNEW (&cu->per_objfile->objfile->objfile_obstack,
- struct dwarf2_property_baton);
- fi->field_batons[result] = offset;
- return result;
- }
- return nullptr;
-}
-
-/* Update all the stored field property batons. FI is the field info
- for the structure being created. TYPE is the corresponding struct
- type with its fields already filled in. This fills in the correct
- field for each baton that was stored while processing this
- type. */
-
-static void
-update_field_batons (field_info *fi, struct type *type)
-{
- int n_bases = fi->baseclasses.size ();
- for (auto &[baton, offset] : fi->field_batons)
- {
- for (int i = 0; i < fi->fields.size (); ++i)
- {
- if (fi->fields[i].offset == offset)
- {
- baton->field = &type->field (n_bases + i);
- break;
- }
- }
- }
+ dwarf2_property_baton *result
+ = XOBNEW (&cu->per_objfile->objfile->objfile_obstack,
+ struct dwarf2_property_baton);
+ memset (&result->field, 0, sizeof (result->field));
+ compute_field_location (cu, die, &result->field);
+ return result;
}
/* Finish creating a structure or union type, including filling in its
@@ -11284,9 +11323,6 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
struct field_info fi;
std::vector<struct symbol *> template_args;
- scoped_restore save_field_info
- = make_scoped_restore (&cu->field_info, &fi);
-
for (die_info *child_die : die->children ())
handle_struct_member_die (child_die, type, &fi, &template_args, cu);
@@ -11308,11 +11344,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
/* Attach fields and member functions to the type. */
if (fi.nfields () > 0)
- {
- dwarf2_attach_fields_to_type (&fi, type, cu);
- update_field_batons (&fi, type);
- }
-
+ dwarf2_attach_fields_to_type (&fi, type, cu);
if (!fi.fnfieldlists.empty ())
{
dwarf2_attach_fn_fields_to_type (&fi, type, cu);
@@ -13927,13 +13959,12 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
case DW_AT_data_member_location:
case DW_AT_data_bit_offset:
{
- baton = find_field_create_baton (cu, target_die->sect_off);
+ baton = find_field_create_baton (cu, target_die);
if (baton == nullptr)
return 0;
baton->property_type = read_type_die (target_die->parent,
target_cu);
- baton->field = nullptr;
prop->set_field (baton);
break;
}
@@ -17172,29 +17203,6 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
return (sym);
}
-/* Given an attr with a DW_FORM_dataN value in host byte order,
- zero-extend it as appropriate for the symbol's type. The DWARF
- standard (v4) is not entirely clear about the meaning of using
- DW_FORM_dataN for a constant with a signed type, where the type is
- wider than the data. The conclusion of a discussion on the DWARF
- list was that this is unspecified. We choose to always zero-extend
- because that is the interpretation long in use by GCC. */
-
-static void
-dwarf2_const_value_data (const struct attribute *attr, LONGEST *value,
- int bits)
-{
- LONGEST l = attr->constant_value (0);
-
- if (bits < sizeof (*value) * 8)
- {
- l &= ((LONGEST) 1 << bits) - 1;
- *value = l;
- }
- else
- *value = l;
-}
-
/* Read a constant value from an attribute. Either set *VALUE, or if
the value does not fit in *VALUE, set *BYTES - either already
allocated on the objfile obstack, or newly allocated on OBSTACK,
@@ -17278,25 +17286,13 @@ dwarf2_const_value_attr (const struct attribute *attr, struct type *type,
converted to host endianness, so we just need to sign- or
zero-extend it as appropriate. */
case DW_FORM_data1:
- dwarf2_const_value_data (attr, value, 8);
- break;
case DW_FORM_data2:
- dwarf2_const_value_data (attr, value, 16);
- break;
case DW_FORM_data4:
- dwarf2_const_value_data (attr, value, 32);
- break;
case DW_FORM_data8:
- dwarf2_const_value_data (attr, value, 64);
- break;
-
case DW_FORM_sdata:
case DW_FORM_implicit_const:
- *value = attr->as_signed ();
- break;
-
case DW_FORM_udata:
- *value = attr->as_unsigned ();
+ *value = attr->confused_constant ().value_or (0);
break;
default:
@@ -18488,39 +18484,19 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
symbol's value "represented as it would be on the target
architecture." By the time we get here, it's already been
converted to host endianness, so we just need to sign- or
- zero-extend it as appropriate. */
+ zero-extend it as appropriate.
+
+ Both GCC and LLVM agree that these are always signed, though. */
case DW_FORM_data1:
- type = die_type (die, cu);
- dwarf2_const_value_data (attr, &value, 8);
- result = write_constant_as_bytes (obstack, byte_order, type, value, len);
- break;
case DW_FORM_data2:
- type = die_type (die, cu);
- dwarf2_const_value_data (attr, &value, 16);
- result = write_constant_as_bytes (obstack, byte_order, type, value, len);
- break;
case DW_FORM_data4:
- type = die_type (die, cu);
- dwarf2_const_value_data (attr, &value, 32);
- result = write_constant_as_bytes (obstack, byte_order, type, value, len);
- break;
case DW_FORM_data8:
- type = die_type (die, cu);
- dwarf2_const_value_data (attr, &value, 64);
- result = write_constant_as_bytes (obstack, byte_order, type, value, len);
- break;
-
case DW_FORM_sdata:
case DW_FORM_implicit_const:
- type = die_type (die, cu);
- result = write_constant_as_bytes (obstack, byte_order,
- type, attr->as_signed (), len);
- break;
-
case DW_FORM_udata:
type = die_type (die, cu);
- result = write_constant_as_bytes (obstack, byte_order,
- type, attr->as_unsigned (), len);
+ value = attr->confused_constant ().value_or (0);
+ result = write_constant_as_bytes (obstack, byte_order, type, value, len);
break;
default:
@@ -19718,9 +19694,7 @@ show_check_physname (struct ui_file *file, int from_tty,
value);
}
-void _initialize_dwarf2_read ();
-void
-_initialize_dwarf2_read ()
+INIT_GDB_FILE (dwarf2_read)
{
add_setshow_prefix_cmd ("dwarf", class_maintenance,
_("\
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 5b4c8f6..a5cfb31 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -20,6 +20,9 @@
#ifndef GDB_DWARF2_READ_H
#define GDB_DWARF2_READ_H
+#if CXX_STD_THREAD
+#include <mutex>
+#endif
#include <queue>
#include "dwarf2/abbrev.h"
#include "dwarf2/unit-head.h"
@@ -512,8 +515,8 @@ struct dwarf2_per_bfd
const char *filename () const
{ return bfd_get_filename (this->obfd); }
- /* Return the CU given its index. */
- dwarf2_per_cu *get_cu (int index) const
+ /* Return the unit given its index. */
+ dwarf2_per_cu *get_unit (int index) const
{
return this->all_units[index].get ();
}
@@ -522,7 +525,7 @@ struct dwarf2_per_bfd
dwarf2_per_cu *get_index_cu (int index) const
{
if (this->all_comp_units_index_cus.empty ())
- return get_cu (index);
+ return get_unit (index);
return this->all_comp_units_index_cus[index];
}
@@ -634,6 +637,11 @@ public:
/* Set of dwo_file objects. */
dwo_file_up_set dwo_files;
+#if CXX_STD_THREAD
+ /* Mutex to synchronize access to DWO_FILES. */
+ std::mutex dwo_files_lock;
+#endif
+
/* The DWP file if there is one, or NULL. */
dwp_file_up dwp_file;
@@ -702,7 +710,7 @@ public:
dwarf2_per_cu *operator* () const
{
- return m_per_bfd->get_cu (m_index);
+ return m_per_bfd->get_unit (m_index);
}
bool operator== (const all_units_iterator &other) const
@@ -1029,8 +1037,7 @@ private:
dwo_file_up open_and_init_dwo_file (dwarf2_cu *cu, const char *dwo_name,
const char *comp_dir);
- void locate_dwo_sections (struct objfile *objfile, bfd *abfd, asection *sectp,
- struct dwo_sections *dwo_sections);
+ void locate_dwo_sections (objfile *objfile, dwo_file &dwo_file);
void create_dwo_unit_hash_tables (dwo_file &dwo_file, dwarf2_cu &skeleton_cu,
dwarf2_section_info &section,
diff --git a/gdb/dwarf2/section.h b/gdb/dwarf2/section.h
index b9d3c31..fd6e34d 100644
--- a/gdb/dwarf2/section.h
+++ b/gdb/dwarf2/section.h
@@ -112,4 +112,6 @@ struct dwarf2_section_info
bool is_virtual;
};
+using dwarf2_section_info_up = std::unique_ptr<dwarf2_section_info>;
+
#endif /* GDB_DWARF2_SECTION_H */
diff --git a/gdb/elfread.c b/gdb/elfread.c
index 7dd8fc7..ae74978 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -1513,9 +1513,7 @@ static const struct gnu_ifunc_fns elf_gnu_ifunc_fns =
elf_gnu_ifunc_resolver_return_stop
};
-void _initialize_elfread ();
-void
-_initialize_elfread ()
+INIT_GDB_FILE (elfread)
{
add_symtab_fns (bfd_target_elf_flavour, &elf_sym_fns);
diff --git a/gdb/eval.c b/gdb/eval.c
index 19770ad..539b700 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -2558,27 +2558,26 @@ unop_extract_operation::evaluate (struct type *expect_type,
}
-
/* Helper for evaluate_subexp_for_address. */
static value *
-evaluate_subexp_for_address_base (struct expression *exp, enum noside noside,
- value *x)
+evaluate_subexp_for_address_base (enum noside noside, value *x)
{
if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
struct type *type = check_typedef (x->type ());
+ enum type_code typecode = type->code ();
if (TYPE_IS_REFERENCE (type))
return value::zero (lookup_pointer_type (type->target_type ()),
- not_lval);
- else if (x->lval () == lval_memory || value_must_coerce_to_target (x))
- return value::zero (lookup_pointer_type (x->type ()),
- not_lval);
+ not_lval);
+ else if (x->lval () == lval_memory || value_must_coerce_to_target (x)
+ || typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)
+ return value::zero (lookup_pointer_type (x->type ()), not_lval);
else
- error (_("Attempt to take address of "
- "value not located in memory."));
+ error (_("Attempt to take address of value not located in memory."));
}
+
return value_addr (x);
}
@@ -2598,7 +2597,7 @@ value *
operation::evaluate_for_address (struct expression *exp, enum noside noside)
{
value *val = evaluate (nullptr, exp, noside);
- return evaluate_subexp_for_address_base (exp, noside, val);
+ return evaluate_subexp_for_address_base (noside, val);
}
value *
@@ -2625,7 +2624,7 @@ unop_ind_base_operation::evaluate_for_address (struct expression *exp,
if (unop_user_defined_p (UNOP_IND, x))
{
x = value_x_unop (x, UNOP_IND, noside);
- return evaluate_subexp_for_address_base (exp, noside, x);
+ return evaluate_subexp_for_address_base (noside, x);
}
return coerce_array (x);
diff --git a/gdb/event-top.c b/gdb/event-top.c
index 968117c..f96982a 100644
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -1650,9 +1650,7 @@ show_debug_event_loop_command (struct ui_file *file, int from_tty,
gdb_printf (file, _("Event loop debugging is %s.\n"), value);
}
-void _initialize_event_top ();
-void
-_initialize_event_top ()
+INIT_GDB_FILE (event_top)
{
add_setshow_enum_cmd ("event-loop", class_maintenance,
debug_event_loop_enum,
diff --git a/gdb/exec.c b/gdb/exec.c
index c7979a2..c2a1f8a 100644
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -44,7 +44,7 @@
#include <ctype.h>
#include <sys/stat.h>
-#include "solist.h"
+#include "solib.h"
#include <algorithm>
#include "gdbsupport/pathstuff.h"
#include "cli/cli-style.h"
@@ -218,28 +218,32 @@ validate_exec_file (int from_tty)
if (exec_file_mismatch_mode == exec_file_mismatch_off)
return;
+ /* If there's no current executable, then there's nothing to
+ validate against, so we're done. */
const char *current_exec_file = current_program_space->exec_filename ();
- struct inferior *inf = current_inferior ();
- /* Try to determine a filename from the process itself. */
- const char *pid_exec_file = target_pid_to_exec_file (inf->pid);
- bool build_id_mismatch = false;
-
- /* If we cannot validate the exec file, return. */
- if (current_exec_file == NULL || pid_exec_file == NULL)
+ if (current_exec_file == nullptr)
return;
- /* Try validating via build-id, if available. This is the most
- reliable check. */
+ /* Try to determine a filename from the process itself. If we
+ cannot get an executable from the process, then no validation is
+ possible. */
+ const char *pid_exec_file
+ = target_pid_to_exec_file (current_inferior ()->pid);
+ if (pid_exec_file == nullptr)
+ return;
- /* In case current_exec_file was changed, reopen_exec_file ensures
- an up to date build_id (will do nothing if the file timestamp
- did not change). If exec file changed, reopen_exec_file has
- allocated another file name, so get_exec_file again. */
+ /* In case current_exec_file was changed, reopen_exec_file ensures an up
+ to date build_id (will do nothing if the file timestamp did not
+ change). If exec file changed, reopen_exec_file has allocated another
+ file name, so get_exec_file again. */
reopen_exec_file ();
current_exec_file = current_program_space->exec_filename ();
+ /* Try validating via build-id, if available. This is the most reliable
+ check. */
const bfd_build_id *exec_file_build_id
= build_id_bfd_get (current_program_space->exec_bfd ());
+ bool build_id_mismatch = false;
if (exec_file_build_id != nullptr)
{
/* Prepend the target prefix, to force gdb_bfd_open to open the
@@ -334,6 +338,14 @@ exec_file_locate_attach (int pid, int defer_bp_reset, int from_tty)
gdb::unique_xmalloc_ptr<char> exec_file_host
= exec_file_find (exec_file_target, NULL);
+ if (exec_file_host == nullptr)
+ {
+ warning (_("No executable has been specified, and target executable "
+ "%ps could not be found. Try using the \"%ps\" command."),
+ styled_string (file_name_style.style (), exec_file_target),
+ styled_string (command_style.style (), "file"));
+ return;
+ }
if (defer_bp_reset)
add_flags |= SYMFILE_DEFER_BP_RESET;
@@ -1065,9 +1077,7 @@ exec_target::find_memory_regions (find_memory_region_ftype func, void *data)
return objfile_find_memory_regions (this, func, data);
}
-void _initialize_exec ();
-void
-_initialize_exec ()
+INIT_GDB_FILE (exec)
{
struct cmd_list_element *c;
diff --git a/gdb/extension.c b/gdb/extension.c
index 6d14a20..d34dbcd 100644
--- a/gdb/extension.c
+++ b/gdb/extension.c
@@ -1102,9 +1102,7 @@ ext_lang_before_prompt (const char *current_gdb_prompt)
}
}
-void _initialize_extension ();
-void
-_initialize_extension ()
+INIT_GDB_FILE (extension)
{
gdb::observers::before_prompt.attach (ext_lang_before_prompt, "extension");
}
diff --git a/gdb/extract-store-integer.c b/gdb/extract-store-integer.c
index 4f20092..d73040b 100644
--- a/gdb/extract-store-integer.c
+++ b/gdb/extract-store-integer.c
@@ -337,9 +337,7 @@ extract_integer_test ()
#endif
-void _initialize_extract_store_integer ();
-void
-_initialize_extract_store_integer ()
+INIT_GDB_FILE (extract_store_integer)
{
#if GDB_SELF_TEST
selftests::register_test ("copy_integer_to_size",
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index 3e31dce..1aa9fc4 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -1836,9 +1836,7 @@ builtin_f_type (struct gdbarch *gdbarch)
static struct cmd_list_element *set_fortran_list;
static struct cmd_list_element *show_fortran_list;
-void _initialize_f_language ();
-void
-_initialize_f_language ()
+INIT_GDB_FILE (f_language)
{
add_setshow_prefix_cmd
("fortran", no_class,
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index 0f3b2a6..a0812b3 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -719,9 +719,7 @@ info_common_command (const char *comname, int from_tty)
}
}
-void _initialize_f_valprint ();
-void
-_initialize_f_valprint ()
+INIT_GDB_FILE (f_valprint)
{
add_info ("common", info_common_command,
_("Print out the values contained in a Fortran COMMON block."));
diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c
index 71a8386..935b947 100644
--- a/gdb/fbsd-nat.c
+++ b/gdb/fbsd-nat.c
@@ -2465,14 +2465,12 @@ fbsd_nat_get_siginfo (ptid_t ptid, siginfo_t *siginfo)
if (ptrace (PT_LWPINFO, pid, (caddr_t) &pl, sizeof pl) == -1)
return false;
if (!(pl.pl_flags & PL_FLAG_SI))
- return false;;
+ return false;
*siginfo = pl.pl_siginfo;
return (true);
}
-void _initialize_fbsd_nat ();
-void
-_initialize_fbsd_nat ()
+INIT_GDB_FILE (fbsd_nat)
{
add_setshow_boolean_cmd ("fbsd-lwp", class_maintenance,
&debug_fbsd_lwp, _("\
diff --git a/gdb/filesystem.c b/gdb/filesystem.c
index 51e1c3f..a272c13 100644
--- a/gdb/filesystem.c
+++ b/gdb/filesystem.c
@@ -76,9 +76,7 @@ is \"%s\".\n"),
value);
}
-void _initialize_filesystem ();
-void
-_initialize_filesystem ()
+INIT_GDB_FILE (filesystem)
{
add_setshow_enum_cmd ("target-file-system-kind",
class_files,
diff --git a/gdb/findcmd.c b/gdb/findcmd.c
index 993c487..4e47877 100644
--- a/gdb/findcmd.c
+++ b/gdb/findcmd.c
@@ -279,9 +279,7 @@ find_command (const char *args, int from_tty)
found_count > 1 ? "s" : "");
}
-void _initialize_mem_search ();
-void
-_initialize_mem_search ()
+INIT_GDB_FILE (mem_search)
{
add_cmd ("find", class_vars, find_command, _("\
Search memory for a sequence of bytes.\n\
diff --git a/gdb/fork-child.c b/gdb/fork-child.c
index 8abfbda..fd7f1e0 100644
--- a/gdb/fork-child.c
+++ b/gdb/fork-child.c
@@ -153,9 +153,7 @@ show_startup_with_shell (struct ui_file *file, int from_tty,
value);
}
-void _initialize_fork_child ();
-void
-_initialize_fork_child ()
+INIT_GDB_FILE (fork_child)
{
add_setshow_filename_cmd ("exec-wrapper", class_run, &exec_wrapper, _("\
Set a wrapper for running programs.\n\
diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c
index 9ed2dee..95768fa 100644
--- a/gdb/frame-unwind.c
+++ b/gdb/frame-unwind.c
@@ -49,6 +49,7 @@ static constexpr std::initializer_list<const frame_unwind *>
standard_unwinders =
{
&dummy_frame_unwind,
+#if defined(DWARF_FORMAT_AVAILABLE)
/* The DWARF tailcall sniffer must come before the inline sniffer.
Otherwise, we can end up in a situation where a DWARF frame finds
tailcall information, but then the inline sniffer claims a frame
@@ -57,6 +58,7 @@ static constexpr std::initializer_list<const frame_unwind *>
activated if the newer frame was created using the DWARF
unwinder, and it also found tailcall information. */
&dwarf2_tailcall_frame_unwind,
+#endif
&inline_frame_unwind,
};
@@ -612,9 +614,7 @@ maintenance_enable_frame_unwinders (const char *args, int from_tty)
enable_disable_frame_unwinders (args, from_tty, true);
}
-void _initialize_frame_unwind ();
-void
-_initialize_frame_unwind ()
+INIT_GDB_FILE (frame_unwind)
{
/* Add "maint info frame-unwinders". */
add_cmd ("frame-unwinders",
diff --git a/gdb/frame.c b/gdb/frame.c
index fe5336f..fc4cbca 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -3424,9 +3424,7 @@ frame_info_ptr::reinflate () const
return m_ptr;
}
-void _initialize_frame ();
-void
-_initialize_frame ()
+INIT_GDB_FILE (frame)
{
obstack_init (&frame_cache_obstack);
diff --git a/gdb/frv-linux-tdep.c b/gdb/frv-linux-tdep.c
index 067b983..2a0fe1b 100644
--- a/gdb/frv-linux-tdep.c
+++ b/gdb/frv-linux-tdep.c
@@ -482,9 +482,7 @@ frv_linux_elf_osabi_sniffer (bfd *abfd)
return GDB_OSABI_UNKNOWN;
}
-void _initialize_frv_linux_tdep ();
-void
-_initialize_frv_linux_tdep ()
+INIT_GDB_FILE (frv_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_frv, 0, GDB_OSABI_LINUX,
frv_linux_init_abi);
diff --git a/gdb/frv-tdep.c b/gdb/frv-tdep.c
index 3608872..b2d6e1a 100644
--- a/gdb/frv-tdep.c
+++ b/gdb/frv-tdep.c
@@ -25,6 +25,7 @@
#include "frame.h"
#include "frame-unwind.h"
#include "frame-base.h"
+#include "solib-frv.h"
#include "trad-frame.h"
#include "dis-asm.h"
#include "sim-regno.h"
@@ -1554,7 +1555,7 @@ frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_convert_from_func_ptr_addr (gdbarch,
frv_convert_from_func_ptr_addr);
- set_gdbarch_so_ops (gdbarch, &frv_so_ops);
+ set_gdbarch_make_solib_ops (gdbarch, make_frv_solib_ops);
/* Hook in ABI-specific overrides, if they have been registered. */
gdbarch_init_osabi (info, gdbarch);
@@ -1569,9 +1570,7 @@ frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
return gdbarch;
}
-void _initialize_frv_tdep ();
-void
-_initialize_frv_tdep ()
+INIT_GDB_FILE (frv_tdep)
{
gdbarch_register (bfd_arch_frv, frv_gdbarch_init);
}
diff --git a/gdb/frv-tdep.h b/gdb/frv-tdep.h
index 07982b4..7b51b42 100644
--- a/gdb/frv-tdep.h
+++ b/gdb/frv-tdep.h
@@ -118,7 +118,4 @@ CORE_ADDR frv_fdpic_find_canonical_descriptor (CORE_ADDR entry_point);
needed for TLS support. */
CORE_ADDR frv_fetch_objfile_link_map (struct objfile *objfile);
-struct solib_ops;
-extern const solib_ops frv_so_ops;
-
#endif /* GDB_FRV_TDEP_H */
diff --git a/gdb/ft32-tdep.c b/gdb/ft32-tdep.c
index f84e225..3384929 100644
--- a/gdb/ft32-tdep.c
+++ b/gdb/ft32-tdep.c
@@ -621,9 +621,7 @@ ft32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
/* Register this machine's init routine. */
-void _initialize_ft32_tdep ();
-void
-_initialize_ft32_tdep ()
+INIT_GDB_FILE (ft32_tdep)
{
gdbarch_register (bfd_arch_ft32, ft32_gdbarch_init);
}
diff --git a/gdb/gcore-1.in b/gdb/gcore-1.in
index 1220f4a..2f6eb02 100644
--- a/gdb/gcore-1.in
+++ b/gdb/gcore-1.in
@@ -34,11 +34,11 @@ data_directory_opt=()
function print_usage() {
prefix="Usage: $0"
- paddin=$(printf '%*s' ${#prefix})
+ padding=$(printf '%*s' ${#prefix})
echo "$prefix [-h|--help] [-v|--version]"
- echo "$paddin [-a] [-o prefix] [-d data-directory]"
- echo "$paddin pid1 [pid2...pidN]"
+ echo "$padding [-a] [-o prefix] [-d data-directory]"
+ echo "$padding pid1 [pid2...pidN]"
}
function print_try_help() {
diff --git a/gdb/gcore.c b/gdb/gcore.c
index fa15d06..d532652 100644
--- a/gdb/gcore.c
+++ b/gdb/gcore.c
@@ -861,9 +861,7 @@ gcore_find_signalled_thread ()
return nullptr;
}
-void _initialize_gcore ();
-void
-_initialize_gcore ()
+INIT_GDB_FILE (gcore)
{
cmd_list_element *generate_core_file_cmd
= add_com ("generate-core-file", class_files, gcore_command, _("\
diff --git a/gdb/gdb-demangle.c b/gdb/gdb-demangle.c
index 239306a..c285788 100644
--- a/gdb/gdb-demangle.c
+++ b/gdb/gdb-demangle.c
@@ -208,9 +208,7 @@ demangle_command (const char *args, int from_tty)
error (_("Can't demangle \"%s\""), name);
}
-void _initialize_gdb_demangle ();
-void
-_initialize_gdb_demangle ()
+INIT_GDB_FILE (gdb_demangle)
{
int i, ndems;
diff --git a/gdb/gdb-gdb.py.in b/gdb/gdb-gdb.py.in
index 4d96235..7388c6f 100644
--- a/gdb/gdb-gdb.py.in
+++ b/gdb/gdb-gdb.py.in
@@ -122,7 +122,7 @@ class StructTypePrettyPrinter:
class StructMainTypePrettyPrinter:
- """Pretty-print an objet of type main_type"""
+ """Pretty-print an object of type main_type"""
def __init__(self, val):
self.val = val
@@ -164,8 +164,10 @@ class StructMainTypePrettyPrinter:
return "physaddr = 0x%x" % loc_val["physaddr"]
elif loc_kind == "FIELD_LOC_KIND_PHYSNAME":
return "physname = %s" % loc_val["physname"]
- elif loc_kind == "FIELD_LOC_KIND_DWARF_BLOCK":
- return "dwarf_block = %s" % loc_val["dwarf_block"]
+ elif loc_kind == "FIELD_LOC_KIND_DWARF_BLOCK_ADDR":
+ return "dwarf_block_addr = %s" % loc_val["dwarf_block"]
+ elif loc_kind == "FIELD_LOC_KIND_DWARF_BLOCK_BITPOS":
+ return "dwarf_block_bitpos = %s" % loc_val["dwarf_block"]
else:
return "m_loc = ??? (unsupported m_loc_kind value)"
diff --git a/gdb/gdb-stabs.h b/gdb/gdb-stabs.h
index 2f3a0a5..9909129 100644
--- a/gdb/gdb-stabs.h
+++ b/gdb/gdb-stabs.h
@@ -20,9 +20,9 @@
#ifndef GDB_GDB_STABS_H
#define GDB_GDB_STABS_H
-/* During initial symbol readin, we need to have a structure to keep
+/* During initial symbol reading, we need to have a structure to keep
track of which psymtabs have which bincls in them. This structure
- is used during readin to setup the list of dependencies within each
+ is used during reading to setup the list of dependencies within each
partial symbol table. */
struct legacy_psymtab;
diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c
index 06d6f5c..2e477eb 100644
--- a/gdb/gdb_bfd.c
+++ b/gdb/gdb_bfd.c
@@ -1346,9 +1346,7 @@ gdb_bfd_init ()
error (_("fatal error: libbfd ABI mismatch"));
}
-void _initialize_gdb_bfd ();
-void
-_initialize_gdb_bfd ()
+INIT_GDB_FILE (gdb_bfd)
{
add_cmd ("bfds", class_maintenance, maintenance_info_bfds, _("\
List the BFDs that are currently open."),
diff --git a/gdb/gdb_buildall.sh b/gdb/gdb_buildall.sh
index 430aae4..2053333 100644
--- a/gdb/gdb_buildall.sh
+++ b/gdb/gdb_buildall.sh
@@ -261,7 +261,7 @@ echo "done."
# Clean up build directory if necessary.
if ${clean}
then
- echo "cleanning up $dir"
+ echo "cleaning up $dir"
rm -rf ${dir}
fi
diff --git a/gdb/gdbarch-gen.c b/gdb/gdbarch-gen.c
index 32d1659..fc570d3 100644
--- a/gdb/gdbarch-gen.c
+++ b/gdb/gdbarch-gen.c
@@ -157,7 +157,7 @@ struct gdbarch
gdbarch_single_step_through_delay_ftype *single_step_through_delay = nullptr;
gdbarch_print_insn_ftype *print_insn = default_print_insn;
gdbarch_skip_trampoline_code_ftype *skip_trampoline_code = generic_skip_trampoline_code;
- const solib_ops * so_ops = &solib_target_so_ops;
+ gdbarch_make_solib_ops_ftype *make_solib_ops = make_target_solib_ops;
gdbarch_skip_solib_resolver_ftype *skip_solib_resolver = generic_skip_solib_resolver;
gdbarch_in_solib_return_trampoline_ftype *in_solib_return_trampoline = generic_in_solib_return_trampoline;
gdbarch_in_indirect_branch_thunk_ftype *in_indirect_branch_thunk = default_in_indirect_branch_thunk;
@@ -425,7 +425,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of single_step_through_delay, has predicate. */
/* Skip verify of print_insn, invalid_p == 0. */
/* Skip verify of skip_trampoline_code, invalid_p == 0. */
- /* Skip verify of so_ops, invalid_p == 0. */
+ /* Skip verify of make_solib_ops, invalid_p == 0. */
/* Skip verify of skip_solib_resolver, invalid_p == 0. */
/* Skip verify of in_solib_return_trampoline, invalid_p == 0. */
/* Skip verify of in_indirect_branch_thunk, invalid_p == 0. */
@@ -966,8 +966,8 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
"gdbarch_dump: skip_trampoline_code = <%s>\n",
host_address_to_string (gdbarch->skip_trampoline_code));
gdb_printf (file,
- "gdbarch_dump: so_ops = %s\n",
- host_address_to_string (gdbarch->so_ops));
+ "gdbarch_dump: make_solib_ops = <%s>\n",
+ host_address_to_string (gdbarch->make_solib_ops));
gdb_printf (file,
"gdbarch_dump: skip_solib_resolver = <%s>\n",
host_address_to_string (gdbarch->skip_solib_resolver));
@@ -3469,21 +3469,21 @@ set_gdbarch_skip_trampoline_code (struct gdbarch *gdbarch,
gdbarch->skip_trampoline_code = skip_trampoline_code;
}
-const solib_ops *
-gdbarch_so_ops (struct gdbarch *gdbarch)
+solib_ops_up
+gdbarch_make_solib_ops (struct gdbarch *gdbarch)
{
gdb_assert (gdbarch != NULL);
- /* Skip verify of so_ops, invalid_p == 0. */
+ gdb_assert (gdbarch->make_solib_ops != NULL);
if (gdbarch_debug >= 2)
- gdb_printf (gdb_stdlog, "gdbarch_so_ops called\n");
- return gdbarch->so_ops;
+ gdb_printf (gdb_stdlog, "gdbarch_make_solib_ops called\n");
+ return gdbarch->make_solib_ops ();
}
void
-set_gdbarch_so_ops (struct gdbarch *gdbarch,
- const solib_ops * so_ops)
+set_gdbarch_make_solib_ops (struct gdbarch *gdbarch,
+ gdbarch_make_solib_ops_ftype make_solib_ops)
{
- gdbarch->so_ops = so_ops;
+ gdbarch->make_solib_ops = make_solib_ops;
}
CORE_ADDR
diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h
index 313a8f1..281b97b 100644
--- a/gdb/gdbarch-gen.h
+++ b/gdb/gdbarch-gen.h
@@ -818,10 +818,11 @@ typedef CORE_ADDR (gdbarch_skip_trampoline_code_ftype) (const frame_info_ptr &fr
extern CORE_ADDR gdbarch_skip_trampoline_code (struct gdbarch *gdbarch, const frame_info_ptr &frame, CORE_ADDR pc);
extern void set_gdbarch_skip_trampoline_code (struct gdbarch *gdbarch, gdbarch_skip_trampoline_code_ftype *skip_trampoline_code);
-/* Vtable of solib operations functions. */
+/* Return a newly-allocated solib_ops object capable of providing the solibs for this architecture. */
-extern const solib_ops * gdbarch_so_ops (struct gdbarch *gdbarch);
-extern void set_gdbarch_so_ops (struct gdbarch *gdbarch, const solib_ops * so_ops);
+typedef solib_ops_up (gdbarch_make_solib_ops_ftype) ();
+extern solib_ops_up gdbarch_make_solib_ops (struct gdbarch *gdbarch);
+extern void set_gdbarch_make_solib_ops (struct gdbarch *gdbarch, gdbarch_make_solib_ops_ftype *make_solib_ops);
/* If in_solib_dynsym_resolve_code() returns true, and SKIP_SOLIB_RESOLVER
evaluates non-zero, this is the address where the debugger will place
diff --git a/gdb/gdbarch-selftests.c b/gdb/gdbarch-selftests.c
index c370204..5c94f60 100644
--- a/gdb/gdbarch-selftests.c
+++ b/gdb/gdbarch-selftests.c
@@ -183,9 +183,7 @@ check_stack_growth (struct gdbarch *gdbarch)
} /* namespace selftests */
-void _initialize_gdbarch_selftests ();
-void
-_initialize_gdbarch_selftests ()
+INIT_GDB_FILE (gdbarch_selftests)
{
selftests::register_test_foreach_arch ("register_to_value",
selftests::register_to_value_test);
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 9feb2cc..6accbd2 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -30,6 +30,7 @@
#include "displaced-stepping.h"
#include "gdbsupport/gdb-checked-static-cast.h"
#include "registry.h"
+#include "solib.h"
struct floatformat;
struct ui_file;
diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py
index ec09d95..91c867e 100644
--- a/gdb/gdbarch_components.py
+++ b/gdb/gdbarch_components.py
@@ -1431,12 +1431,12 @@ Function(
invalid=False,
)
-Value(
- comment="Vtable of solib operations functions.",
- type="const solib_ops *",
- name="so_ops",
- predefault="&solib_target_so_ops",
- printer="host_address_to_string (gdbarch->so_ops)",
+Function(
+ comment="Return a newly-allocated solib_ops object capable of providing the solibs for this architecture.",
+ type="solib_ops_up",
+ name="make_solib_ops",
+ params=[],
+ predefault="make_target_solib_ops",
invalid=False,
)
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index a241223..14a903b 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -2121,7 +2121,7 @@ is_dynamic_type_internal (struct type *type, bool top_level)
return true;
/* If the field is at a fixed offset, then it is not
dynamic. */
- if (type->field (i).loc_kind () != FIELD_LOC_KIND_DWARF_BLOCK)
+ if (!type->field (i).loc_is_dwarf_block ())
continue;
/* Do not consider C++ virtual base types to be dynamic
due to the field's offset being dynamic; these are
@@ -2723,7 +2723,7 @@ resolve_dynamic_field (struct field &field,
{
gdb_assert (!field.is_static ());
- if (field.loc_kind () == FIELD_LOC_KIND_DWARF_BLOCK)
+ if (field.loc_is_dwarf_block ())
{
dwarf2_locexpr_baton *field_loc
= field.loc_dwarf_block ();
@@ -2736,10 +2736,15 @@ resolve_dynamic_field (struct field &field,
prop.set_locexpr (&baton);
CORE_ADDR vals[1] = {addr_stack->addr};
- CORE_ADDR addr;
- if (dwarf2_evaluate_property (&prop, frame, addr_stack, &addr, vals))
+ CORE_ADDR addr_or_bitpos;
+ if (dwarf2_evaluate_property (&prop, frame, addr_stack,
+ &addr_or_bitpos, vals))
{
- field.set_loc_bitpos (TARGET_CHAR_BIT * (addr - addr_stack->addr));
+ if (field.loc_kind () == FIELD_LOC_KIND_DWARF_BLOCK_ADDR)
+ field.set_loc_bitpos (TARGET_CHAR_BIT
+ * (addr_or_bitpos - addr_stack->addr));
+ else
+ field.set_loc_bitpos (addr_or_bitpos);
if (field_loc->is_field_location)
{
@@ -4415,7 +4420,8 @@ check_types_equal (struct type *type1, struct type *type2,
field2->loc_physname ()))
return false;
break;
- case FIELD_LOC_KIND_DWARF_BLOCK:
+ case FIELD_LOC_KIND_DWARF_BLOCK_ADDR:
+ case FIELD_LOC_KIND_DWARF_BLOCK_BITPOS:
{
struct dwarf2_locexpr_baton *block1, *block2;
@@ -5560,8 +5566,12 @@ copy_type_recursive (struct type *type, copied_types_hash_t &copied_types)
new_type->field (i).set_loc_physname
(xstrdup (type->field (i).loc_physname ()));
break;
- case FIELD_LOC_KIND_DWARF_BLOCK:
- new_type->field (i).set_loc_dwarf_block
+ case FIELD_LOC_KIND_DWARF_BLOCK_ADDR:
+ new_type->field (i).set_loc_dwarf_block_addr
+ (type->field (i).loc_dwarf_block ());
+ break;
+ case FIELD_LOC_KIND_DWARF_BLOCK_BITPOS:
+ new_type->field (i).set_loc_dwarf_block_bitpos
(type->field (i).loc_dwarf_block ());
break;
default:
@@ -6174,17 +6184,25 @@ builtin_type (struct objfile *objfile)
return builtin_type (objfile->arch ());
}
-/* See gdbtypes.h. */
+/* See dwarf2/call-site.h. */
CORE_ADDR
call_site::pc () const
{
+ /* dwarf2_per_objfile is defined in dwarf/read.c, so if that is disabled
+ at configure time, we won't be able to use this relocate function.
+ This is dwarf-specific, and would ideally be in call-site.h, but
+ including dwarf2/read.h in dwarf2/call-site.h will lead to things being
+ included in the wrong order and many compilation errors will happen.
+ This is the next best thing. */
+#if defined(DWARF_FORMAT_AVAILABLE)
return per_objfile->relocate (m_unrelocated_pc);
+#else
+ gdb_assert_not_reached ("unexpected call_site object found");
+#endif
}
-void _initialize_gdbtypes ();
-void
-_initialize_gdbtypes ()
+INIT_GDB_FILE (gdbtypes)
{
add_setshow_zuinteger_cmd ("overload", no_class, &overload_debug,
_("Set debugging of C++ overloading."),
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 67b4bf0..9e2efe9 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -480,7 +480,10 @@ enum field_loc_kind
FIELD_LOC_KIND_ENUMVAL, /**< enumval */
FIELD_LOC_KIND_PHYSADDR, /**< physaddr */
FIELD_LOC_KIND_PHYSNAME, /**< physname */
- FIELD_LOC_KIND_DWARF_BLOCK /**< dwarf_block */
+ /* A DWARF block that computes the address of the field. */
+ FIELD_LOC_KIND_DWARF_BLOCK_ADDR, /**< dwarf_block */
+ /* A DWARF block that computes the bit offset of the field. */
+ FIELD_LOC_KIND_DWARF_BLOCK_BITPOS,
};
/* * A discriminant to determine which field in the
@@ -616,6 +619,13 @@ struct field
return m_loc_kind;
}
+ /* Return true if this location has either "DWARF block" kind. */
+ bool loc_is_dwarf_block () const
+ {
+ return (m_loc_kind == FIELD_LOC_KIND_DWARF_BLOCK_ADDR
+ || m_loc_kind == FIELD_LOC_KIND_DWARF_BLOCK_BITPOS);
+ }
+
LONGEST loc_bitpos () const
{
gdb_assert (m_loc_kind == FIELD_LOC_KIND_BITPOS);
@@ -666,13 +676,19 @@ struct field
dwarf2_locexpr_baton *loc_dwarf_block () const
{
- gdb_assert (m_loc_kind == FIELD_LOC_KIND_DWARF_BLOCK);
+ gdb_assert (loc_is_dwarf_block ());
return m_loc.dwarf_block;
}
- void set_loc_dwarf_block (dwarf2_locexpr_baton *dwarf_block)
+ void set_loc_dwarf_block_addr (dwarf2_locexpr_baton *dwarf_block)
+ {
+ m_loc_kind = FIELD_LOC_KIND_DWARF_BLOCK_ADDR;
+ m_loc.dwarf_block = dwarf_block;
+ }
+
+ void set_loc_dwarf_block_bitpos (dwarf2_locexpr_baton *dwarf_block)
{
- m_loc_kind = FIELD_LOC_KIND_DWARF_BLOCK;
+ m_loc_kind = FIELD_LOC_KIND_DWARF_BLOCK_BITPOS;
m_loc.dwarf_block = dwarf_block;
}
diff --git a/gdb/gmp-utils.c b/gdb/gmp-utils.c
index b48e97c..5c5423a 100644
--- a/gdb/gmp-utils.c
+++ b/gdb/gmp-utils.c
@@ -250,10 +250,7 @@ xfree_for_gmp (void *ptr, size_t size)
xfree (ptr);
}
-void _initialize_gmp_utils ();
-
-void
-_initialize_gmp_utils ()
+INIT_GDB_FILE (gmp_utils)
{
/* Tell GMP to use GDB's memory management routines. */
mp_set_memory_functions (xmalloc, xrealloc_for_gmp, xfree_for_gmp);
diff --git a/gdb/gnu-nat.c b/gdb/gnu-nat.c
index ea07dd6..dd639fe 100644
--- a/gdb/gnu-nat.c
+++ b/gdb/gnu-nat.c
@@ -3434,9 +3434,7 @@ to the thread's initial suspend-count when gdb notices the threads."),
&thread_cmd_list);
}
-void _initialize_gnu_nat ();
-void
-_initialize_gnu_nat ()
+INIT_GDB_FILE (gnu_nat)
{
proc_server = getproc ();
diff --git a/gdb/gnu-v2-abi.c b/gdb/gnu-v2-abi.c
index ab9f53b..9246788 100644
--- a/gdb/gnu-v2-abi.c
+++ b/gdb/gnu-v2-abi.c
@@ -265,15 +265,9 @@ gnuv2_value_rtti_type (struct value *v, int *full, LONGEST *top, int *using_enc)
if (top && ((*top) >0))
{
if (rtti_type->length () > known_type->length ())
- {
- if (full)
- *full=0;
- }
+ *full = 0;
else
- {
- if (full)
- *full=1;
- }
+ *full = 1;
}
}
else
@@ -411,9 +405,7 @@ init_gnuv2_ops (void)
gnu_v2_abi_ops.baseclass_offset = gnuv2_baseclass_offset;
}
-void _initialize_gnu_v2_abi ();
-void
-_initialize_gnu_v2_abi ()
+INIT_GDB_FILE (gnu_v2_abi)
{
init_gnuv2_ops ();
register_cp_abi (&gnu_v2_abi_ops);
diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c
index 4f53e9f..e3818d9 100644
--- a/gdb/gnu-v3-abi.c
+++ b/gdb/gnu-v3-abi.c
@@ -476,7 +476,7 @@ gnuv3_baseclass_offset (struct type *type, int index,
return TYPE_BASECLASS_BITPOS (type, index) / 8;
/* If we have a DWARF expression for the offset, evaluate it. */
- if (type->field (index).loc_kind () == FIELD_LOC_KIND_DWARF_BLOCK)
+ if (type->field (index).loc_kind () == FIELD_LOC_KIND_DWARF_BLOCK_ADDR)
{
struct dwarf2_property_baton baton;
baton.property_type
@@ -1570,9 +1570,7 @@ init_gnuv3_ops (void)
gnu_v3_abi_ops.pass_by_reference = gnuv3_pass_by_reference;
}
-void _initialize_gnu_v3_abi ();
-void
-_initialize_gnu_v3_abi ()
+INIT_GDB_FILE (gnu_v3_abi)
{
init_gnuv3_ops ();
diff --git a/gdb/go32-nat.c b/gdb/go32-nat.c
index 8dcb22d..4d8e6c9 100644
--- a/gdb/go32-nat.c
+++ b/gdb/go32-nat.c
@@ -2057,9 +2057,7 @@ go32_pte_for_address (const char *arg, int from_tty)
static struct cmd_list_element *info_dos_cmdlist = NULL;
-void _initialize_go32_nat ();
-void
-_initialize_go32_nat ()
+INIT_GDB_FILE (go32_nat)
{
x86_dr_low.set_control = go32_set_dr7;
x86_dr_low.set_addr = go32_set_dr;
diff --git a/gdb/guile/guile-internal.h b/gdb/guile/guile-internal.h
index 3101882..60a8bf3 100644
--- a/gdb/guile/guile-internal.h
+++ b/gdb/guile/guile-internal.h
@@ -449,10 +449,11 @@ extern const struct block *bkscm_scm_to_block
/* scm-cmd.c */
-extern char *gdbscm_parse_command_name (const char *name,
- const char *func_name, int arg_pos,
- struct cmd_list_element ***base_list,
- struct cmd_list_element **start_list);
+extern char *gdbscm_parse_command_name
+ (const char *name, const char *func_name, int arg_pos,
+ struct cmd_list_element ***base_list,
+ struct cmd_list_element **start_list,
+ struct cmd_list_element **prefix_cmd = nullptr);
extern int gdbscm_valid_command_class_p (int command_class);
diff --git a/gdb/guile/guile.c b/gdb/guile/guile.c
index 1803df0..66a74b3 100644
--- a/gdb/guile/guile.c
+++ b/gdb/guile/guile.c
@@ -827,9 +827,7 @@ message == an error message without a stack will be printed."),
&set_guile_list, &show_guile_list);
}
-void _initialize_guile ();
-void
-_initialize_guile ()
+INIT_GDB_FILE (guile)
{
install_gdb_commands ();
}
diff --git a/gdb/guile/scm-cmd.c b/gdb/guile/scm-cmd.c
index 4757872..19fb742 100644
--- a/gdb/guile/scm-cmd.c
+++ b/gdb/guile/scm-cmd.c
@@ -457,11 +457,13 @@ cmdscm_completer (struct cmd_list_element *command,
name of the new command. All earlier words must be existing prefix
commands.
- *BASE_LIST is set to the final prefix command's list of
- *sub-commands.
+ *BASE_LIST is set to the final prefix command's list of sub-commands.
START_LIST is the list in which the search starts.
+ When PREFIX_CMD is not NULL then *PREFIX_CMD is set to the prefix
+ command itself, or NULL, if there is no prefix command.
+
This function returns the xmalloc()d name of the new command.
On error a Scheme exception is thrown. */
@@ -469,13 +471,17 @@ char *
gdbscm_parse_command_name (const char *name,
const char *func_name, int arg_pos,
struct cmd_list_element ***base_list,
- struct cmd_list_element **start_list)
+ struct cmd_list_element **start_list,
+ struct cmd_list_element **prefix_cmd)
{
struct cmd_list_element *elt;
int len = strlen (name);
int i, lastchar;
char *msg;
+ if (prefix_cmd != nullptr)
+ *prefix_cmd = nullptr;
+
/* Skip trailing whitespace. */
for (i = len - 1; i >= 0 && (name[i] == ' ' || name[i] == '\t'); --i)
;
@@ -490,9 +496,9 @@ gdbscm_parse_command_name (const char *name,
/* Find first character of the final word. */
for (; i > 0 && valid_cmd_char_p (name[i - 1]); --i)
;
- gdb::unique_xmalloc_ptr<char> result ((char *) xmalloc (lastchar - i + 2));
- memcpy (result.get (), &name[i], lastchar - i + 1);
- result.get ()[lastchar - i + 1] = '\0';
+
+ gdb::unique_xmalloc_ptr<char> result
+ = make_unique_xstrndup (&name[i], lastchar - i + 1);
/* Skip whitespace again. */
for (--i; i >= 0 && (name[i] == ' ' || name[i] == '\t'); --i)
@@ -503,18 +509,21 @@ gdbscm_parse_command_name (const char *name,
return result.release ();
}
- gdb::unique_xmalloc_ptr<char> prefix_text ((char *) xmalloc (i + 2));
- memcpy (prefix_text.get (), name, i + 1);
- prefix_text.get ()[i + 1] = '\0';
+ gdb::unique_xmalloc_ptr<char> prefix_text
+ = make_unique_xstrndup (name, i + 1);
const char *prefix_text2 = prefix_text.get ();
elt = lookup_cmd_1 (&prefix_text2, *start_list, NULL, NULL, 1);
- if (elt == NULL || elt == CMD_LIST_AMBIGUOUS)
+ if (elt == nullptr || elt == CMD_LIST_AMBIGUOUS || *prefix_text2 != '\0')
{
msg = xstrprintf (_("could not find command prefix '%s'"),
prefix_text.get ()).release ();
scm_dynwind_begin ((scm_t_dynwind_flags) 0);
gdbscm_dynwind_xfree (msg);
+ /* Release memory now as the destructors will not be run when the
+ guile exception is thrown. */
+ result = nullptr;
+ prefix_text = nullptr;
gdbscm_out_of_range_error (func_name, arg_pos,
gdbscm_scm_from_c_string (name), msg);
}
@@ -522,6 +531,8 @@ gdbscm_parse_command_name (const char *name,
if (elt->is_prefix ())
{
*base_list = elt->subcommands;
+ if (prefix_cmd != nullptr)
+ *prefix_cmd = elt;
return result.release ();
}
@@ -529,6 +540,10 @@ gdbscm_parse_command_name (const char *name,
prefix_text.get ()).release ();
scm_dynwind_begin ((scm_t_dynwind_flags) 0);
gdbscm_dynwind_xfree (msg);
+ /* Release memory now as the destructors will not be run when the guile
+ exception is thrown. */
+ result = nullptr;
+ prefix_text = nullptr;
gdbscm_out_of_range_error (func_name, arg_pos,
gdbscm_scm_from_c_string (name), msg);
/* NOTREACHED */
@@ -743,8 +758,9 @@ gdbscm_register_command_x (SCM self)
if (cmdscm_is_valid (c_smob))
scm_misc_error (FUNC_NAME, _("command is already registered"), SCM_EOL);
+ struct cmd_list_element *prefix_cmd = nullptr;
cmd_name = gdbscm_parse_command_name (c_smob->name, FUNC_NAME, SCM_ARG1,
- &cmd_list, &cmdlist);
+ &cmd_list, &cmdlist, &prefix_cmd);
c_smob->cmd_name = gdbscm_gc_xstrdup (cmd_name);
xfree (cmd_name);
@@ -753,18 +769,50 @@ gdbscm_register_command_x (SCM self)
{
if (c_smob->is_prefix)
{
- /* If we have our own "invoke" method, then allow unknown
- sub-commands. */
- int allow_unknown = gdbscm_is_true (c_smob->invoke);
+ bool has_invoke = gdbscm_is_true (c_smob->invoke) == 1;
- cmd = add_prefix_cmd (c_smob->cmd_name, c_smob->cmd_class,
- NULL, c_smob->doc, &c_smob->sub_list,
- allow_unknown, cmd_list);
+ if (has_invoke)
+ {
+ cmd = add_prefix_cmd (c_smob->cmd_name, c_smob->cmd_class,
+ NULL, c_smob->doc, &c_smob->sub_list,
+ 1 /* allow_unknown */, cmd_list);
+ cmd->func = cmdscm_function;
+ }
+ else
+ {
+ /* If there is no 'invoke' method, then create the prefix
+ using the standard prefix callbacks. This means that for
+ 'set prefix' the user will get the help text listing all
+ of the sub-commands, and for 'show prefix', the user will
+ see all of the sub-command values. */
+ if (prefix_cmd != nullptr)
+ {
+ while (prefix_cmd->prefix != nullptr)
+ prefix_cmd = prefix_cmd->prefix;
+ }
+
+ bool is_show = (prefix_cmd != nullptr
+ && prefix_cmd->subcommands == &showlist);
+
+ if (is_show)
+ cmd = add_show_prefix_cmd (c_smob->cmd_name,
+ c_smob->cmd_class,
+ c_smob->doc,
+ &c_smob->sub_list,
+ 0 /* allow_unknown */, cmd_list);
+ else
+ cmd = add_basic_prefix_cmd (c_smob->cmd_name,
+ c_smob->cmd_class,
+ c_smob->doc,
+ &c_smob->sub_list,
+ 0 /* allow_unknown */, cmd_list);
+ }
}
else
{
cmd = add_cmd (c_smob->cmd_name, c_smob->cmd_class,
c_smob->doc, cmd_list);
+ cmd->func = cmdscm_function;
}
}
catch (const gdb_exception &except)
@@ -777,7 +825,6 @@ gdbscm_register_command_x (SCM self)
So no more errors after this point. */
/* There appears to be no API to set this. */
- cmd->func = cmdscm_function;
cmd->destroyer = cmdscm_destroyer;
c_smob->command = cmd;
diff --git a/gdb/guile/scm-param.c b/gdb/guile/scm-param.c
index 65226ec..5137847 100644
--- a/gdb/guile/scm-param.c
+++ b/gdb/guile/scm-param.c
@@ -308,13 +308,37 @@ pascm_is_valid (param_smob *p_smob)
return p_smob->commands.set != nullptr;
}
-/* A helper function which return the default documentation string for
- a parameter (which is to say that it's undocumented). */
+
+/* The different types of documentation string. */
+
+enum doc_string_type
+{
+ doc_string_set,
+ doc_string_show,
+ doc_string_description
+};
+
+/* A helper function which returns the default documentation string for
+ a parameter CMD_NAME. The DOC_TYPE indicates which type of
+ documentation string is needed. The returned string is dynamically
+ allocated. */
static char *
-get_doc_string (void)
+get_doc_string (doc_string_type doc_type, const char *cmd_name)
{
- return xstrdup (_("This command is not documented."));
+ if (doc_type == doc_string_description)
+ return xstrdup (_("This command is not documented."));
+ else
+ {
+ gdb_assert (cmd_name != nullptr);
+
+ if (doc_type == doc_string_show)
+ return xstrprintf (_("Show the current value of '%s'."),
+ cmd_name).release ();
+ else
+ return xstrprintf (_("Set the current value of '%s'."),
+ cmd_name).release ();
+ }
}
/* Subroutine of pascm_set_func, pascm_show_func to simplify them.
@@ -990,11 +1014,14 @@ gdbscm_make_parameter (SCM name_scm, SCM rest)
&show_doc_arg_pos, &show_doc,
&initial_value_arg_pos, &initial_value_scm);
- /* If doc is NULL, leave it NULL. See add_setshow_cmd_full. */
+ if (doc == nullptr)
+ doc = get_doc_string (doc_string_description, nullptr);
+ else if (*doc == '\0')
+ doc = nullptr;
if (set_doc == NULL)
- set_doc = get_doc_string ();
+ set_doc = get_doc_string (doc_string_set, name);
if (show_doc == NULL)
- show_doc = get_doc_string ();
+ show_doc = get_doc_string (doc_string_show, name);
s = name;
name = gdbscm_canonicalize_command_name (s, 0);
diff --git a/gdb/h8300-tdep.c b/gdb/h8300-tdep.c
index db54438..15b0002 100644
--- a/gdb/h8300-tdep.c
+++ b/gdb/h8300-tdep.c
@@ -1374,9 +1374,7 @@ h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
}
-void _initialize_h8300_tdep ();
-void
-_initialize_h8300_tdep ()
+INIT_GDB_FILE (h8300_tdep)
{
gdbarch_register (bfd_arch_h8300, h8300_gdbarch_init);
}
diff --git a/gdb/hppa-bsd-tdep.c b/gdb/hppa-bsd-tdep.c
index db6c92f..715e794 100644
--- a/gdb/hppa-bsd-tdep.c
+++ b/gdb/hppa-bsd-tdep.c
@@ -128,8 +128,7 @@ hppabsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_skip_trampoline_code (gdbarch, hppa_skip_trampoline_code);
/* OpenBSD and NetBSD use SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
/* Hook in the DWARF CFI frame unwinder. */
dwarf2_frame_set_init_reg (gdbarch, hppabsd_dwarf2_frame_init_reg);
diff --git a/gdb/hppa-linux-nat.c b/gdb/hppa-linux-nat.c
index 62b3294..5e63e7f 100644
--- a/gdb/hppa-linux-nat.c
+++ b/gdb/hppa-linux-nat.c
@@ -383,9 +383,7 @@ fill_fpregset (const struct regcache *regcache,
}
}
-void _initialize_hppa_linux_nat ();
-void
-_initialize_hppa_linux_nat ()
+INIT_GDB_FILE (hppa_linux_nat)
{
/* Register the target. */
linux_target = &the_hppa_linux_nat_target;
diff --git a/gdb/hppa-linux-tdep.c b/gdb/hppa-linux-tdep.c
index 16cdd45..2eb8d46 100644
--- a/gdb/hppa-linux-tdep.c
+++ b/gdb/hppa-linux-tdep.c
@@ -32,6 +32,7 @@
#include "regcache.h"
#include "hppa-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "elf/common.h"
/* Map DWARF DBX register numbers to GDB register numbers. */
@@ -499,8 +500,7 @@ hppa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
frame_unwind_append_unwinder (gdbarch, &hppa_linux_sigtramp_frame_unwind);
/* GNU/Linux uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
tdep->in_solib_call_trampoline = hppa_in_solib_call_trampoline;
set_gdbarch_skip_trampoline_code (gdbarch, hppa_skip_trampoline_code);
@@ -524,9 +524,7 @@ hppa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
svr4_fetch_objfile_link_map);
}
-void _initialize_hppa_linux_tdep ();
-void
-_initialize_hppa_linux_tdep ()
+INIT_GDB_FILE (hppa_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_LINUX,
hppa_linux_init_abi);
diff --git a/gdb/hppa-netbsd-nat.c b/gdb/hppa-netbsd-nat.c
index f57d650..1ebf205 100644
--- a/gdb/hppa-netbsd-nat.c
+++ b/gdb/hppa-netbsd-nat.c
@@ -229,9 +229,7 @@ hppa_nbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
}
}
-void _initialize_hppanbsd_nat ();
-void
-_initialize_hppanbsd_nat ()
+INIT_GDB_FILE (hppanbsd_nat)
{
add_inf_child_target (&the_hppa_nbsd_nat_target);
}
diff --git a/gdb/hppa-netbsd-tdep.c b/gdb/hppa-netbsd-tdep.c
index e52e181..90d8eb8 100644
--- a/gdb/hppa-netbsd-tdep.c
+++ b/gdb/hppa-netbsd-tdep.c
@@ -210,9 +210,7 @@ hppanbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tramp_frame_prepend_unwinder (gdbarch, &hppanbsd_sigtramp_si4);
}
-void _initialize_hppanbsd_tdep ();
-void
-_initialize_hppanbsd_tdep ()
+INIT_GDB_FILE (hppanbsd_tdep)
{
gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_NETBSD,
hppanbsd_init_abi);
diff --git a/gdb/hppa-obsd-nat.c b/gdb/hppa-obsd-nat.c
index d879835..322b6f9 100644
--- a/gdb/hppa-obsd-nat.c
+++ b/gdb/hppa-obsd-nat.c
@@ -250,9 +250,7 @@ hppa_obsd_nat_target::store_registers (struct regcache *regcache, int regnum)
}
}
-void _initialize_hppaobsd_nat ();
-void
-_initialize_hppaobsd_nat ()
+INIT_GDB_FILE (hppaobsd_nat)
{
add_inf_child_target (&the_hppa_obsd_nat_target);
}
diff --git a/gdb/hppa-obsd-tdep.c b/gdb/hppa-obsd-tdep.c
index d2144f9..a511fa8 100644
--- a/gdb/hppa-obsd-tdep.c
+++ b/gdb/hppa-obsd-tdep.c
@@ -166,9 +166,7 @@ hppaobsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
(gdbarch, hppaobsd_iterate_over_regset_sections);
}
-void _initialize_hppabsd_tdep ();
-void
-_initialize_hppabsd_tdep ()
+INIT_GDB_FILE (hppabsd_tdep)
{
gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_OPENBSD,
hppaobsd_init_abi);
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c
index 3c9dde2..61e6cb2 100644
--- a/gdb/hppa-tdep.c
+++ b/gdb/hppa-tdep.c
@@ -3119,9 +3119,7 @@ hppa_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
gdb_printf (file, "elf = %s\n", tdep->is_elf ? "yes" : "no");
}
-void _initialize_hppa_tdep ();
-void
-_initialize_hppa_tdep ()
+INIT_GDB_FILE (hppa_tdep)
{
gdbarch_register (bfd_arch_hppa, hppa_gdbarch_init, hppa_dump_tdep);
diff --git a/gdb/i386-bsd-nat.c b/gdb/i386-bsd-nat.c
index ae9e090..c5eda86 100644
--- a/gdb/i386-bsd-nat.c
+++ b/gdb/i386-bsd-nat.c
@@ -237,9 +237,7 @@ i386bsd_store_inferior_registers (struct regcache *regcache, int regnum)
}
}
-void _initialize_i386bsd_nat ();
-void
-_initialize_i386bsd_nat ()
+INIT_GDB_FILE (i386bsd_nat)
{
/* To support the recognition of signal handlers, i386-bsd-tdep.c
hardcodes some constants. Inclusion of this file means that we
diff --git a/gdb/i386-darwin-nat.c b/gdb/i386-darwin-nat.c
index 08d3a71..09d6ba6 100644
--- a/gdb/i386-darwin-nat.c
+++ b/gdb/i386-darwin-nat.c
@@ -631,9 +631,7 @@ darwin_set_sstep (thread_t thread, int enable)
}
}
-void _initialize_i386_darwin_nat ();
-void
-_initialize_i386_darwin_nat ()
+INIT_GDB_FILE (i386_darwin_nat)
{
#ifdef BFD64
amd64_native_gregset64_reg_offset = amd64_darwin_thread_state_reg_offset;
diff --git a/gdb/i386-darwin-tdep.c b/gdb/i386-darwin-tdep.c
index 6180e02..a91afa2 100644
--- a/gdb/i386-darwin-tdep.c
+++ b/gdb/i386-darwin-tdep.c
@@ -271,7 +271,7 @@ i386_darwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
alignment. */
set_gdbarch_long_double_bit (gdbarch, 128);
- set_gdbarch_so_ops (gdbarch, &darwin_so_ops);
+ set_gdbarch_make_solib_ops (gdbarch, make_darwin_solib_ops);
}
static enum gdb_osabi
@@ -286,9 +286,7 @@ i386_mach_o_osabi_sniffer (bfd *abfd)
return GDB_OSABI_UNKNOWN;
}
-void _initialize_i386_darwin_tdep ();
-void
-_initialize_i386_darwin_tdep ()
+INIT_GDB_FILE (i386_darwin_tdep)
{
gdbarch_register_osabi_sniffer (bfd_arch_unknown, bfd_target_mach_o_flavour,
i386_mach_o_osabi_sniffer);
diff --git a/gdb/i386-dicos-tdep.c b/gdb/i386-dicos-tdep.c
index d3f19e2..50570c9 100644
--- a/gdb/i386-dicos-tdep.c
+++ b/gdb/i386-dicos-tdep.c
@@ -40,9 +40,7 @@ i386_dicos_osabi_sniffer (bfd *abfd)
return GDB_OSABI_UNKNOWN;
}
-void _initialize_i386_dicos_tdep ();
-void
-_initialize_i386_dicos_tdep ()
+INIT_GDB_FILE (i386_dicos_tdep)
{
gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour,
i386_dicos_osabi_sniffer);
diff --git a/gdb/i386-fbsd-nat.c b/gdb/i386-fbsd-nat.c
index 77f0edd..f4088a3 100644
--- a/gdb/i386-fbsd-nat.c
+++ b/gdb/i386-fbsd-nat.c
@@ -330,9 +330,7 @@ i386_fbsd_nat_target::read_description ()
return i386_target_description (X86_XSTATE_X87_MASK, true);
}
-void _initialize_i386fbsd_nat ();
-void
-_initialize_i386fbsd_nat ()
+INIT_GDB_FILE (i386fbsd_nat)
{
add_inf_child_target (&the_i386_fbsd_nat_target);
diff --git a/gdb/i386-fbsd-tdep.c b/gdb/i386-fbsd-tdep.c
index 72237d8..827d53c 100644
--- a/gdb/i386-fbsd-tdep.c
+++ b/gdb/i386-fbsd-tdep.c
@@ -402,8 +402,7 @@ i386fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
i386fbsd_core_read_description);
/* FreeBSD uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
set_gdbarch_fetch_tls_load_module_address (gdbarch,
svr4_fetch_objfile_link_map);
@@ -411,9 +410,7 @@ i386fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
i386fbsd_get_thread_local_address);
}
-void _initialize_i386fbsd_tdep ();
-void
-_initialize_i386fbsd_tdep ()
+INIT_GDB_FILE (i386fbsd_tdep)
{
gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_FREEBSD,
i386fbsd_init_abi);
diff --git a/gdb/i386-gnu-tdep.c b/gdb/i386-gnu-tdep.c
index 97fbc69..f944fa5 100644
--- a/gdb/i386-gnu-tdep.c
+++ b/gdb/i386-gnu-tdep.c
@@ -180,8 +180,7 @@ i386gnu_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* Hurd uses SVR4-style shared libraries. */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
/* Hurd uses the dynamic linker included in the GNU C Library. */
set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
@@ -202,9 +201,7 @@ i386gnu_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->sc_num_regs = ARRAY_SIZE (i386_gnu_sc_reg_offset);
}
-void _initialize_i386gnu_tdep ();
-void
-_initialize_i386gnu_tdep ()
+INIT_GDB_FILE (i386gnu_tdep)
{
gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_HURD, i386gnu_init_abi);
}
diff --git a/gdb/i386-go32-tdep.c b/gdb/i386-go32-tdep.c
index 4db09b3..e6a1721 100644
--- a/gdb/i386-go32-tdep.c
+++ b/gdb/i386-go32-tdep.c
@@ -61,9 +61,7 @@ i386_coff_osabi_sniffer (bfd *abfd)
}
-void _initialize_i386_go32_tdep ();
-void
-_initialize_i386_go32_tdep ()
+INIT_GDB_FILE (i386_go32_tdep)
{
gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
i386_coff_osabi_sniffer);
diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c
index a5d5582..f5112d2 100644
--- a/gdb/i386-linux-nat.c
+++ b/gdb/i386-linux-nat.c
@@ -696,9 +696,7 @@ i386_linux_nat_target::low_resume (ptid_t ptid, int step, enum gdb_signal signal
perror_with_name (("ptrace"));
}
-void _initialize_i386_linux_nat ();
-void
-_initialize_i386_linux_nat ()
+INIT_GDB_FILE (i386_linux_nat)
{
linux_target = &the_i386_linux_nat_target;
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
index 4b05cc6..efbde6a 100644
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -30,6 +30,7 @@
#include "i386-tdep.h"
#include "i386-linux-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "utils.h"
#include "glibc-tdep.h"
#include "solib-svr4.h"
@@ -1461,8 +1462,7 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* GNU/Linux uses SVR4-style shared libraries. */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
/* GNU/Linux uses the dynamic linker included in the GNU C Library. */
set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
@@ -1490,9 +1490,7 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
i386_linux_get_syscall_number);
}
-void _initialize_i386_linux_tdep ();
-void
-_initialize_i386_linux_tdep ()
+INIT_GDB_FILE (i386_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_LINUX,
i386_linux_init_abi);
diff --git a/gdb/i386-netbsd-nat.c b/gdb/i386-netbsd-nat.c
index 0f39fe1..efbf361 100644
--- a/gdb/i386-netbsd-nat.c
+++ b/gdb/i386-netbsd-nat.c
@@ -72,9 +72,7 @@ i386nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
static i386_bsd_nat_target<nbsd_nat_target> the_i386_nbsd_nat_target;
-void _initialize_i386nbsd_nat ();
-void
-_initialize_i386nbsd_nat ()
+INIT_GDB_FILE (i386nbsd_nat)
{
add_inf_child_target (&the_i386_nbsd_nat_target);
diff --git a/gdb/i386-netbsd-tdep.c b/gdb/i386-netbsd-tdep.c
index 701ce04..a1124d0 100644
--- a/gdb/i386-netbsd-tdep.c
+++ b/gdb/i386-netbsd-tdep.c
@@ -415,16 +415,13 @@ i386nbsdelf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
i386_elf_init_abi (info, gdbarch);
/* NetBSD ELF uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
/* NetBSD ELF uses -fpcc-struct-return by default. */
tdep->struct_return = pcc_struct_return;
}
-void _initialize_i386nbsd_tdep ();
-void
-_initialize_i386nbsd_tdep ()
+INIT_GDB_FILE (i386nbsd_tdep)
{
gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_NETBSD,
i386nbsdelf_init_abi);
diff --git a/gdb/i386-obsd-nat.c b/gdb/i386-obsd-nat.c
index 323acdb..f478e73 100644
--- a/gdb/i386-obsd-nat.c
+++ b/gdb/i386-obsd-nat.c
@@ -89,9 +89,7 @@ i386obsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
static i386_bsd_nat_target<obsd_nat_target> the_i386_obsd_nat_target;
-void _initialize_i386obsd_nat ();
-void
-_initialize_i386obsd_nat ()
+INIT_GDB_FILE (i386obsd_nat)
{
add_inf_child_target (&i386_obsd_nat_target);
diff --git a/gdb/i386-obsd-tdep.c b/gdb/i386-obsd-tdep.c
index be65668..1126597 100644
--- a/gdb/i386-obsd-tdep.c
+++ b/gdb/i386-obsd-tdep.c
@@ -441,13 +441,10 @@ i386obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
frame_unwind_prepend_unwinder (gdbarch, &i386obsd_trapframe_unwind);
/* OpenBSD ELF uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
}
-void _initialize_i386obsd_tdep ();
-void
-_initialize_i386obsd_tdep ()
+INIT_GDB_FILE (i386obsd_tdep)
{
gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_OPENBSD,
i386obsd_init_abi);
diff --git a/gdb/i386-sol2-nat.c b/gdb/i386-sol2-nat.c
index d0fb836..1e87007 100644
--- a/gdb/i386-sol2-nat.c
+++ b/gdb/i386-sol2-nat.c
@@ -252,9 +252,7 @@ fill_fpregset (const struct regcache *regcache,
#endif
-void _initialize_amd64_sol2_nat ();
-void
-_initialize_amd64_sol2_nat ()
+INIT_GDB_FILE (amd64_sol2_nat)
{
#if PR_MODEL_NATIVE == PR_MODEL_LP64
amd64_native_gregset32_reg_offset = amd64_sol2_gregset32_reg_offset;
diff --git a/gdb/i386-sol2-tdep.c b/gdb/i386-sol2-tdep.c
index e842236..4ff08d2 100644
--- a/gdb/i386-sol2-tdep.c
+++ b/gdb/i386-sol2-tdep.c
@@ -86,8 +86,7 @@ i386_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->sc_num_regs = tdep->gregset_num_regs;
/* Solaris has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
}
@@ -102,9 +101,7 @@ i386_sol2_osabi_sniffer (bfd *abfd)
return GDB_OSABI_UNKNOWN;
}
-void _initialize_i386_sol2_tdep ();
-void
-_initialize_i386_sol2_tdep ()
+INIT_GDB_FILE (i386_sol2_tdep)
{
/* Register an ELF OS ABI sniffer for Solaris 2 binaries. */
gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour,
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 23788b4..9be4748 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -8970,9 +8970,7 @@ i386_target_description (uint64_t xcr0, bool segments)
return *tdesc;
}
-void _initialize_i386_tdep ();
-void
-_initialize_i386_tdep ()
+INIT_GDB_FILE (i386_tdep)
{
gdbarch_register (bfd_arch_i386, i386_gdbarch_init);
diff --git a/gdb/i386-windows-nat.c b/gdb/i386-windows-nat.c
index 6c1369a..f878727 100644
--- a/gdb/i386-windows-nat.c
+++ b/gdb/i386-windows-nat.c
@@ -82,9 +82,7 @@ i386_windows_segment_register_p (int regnum)
return regnum >= I386_CS_REGNUM && regnum <= I386_GS_REGNUM;
}
-void _initialize_i386_windows_nat ();
-void
-_initialize_i386_windows_nat ()
+INIT_GDB_FILE (i386_windows_nat)
{
#ifndef __x86_64__
x86_set_debug_register_length (4);
diff --git a/gdb/i386-windows-tdep.c b/gdb/i386-windows-tdep.c
index 43ae5e4..892ecd4 100644
--- a/gdb/i386-windows-tdep.c
+++ b/gdb/i386-windows-tdep.c
@@ -229,9 +229,7 @@ i386_cygwin_core_osabi_sniffer (bfd *abfd)
return GDB_OSABI_UNKNOWN;
}
-void _initialize_i386_windows_tdep ();
-void
-_initialize_i386_windows_tdep ()
+INIT_GDB_FILE (i386_windows_tdep)
{
gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
i386_windows_osabi_sniffer);
diff --git a/gdb/ia64-libunwind-tdep.c b/gdb/ia64-libunwind-tdep.c
index 3ba9cb6..6d3b265 100644
--- a/gdb/ia64-libunwind-tdep.c
+++ b/gdb/ia64-libunwind-tdep.c
@@ -574,9 +574,7 @@ libunwind_is_initialized (void)
return libunwind_initialized;
}
-void _initialize_libunwind_frame ();
-void
-_initialize_libunwind_frame ()
+INIT_GDB_FILE (libunwind_frame)
{
libunwind_initialized = libunwind_load ();
}
diff --git a/gdb/ia64-linux-nat.c b/gdb/ia64-linux-nat.c
index 964b175..e833f9d 100644
--- a/gdb/ia64-linux-nat.c
+++ b/gdb/ia64-linux-nat.c
@@ -914,9 +914,7 @@ ia64_linux_nat_target::low_status_is_event (int status)
|| WSTOPSIG (status) == SIGILL);
}
-void _initialize_ia64_linux_nat ();
-void
-_initialize_ia64_linux_nat ()
+INIT_GDB_FILE (ia64_linux_nat)
{
/* Register the target. */
linux_target = &the_ia64_linux_nat_target;
diff --git a/gdb/ia64-linux-tdep.c b/gdb/ia64-linux-tdep.c
index c45b2bb..6afffee 100644
--- a/gdb/ia64-linux-tdep.c
+++ b/gdb/ia64-linux-tdep.c
@@ -26,6 +26,7 @@
#include "solib-svr4.h"
#include "symtab.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "regset.h"
#include <ctype.h>
@@ -235,8 +236,7 @@ ia64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_lp64_svr4_solib_ops);
/* Enable TLS support. */
set_gdbarch_fetch_tls_load_module_address (gdbarch,
@@ -257,9 +257,7 @@ ia64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
ia64_linux_stap_is_single_operand);
}
-void _initialize_ia64_linux_tdep ();
-void
-_initialize_ia64_linux_tdep ()
+INIT_GDB_FILE (ia64_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_ia64, 0, GDB_OSABI_LINUX,
ia64_linux_init_abi);
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
index 395b5f7..7c6526a 100644
--- a/gdb/ia64-tdep.c
+++ b/gdb/ia64-tdep.c
@@ -4014,9 +4014,7 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
return gdbarch;
}
-void _initialize_ia64_tdep ();
-void
-_initialize_ia64_tdep ()
+INIT_GDB_FILE (ia64_tdep)
{
gdbarch_register (bfd_arch_ia64, ia64_gdbarch_init, NULL);
}
diff --git a/gdb/ia64-vms-tdep.c b/gdb/ia64-vms-tdep.c
index dcd5598..32fe5d4 100644
--- a/gdb/ia64-vms-tdep.c
+++ b/gdb/ia64-vms-tdep.c
@@ -153,9 +153,7 @@ ia64_openvms_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
#endif
}
-void _initialize_ia64_vms_tdep ();
-void
-_initialize_ia64_vms_tdep ()
+INIT_GDB_FILE (ia64_vms_tdep)
{
gdbarch_register_osabi (bfd_arch_ia64, 0, GDB_OSABI_OPENVMS,
ia64_openvms_init_abi);
diff --git a/gdb/inf-child.c b/gdb/inf-child.c
index 016f30a..57ad0b4 100644
--- a/gdb/inf-child.c
+++ b/gdb/inf-child.c
@@ -322,11 +322,11 @@ inf_child_target::fileio_fstat (int fd, struct stat *sb, fileio_error *target_er
return ret;
}
-/* Implementation of to_fileio_stat. */
+/* Implementation of to_fileio_lstat. */
int
-inf_child_target::fileio_stat (struct inferior *inf, const char *filename,
- struct stat *sb, fileio_error *target_errno)
+inf_child_target::fileio_lstat (struct inferior *inf, const char *filename,
+ struct stat *sb, fileio_error *target_errno)
{
int ret;
diff --git a/gdb/inf-child.h b/gdb/inf-child.h
index 79b5157..70de393 100644
--- a/gdb/inf-child.h
+++ b/gdb/inf-child.h
@@ -81,8 +81,8 @@ public:
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_lstat (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/infcall.c b/gdb/infcall.c
index 098072d..2b5936d 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -1870,9 +1870,7 @@ When the function is done executing, GDB will silently stop."),
gdb_assert_not_reached ("... should not be here");
}
-void _initialize_infcall ();
-void
-_initialize_infcall ()
+INIT_GDB_FILE (infcall)
{
add_setshow_boolean_cmd ("may-call-functions", no_class,
&may_call_functions_p, _("\
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index e9b58ce..8978c8a 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -224,14 +224,11 @@ strip_bg_char (const char *args, int *bg_char_p)
return make_unique_xstrdup (args);
}
-/* Common actions to take after creating any sort of inferior, by any
- means (running, attaching, connecting, et cetera). The target
- should be stopped. */
+/* See inferior.h. */
void
-post_create_inferior (int from_tty)
+post_create_inferior (int from_tty, bool set_pspace_solib_ops)
{
-
/* Be sure we own the terminal in case write operations are performed. */
target_terminal::ours_for_output ();
@@ -261,6 +258,10 @@ post_create_inferior (int from_tty)
throw;
}
+ if (set_pspace_solib_ops)
+ current_program_space->set_solib_ops
+ (gdbarch_make_solib_ops (current_inferior ()->arch ()));
+
if (current_program_space->exec_bfd ())
{
const unsigned solib_add_generation
@@ -482,7 +483,7 @@ run_command_1 (const char *args, int from_tty, enum run_how run_how)
/* Pass zero for FROM_TTY, because at this point the "run" command
has done its thing; now we are setting up the running program. */
- post_create_inferior (0);
+ post_create_inferior (0, true);
/* Queue a pending event so that the program stops immediately. */
if (run_how == RUN_STOP_AT_FIRST_INSN)
@@ -2506,7 +2507,7 @@ setup_inferior (int from_tty)
/* Take any necessary post-attaching actions for this platform. */
target_post_attach (inferior_ptid.pid ());
- post_create_inferior (from_tty);
+ post_create_inferior (from_tty, true);
}
/* What to do after the first program stops after attaching. */
@@ -3080,9 +3081,7 @@ use \"set args\" without arguments.\n\
\n\
To start the inferior without using a shell, use \"set startup-with-shell off\"."
-void _initialize_infcmd ();
-void
-_initialize_infcmd ()
+INIT_GDB_FILE (infcmd)
{
static struct cmd_list_element *info_proc_cmdlist;
struct cmd_list_element *c = nullptr;
diff --git a/gdb/inferior.h b/gdb/inferior.h
index 54f5229..fe94e28 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -213,7 +213,14 @@ extern ptid_t gdb_startup_inferior (pid_t pid, int num_traps);
extern void setup_inferior (int from_tty);
-extern void post_create_inferior (int from_tty);
+/* Common actions to take after creating any sort of inferior, by any
+ means (running, attaching, connecting, et cetera). The target
+ should be stopped.
+
+ If SET_PSPACE_SOLIB_OPS is true, initialize the program space's solib
+ provider using the current inferior's architecture. */
+
+extern void post_create_inferior (int from_tty, bool set_pspace_solib_ops);
extern void attach_command (const char *, int);
diff --git a/gdb/inflow.c b/gdb/inflow.c
index f5ae6cd..31e1565 100644
--- a/gdb/inflow.c
+++ b/gdb/inflow.c
@@ -944,9 +944,7 @@ initialize_stdin_serial (void)
stdin_serial = serial_fdopen (0);
}
-void _initialize_inflow ();
-void
-_initialize_inflow ()
+INIT_GDB_FILE (inflow)
{
add_info ("terminal", info_terminal_command,
_("Print inferior's saved terminal status."));
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 0b87287..05bf6ab 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -58,7 +58,6 @@
#include "target-descriptions.h"
#include "target-dcache.h"
#include "terminal.h"
-#include "solist.h"
#include "gdbsupport/event-loop.h"
#include "thread-fsm.h"
#include "gdbsupport/enum-flags.h"
@@ -473,6 +472,7 @@ holding the child stopped. Try \"set %ps\" or \"%ps\".\n"),
inferior *parent_inf = current_inferior ();
inferior *child_inf = nullptr;
+ bool child_has_new_pspace = false;
gdb_assert (parent_inf->thread_waiting_for_vfork_done == nullptr);
@@ -537,6 +537,7 @@ holding the child stopped. Try \"set %ps\" or \"%ps\".\n"),
else
{
child_inf->pspace = new program_space (new_address_space ());
+ child_has_new_pspace = true;
child_inf->aspace = child_inf->pspace->aspace;
child_inf->removable = true;
clone_program_space (child_inf->pspace, parent_inf->pspace);
@@ -626,6 +627,7 @@ holding the child stopped. Try \"set %ps\" or \"%ps\".\n"),
else
{
child_inf->pspace = new program_space (new_address_space ());
+ child_has_new_pspace = true;
child_inf->aspace = child_inf->pspace->aspace;
child_inf->removable = true;
child_inf->symfile_flags = SYMFILE_NO_READ;
@@ -724,7 +726,8 @@ holding the child stopped. Try \"set %ps\" or \"%ps\".\n"),
maybe_restore.emplace ();
switch_to_thread (*child_inf->threads ().begin ());
- post_create_inferior (0);
+
+ post_create_inferior (0, child_has_new_pspace);
}
return false;
@@ -1322,6 +1325,7 @@ follow_exec (ptid_t ptid, const char *exec_file_target)
we don't want those to be satisfied by the libraries of the
previous incarnation of this process. */
no_shared_libraries (current_program_space);
+ current_program_space->unset_solib_ops ();
inferior *execing_inferior = current_inferior ();
inferior *following_inferior;
@@ -1378,6 +1382,8 @@ follow_exec (ptid_t ptid, const char *exec_file_target)
registers. */
target_find_description ();
+ current_program_space->set_solib_ops
+ (gdbarch_make_solib_ops (following_inferior->arch ()));
gdb::observers::inferior_execd.notify (execing_inferior, following_inferior);
breakpoint_re_set ();
@@ -3819,7 +3825,7 @@ start_remote (int from_tty)
/* Now that the inferior has stopped, do any bookkeeping like
loading shared libraries. We want to do this before normal_stop,
so that the displayed frame is up to date. */
- post_create_inferior (from_tty);
+ post_create_inferior (from_tty, true);
normal_stop ();
}
@@ -10532,9 +10538,7 @@ infrun_thread_ptid_changed ()
#endif /* GDB_SELF_TEST */
-void _initialize_infrun ();
-void
-_initialize_infrun ()
+INIT_GDB_FILE (infrun)
{
struct cmd_list_element *c;
diff --git a/gdb/inline-frame.c b/gdb/inline-frame.c
index d724c28..2191282 100644
--- a/gdb/inline-frame.c
+++ b/gdb/inline-frame.c
@@ -615,9 +615,7 @@ maintenance_info_inline_frames (const char *arg, int from_tty)
-void _initialize_inline_frame ();
-void
-_initialize_inline_frame ()
+INIT_GDB_FILE (inline_frame)
{
add_cmd ("inline-frames", class_maintenance, maintenance_info_inline_frames,
_("\
diff --git a/gdb/interps.c b/gdb/interps.c
index 00796bc..b4de3c7 100644
--- a/gdb/interps.c
+++ b/gdb/interps.c
@@ -575,9 +575,7 @@ interps_notify_memory_changed (inferior *inf, CORE_ADDR addr, ssize_t len,
}
/* This just adds the "interpreter-exec" command. */
-void _initialize_interpreter ();
-void
-_initialize_interpreter ()
+INIT_GDB_FILE (interpreter)
{
struct cmd_list_element *c;
diff --git a/gdb/interps.h b/gdb/interps.h
index 8d35309..c74495b 100644
--- a/gdb/interps.h
+++ b/gdb/interps.h
@@ -23,6 +23,7 @@
#define GDB_INTERPS_H
#include "gdbsupport/intrusive_list.h"
+#include "gdbsupport/event-loop.h"
struct bpstat;
struct ui_out;
@@ -78,6 +79,13 @@ public:
virtual void pre_command_loop ()
{}
+ /* Service one event.
+ This gives the interpreter a chance to handle its own private
+ events that cannot be fed into the gdb event mechanism.
+ In all cases, this should call gdb_do_one_event at some point. */
+ virtual int do_one_event (int mstimeout = -1)
+ { return gdb_do_one_event (mstimeout); }
+
/* Returns true if this interpreter supports using the readline
library; false if it uses GDB's own simplified readline
emulation. */
diff --git a/gdb/iq2000-tdep.c b/gdb/iq2000-tdep.c
index 49ae744..58a4dfb 100644
--- a/gdb/iq2000-tdep.c
+++ b/gdb/iq2000-tdep.c
@@ -840,9 +840,7 @@ iq2000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
Initializer function for the iq2000 module.
Called by gdb at start-up. */
-void _initialize_iq2000_tdep ();
-void
-_initialize_iq2000_tdep ()
+INIT_GDB_FILE (iq2000_tdep)
{
gdbarch_register (bfd_arch_iq2000, iq2000_gdbarch_init);
}
diff --git a/gdb/jit.c b/gdb/jit.c
index 1944e8a..0ea7bd9 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -1313,9 +1313,7 @@ show_jit_reader_directory (const char *args, int from_tty)
jit_reader_dir.c_str ()));
}
-void _initialize_jit ();
-void
-_initialize_jit ()
+INIT_GDB_FILE (jit)
{
jit_reader_dir = relocate_gdb_directory (JIT_READER_DIR,
JIT_READER_DIR_RELOCATABLE);
diff --git a/gdb/language.c b/gdb/language.c
index 18a7c9c..80f9b01 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -1095,9 +1095,7 @@ language_lookup_primitive_type_as_symbol (const struct language_defn *la,
/* Initialize the language routines. */
-void _initialize_language ();
-void
-_initialize_language ()
+INIT_GDB_FILE (language)
{
static const char *const type_or_range_names[]
= { "on", "off", "warn", "auto", NULL };
diff --git a/gdb/linespec.c b/gdb/linespec.c
index d42420c..b59c055 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -1016,7 +1016,7 @@ linespec_lexer_consume_token (linespec_parser *parser)
if (*parser->lexer.stream != '\0')
{
parser->completion_quote_char = '\0';
- parser->completion_quote_end = NULL;;
+ parser->completion_quote_end = NULL;
}
}
@@ -1074,6 +1074,12 @@ add_sal_to_sals (struct linespec_state *self,
struct symtab_and_line *sal,
const char *symname, bool literal_canonical)
{
+ /* We don't want two SALs with the same PC from the
+ same program space. */
+ for (const auto &s : *sals)
+ if (sal->pc == s.pc && sal->pspace == s.pspace)
+ return;
+
sals->push_back (*sal);
if (self->canonical)
@@ -3407,30 +3413,52 @@ lookup_prefix_sym (struct linespec_state *state,
return collector.release_symbols ();
}
-/* A std::sort comparison function for symbols. The resulting order does
- not actually matter; we just need to be able to sort them so that
- symbols with the same program space end up next to each other. */
+/* Compare pspace A and B based on program space ID. Return 0 if equal,
+ 1 if A->num > B->num, -1 otherwise (modeled on strcmp). */
-static bool
-compare_symbols (const block_symbol &a, const block_symbol &b)
+static int
+compare_pspace (const struct program_space *a, const struct program_space *b)
{
- uintptr_t uia, uib;
+ if (a->num > b->num)
+ return 1;
- uia = (uintptr_t) a.symbol->symtab ()->compunit ()->objfile ()->pspace ();
- uib = (uintptr_t) b.symbol->symtab ()->compunit ()->objfile ()->pspace ();
+ if (a->num < b->num)
+ return -1;
- if (uia < uib)
- return true;
- if (uia > uib)
- return false;
+ return 0;
+}
+
+/* An std::sort comparison function for pointers. Don't use this if stable
+ sorting results are required. */
+
+static bool
+compare_pointers (void *a, void *b)
+{
+ return (uintptr_t)a < (uintptr_t)b;
+}
- uia = (uintptr_t) a.symbol;
- uib = (uintptr_t) b.symbol;
+/* An std::sort comparison function for symbols. The requirement is that
+ symbols with the same program space end up next to each other. This is for
+ the purpose of iterating over the symbols and doing something once for each
+ program space. */
- if (uia < uib)
+static bool
+compare_symbols (const block_symbol &a, const block_symbol &b)
+{
+ /* To check for same program space, we could just use a pointer comparison,
+ which gives unstable sorting results. While the assumption is that this
+ doesn't matter, play it safe and compare program space IDs instead. */
+ int cmp
+ = compare_pspace (a.symbol->symtab ()->compunit ()->objfile ()->pspace (),
+ b.symbol->symtab ()->compunit ()->objfile ()->pspace ());
+ if (cmp == -1)
return true;
+ if (cmp == 1)
+ return false;
- return false;
+ /* This gives unstable sorting results. We assume that this doesn't
+ matter. */
+ return compare_pointers (a.symbol, b.symbol);
}
/* Like compare_symbols but for minimal symbols. */
@@ -3438,23 +3466,16 @@ compare_symbols (const block_symbol &a, const block_symbol &b)
static bool
compare_msymbols (const bound_minimal_symbol &a, const bound_minimal_symbol &b)
{
- uintptr_t uia, uib;
-
- uia = (uintptr_t) a.objfile->pspace ();
- uib = (uintptr_t) a.objfile->pspace ();
-
- if (uia < uib)
+ /* See comment in compare_symbols for use of compare_pspace. */
+ int cmp = compare_pspace (a.objfile->pspace (), a.objfile->pspace ());
+ if (cmp == -1)
return true;
- if (uia > uib)
+ if (cmp == 1)
return false;
- uia = (uintptr_t) a.minsym;
- uib = (uintptr_t) b.minsym;
-
- if (uia < uib)
- return true;
-
- return false;
+ /* This gives unstable sorting results. We assume that this doesn't
+ matter. */
+ return compare_pointers (a.minsym, b.minsym);
}
/* Look for all the matching instances of each symbol in NAMES. Only
diff --git a/gdb/linux-fork.c b/gdb/linux-fork.c
index 338ba03..9e986d8 100644
--- a/gdb/linux-fork.c
+++ b/gdb/linux-fork.c
@@ -1115,9 +1115,7 @@ restart_command (const char *args, int from_tty)
linux_fork_context (fp, from_tty, inf);
}
-void _initialize_linux_fork ();
-void
-_initialize_linux_fork ()
+INIT_GDB_FILE (linux_fork)
{
/* Checkpoint command: create a fork of the inferior process
and set it aside for later debugging. */
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 2f98060..70f77fd 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -2129,7 +2129,7 @@ linux_handle_extended_wait (struct lwp_info *lp, int status)
open_proc_mem_file (lp->ptid);
ourstatus->set_execd
- (make_unique_xstrdup (linux_proc_pid_to_exec_file (pid)));
+ (make_unique_xstrdup (linux_target->pid_to_exec_file (pid)));
/* The thread that execed must have been resumed, but, when a
thread execs, it changes its tid to the tgid, and the old
@@ -4000,7 +4000,14 @@ linux_nat_target::thread_name (struct thread_info *thr)
const char *
linux_nat_target::pid_to_exec_file (int pid)
{
- return linux_proc_pid_to_exec_file (pid);
+ /* If there's no sysroot. Or the sysroot is just 'target:' and the
+ inferior is in the same mount namespce, then we can consider the
+ filesystem local. */
+ bool local_fs = (gdb_sysroot.empty ()
+ || (gdb_sysroot == TARGET_SYSROOT_PREFIX
+ && linux_ns_same (pid, LINUX_NS_MNT)));
+
+ return linux_proc_pid_to_exec_file (pid, local_fs);
}
/* Object representing an /proc/PID/mem open file. We keep one such
@@ -4585,6 +4592,20 @@ linux_nat_target::fileio_open (struct inferior *inf, const char *filename,
return fd;
}
+/* Implementation of to_fileio_lstat. */
+
+int
+linux_nat_target::fileio_lstat (struct inferior *inf, const char *filename,
+ struct stat *sb, fileio_error *target_errno)
+{
+ int r = linux_mntns_lstat (linux_nat_fileio_pid_of (inf), filename, sb);
+
+ if (r == -1)
+ *target_errno = host_to_fileio_error (errno);
+
+ return r;
+}
+
/* Implementation of to_fileio_readlink. */
std::optional<std::string>
@@ -4707,9 +4728,7 @@ maintenance_info_lwps (const char *arg, int from_tty)
}
}
-void _initialize_linux_nat ();
-void
-_initialize_linux_nat ()
+INIT_GDB_FILE (linux_nat)
{
add_setshow_boolean_cmd ("linux-nat", class_maintenance,
&debug_linux_nat, _("\
diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h
index 6e53991..21ec309 100644
--- a/gdb/linux-nat.h
+++ b/gdb/linux-nat.h
@@ -108,6 +108,9 @@ public:
const char *filename,
fileio_error *target_errno) override;
+ int fileio_lstat (struct inferior *inf, const char *filename,
+ struct stat *sb, fileio_error *target_errno) override;
+
int fileio_unlink (struct inferior *inf,
const char *filename,
fileio_error *target_errno) override;
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index bbffb3d..5c4bbf6 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -630,9 +630,9 @@ mapping_is_anonymous_p (const char *filename)
return 0;
}
-/* Return 0 if the memory mapping (which is related to FILTERFLAGS, V,
- MAYBE_PRIVATE_P, MAPPING_ANONYMOUS_P, ADDR and OFFSET) should not
- be dumped, or greater than 0 if it should.
+/* Return false if the memory mapping represented by MAP should not be
+ dumped, or true if it should. FILTERFLAGS guides which mappings
+ should be dumped.
In a nutshell, this is the logic that we follow in order to decide
if a mapping should be dumped or not.
@@ -677,11 +677,14 @@ mapping_is_anonymous_p (const char *filename)
header (of a DSO or an executable, for example). If it is, and
if the user is interested in dump it, then we should dump it. */
-static int
-dump_mapping_p (filter_flags filterflags, const struct smaps_vmflags *v,
- int maybe_private_p, int mapping_anon_p, int mapping_file_p,
- const char *filename, ULONGEST addr, ULONGEST offset)
+static bool
+dump_mapping_p (filter_flags filterflags, const smaps_data &map)
{
+ /* Older Linux kernels did not support the "Anonymous:" counter.
+ If it is missing, we can't be sure what to dump, so dump everything. */
+ if (!map.has_anonymous)
+ return true;
+
/* Initially, we trust in what we received from our caller. This
value may not be very precise (i.e., it was probably gathered
from the permission line in the /proc/PID/smaps list, which
@@ -689,41 +692,42 @@ dump_mapping_p (filter_flags filterflags, const struct smaps_vmflags *v,
what we have until we take a look at the "VmFlags:" field
(assuming that the version of the Linux kernel being used
supports it, of course). */
- int private_p = maybe_private_p;
- int dump_p;
+ int private_p = map.priv;
/* We always dump vDSO and vsyscall mappings, because it's likely that
there'll be no file to read the contents from at core load time.
The kernel does the same. */
- if (strcmp ("[vdso]", filename) == 0
- || strcmp ("[vsyscall]", filename) == 0)
- return 1;
+ if (map.filename == "[vdso]" || map.filename == "[vsyscall]")
+ return true;
- if (v->initialized_p)
+ if (map.vmflags.initialized_p)
{
/* We never dump I/O mappings. */
- if (v->io_page)
- return 0;
+ if (map.vmflags.io_page)
+ return false;
/* Check if we should exclude this mapping. */
- if (!dump_excluded_mappings && v->exclude_coredump)
- return 0;
+ if (!dump_excluded_mappings && map.vmflags.exclude_coredump)
+ return false;
/* Update our notion of whether this mapping is shared or
private based on a trustworthy value. */
- private_p = !v->shared_mapping;
+ private_p = !map.vmflags.shared_mapping;
/* HugeTLB checking. */
- if (v->uses_huge_tlb)
+ if (map.vmflags.uses_huge_tlb)
{
if ((private_p && (filterflags & COREFILTER_HUGETLB_PRIVATE))
|| (!private_p && (filterflags & COREFILTER_HUGETLB_SHARED)))
- return 1;
+ return true;
- return 0;
+ return false;
}
}
+ int mapping_anon_p = map.mapping_anon_p;
+ int mapping_file_p = map.mapping_file_p;
+ bool dump_p;
if (private_p)
{
if (mapping_anon_p && mapping_file_p)
@@ -763,7 +767,7 @@ dump_mapping_p (filter_flags filterflags, const struct smaps_vmflags *v,
A mapping contains an ELF header if it is a private mapping, its
offset is zero, and its first word is ELFMAG. */
- if (!dump_p && private_p && offset == 0
+ if (!dump_p && private_p && map.offset == 0
&& (filterflags & COREFILTER_ELF_HEADERS) != 0)
{
/* Useful define specifying the size of the ELF magical
@@ -774,7 +778,7 @@ dump_mapping_p (filter_flags filterflags, const struct smaps_vmflags *v,
/* Let's check if we have an ELF header. */
gdb_byte h[SELFMAG];
- if (target_read_memory (addr, h, SELFMAG) == 0)
+ if (target_read_memory (map.start_address, h, SELFMAG) == 0)
{
/* The EI_MAG* and ELFMAG* constants come from
<elf/common.h>. */
@@ -783,7 +787,7 @@ dump_mapping_p (filter_flags filterflags, const struct smaps_vmflags *v,
{
/* This mapping contains an ELF header, so we
should dump it. */
- dump_p = 1;
+ dump_p = true;
}
}
}
@@ -794,20 +798,24 @@ dump_mapping_p (filter_flags filterflags, const struct smaps_vmflags *v,
/* As above, but return true only when we should dump the NT_FILE
entry. */
-static int
-dump_note_entry_p (filter_flags filterflags, const struct smaps_vmflags *v,
- int maybe_private_p, int mapping_anon_p, int mapping_file_p,
- const char *filename, ULONGEST addr, ULONGEST offset)
+static bool
+dump_note_entry_p (filter_flags filterflags, const smaps_data &map)
{
- /* vDSO and vsyscall mappings will end up in the core file. Don't
- put them in the NT_FILE note. */
- if (strcmp ("[vdso]", filename) == 0
- || strcmp ("[vsyscall]", filename) == 0)
- return 0;
+ /* No NT_FILE entry for mappings with no filename. */
+ if (map.filename.length () == 0)
+ return false;
+
+ /* Special kernel mappings, those with names like '[vdso]' and
+ '[vsyscall]' will be placed in the core file, but shouldn't get an
+ NT_FILE entry. These special mappings all have a zero inode. */
+ if (map.inode == 0
+ && map.filename.front () == '['
+ && map.filename.back () == ']')
+ return false;
/* Otherwise, any other file-based mapping should be placed in the
note. */
- return 1;
+ return true;
}
/* Implement the "info proc" command. */
@@ -1314,21 +1322,15 @@ linux_core_xfer_siginfo (struct gdbarch *gdbarch, gdb_byte *readbuf,
}
typedef int linux_find_memory_region_ftype (ULONGEST vaddr, ULONGEST size,
- ULONGEST offset, ULONGEST inode,
+ ULONGEST offset,
int read, int write,
int exec, int modified,
bool memory_tagged,
- const char *filename,
+ const std::string &filename,
void *data);
-typedef int linux_dump_mapping_p_ftype (filter_flags filterflags,
- const struct smaps_vmflags *v,
- int maybe_private_p,
- int mapping_anon_p,
- int mapping_file_p,
- const char *filename,
- ULONGEST addr,
- ULONGEST offset);
+typedef bool linux_dump_mapping_p_ftype (filter_flags filterflags,
+ const smaps_data &map);
/* Helper function to parse the contents of /proc/<pid>/smaps into a data
structure, for easy access.
@@ -1590,35 +1592,15 @@ linux_find_memory_regions_full (struct gdbarch *gdbarch,
for (const struct smaps_data &map : smaps)
{
- int should_dump_p = 0;
-
- if (map.has_anonymous)
- {
- should_dump_p
- = should_dump_mapping_p (filterflags, &map.vmflags,
- map.priv,
- map.mapping_anon_p,
- map.mapping_file_p,
- map.filename.c_str (),
- map.start_address,
- map.offset);
- }
- else
- {
- /* Older Linux kernels did not support the "Anonymous:" counter.
- If it is missing, we can't be sure - dump all the pages. */
- should_dump_p = 1;
- }
-
/* Invoke the callback function to create the corefile segment. */
- if (should_dump_p)
+ if (should_dump_mapping_p (filterflags, map))
{
func (map.start_address, map.end_address - map.start_address,
- map.offset, map.inode, map.read, map.write, map.exec,
+ map.offset, map.read, map.write, map.exec,
1, /* MODIFIED is true because we want to dump
the mapping. */
map.vmflags.memory_tagging != 0,
- map.filename.c_str (), obfd);
+ map.filename, obfd);
}
}
@@ -1644,10 +1626,10 @@ struct linux_find_memory_regions_data
static int
linux_find_memory_regions_thunk (ULONGEST vaddr, ULONGEST size,
- ULONGEST offset, ULONGEST inode,
+ ULONGEST offset,
int read, int write, int exec, int modified,
bool memory_tagged,
- const char *filename, void *arg)
+ const std::string &filename, void *arg)
{
struct linux_find_memory_regions_data *data
= (struct linux_find_memory_regions_data *) arg;
@@ -1693,8 +1675,6 @@ struct linux_make_mappings_data
struct type *long_type;
};
-static linux_find_memory_region_ftype linux_make_mappings_callback;
-
/* A callback for linux_find_memory_regions_full that updates the
mappings data for linux_make_mappings_corefile_notes.
@@ -1703,17 +1683,16 @@ static linux_find_memory_region_ftype linux_make_mappings_callback;
static int
linux_make_mappings_callback (ULONGEST vaddr, ULONGEST size,
- ULONGEST offset, ULONGEST inode,
+ ULONGEST offset,
int read, int write, int exec, int modified,
bool memory_tagged,
- const char *filename, void *data)
+ const std::string &filename, void *data)
{
struct linux_make_mappings_data *map_data
= (struct linux_make_mappings_data *) data;
gdb_byte buf[sizeof (ULONGEST)];
- if (*filename == '\0' || inode == 0)
- return 0;
+ gdb_assert (filename.length () > 0);
++map_data->file_count;
@@ -1724,7 +1703,7 @@ linux_make_mappings_callback (ULONGEST vaddr, ULONGEST size,
pack_long (buf, map_data->long_type, offset);
obstack_grow (map_data->data_obstack, buf, map_data->long_type->length ());
- obstack_grow_str0 (map_data->filename_obstack, filename);
+ obstack_grow_str0 (map_data->filename_obstack, filename.c_str ());
return 0;
}
@@ -3102,9 +3081,7 @@ linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch,
linux_corefile_parse_exec_context);
}
-void _initialize_linux_tdep ();
-void
-_initialize_linux_tdep ()
+INIT_GDB_FILE (linux_tdep)
{
/* Observers used to invalidate the cache when needed. */
gdb::observers::inferior_exit.attach (invalidate_linux_cache_inf,
@@ -3139,64 +3116,3 @@ more information about this file, refer to the manpage of proc(5) and core(5).")
&setlist, &showlist);
}
-
-/* Fetch (and possibly build) an appropriate `link_map_offsets' for
- ILP32/LP64 Linux systems which don't have the r_ldsomap field. */
-
-link_map_offsets *
-linux_ilp32_fetch_link_map_offsets ()
-{
- static link_map_offsets lmo;
- static link_map_offsets *lmp = nullptr;
-
- if (lmp == nullptr)
- {
- lmp = &lmo;
-
- lmo.r_version_offset = 0;
- lmo.r_version_size = 4;
- lmo.r_map_offset = 4;
- lmo.r_brk_offset = 8;
- lmo.r_ldsomap_offset = -1;
- lmo.r_next_offset = 20;
-
- /* Everything we need is in the first 20 bytes. */
- lmo.link_map_size = 20;
- lmo.l_addr_offset = 0;
- lmo.l_name_offset = 4;
- lmo.l_ld_offset = 8;
- lmo.l_next_offset = 12;
- lmo.l_prev_offset = 16;
- }
-
- return lmp;
-}
-
-link_map_offsets *
-linux_lp64_fetch_link_map_offsets ()
-{
- static link_map_offsets lmo;
- static link_map_offsets *lmp = nullptr;
-
- if (lmp == nullptr)
- {
- lmp = &lmo;
-
- lmo.r_version_offset = 0;
- lmo.r_version_size = 4;
- lmo.r_map_offset = 8;
- lmo.r_brk_offset = 16;
- lmo.r_ldsomap_offset = -1;
- lmo.r_next_offset = 40;
-
- /* Everything we need is in the first 40 bytes. */
- lmo.link_map_size = 40;
- lmo.l_addr_offset = 0;
- lmo.l_name_offset = 8;
- lmo.l_ld_offset = 16;
- lmo.l_next_offset = 24;
- lmo.l_prev_offset = 32;
- }
-
- return lmp;
-}
diff --git a/gdb/linux-tdep.h b/gdb/linux-tdep.h
index 7485fc1..3d82ea5 100644
--- a/gdb/linux-tdep.h
+++ b/gdb/linux-tdep.h
@@ -22,6 +22,7 @@
#include "bfd.h"
#include "displaced-stepping.h"
+#include "solib.h"
struct inferior;
struct regcache;
@@ -112,9 +113,4 @@ extern CORE_ADDR linux_get_hwcap2 (const std::optional<gdb::byte_vector> &auxv,
extern CORE_ADDR linux_get_hwcap2 ();
-/* Fetch (and possibly build) an appropriate `struct link_map_offsets'
- for ILP32 and LP64 Linux systems. */
-extern struct link_map_offsets *linux_ilp32_fetch_link_map_offsets ();
-extern struct link_map_offsets *linux_lp64_fetch_link_map_offsets ();
-
#endif /* GDB_LINUX_TDEP_H */
diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c
index f60116a..8d49508 100644
--- a/gdb/linux-thread-db.c
+++ b/gdb/linux-thread-db.c
@@ -1981,9 +1981,7 @@ maintenance_check_libthread_db (const char *args, int from_tty)
check_thread_db (info, true);
}
-void _initialize_thread_db ();
-void
-_initialize_thread_db ()
+INIT_GDB_FILE (thread_db)
{
/* Defer loading of libthread_db.so until inferior is running.
This allows gdb to load correct libthread_db for a given
diff --git a/gdb/lm32-tdep.c b/gdb/lm32-tdep.c
index ef956b8..cee2e51 100644
--- a/gdb/lm32-tdep.c
+++ b/gdb/lm32-tdep.c
@@ -536,9 +536,7 @@ lm32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
return gdbarch;
}
-void _initialize_lm32_tdep ();
-void
-_initialize_lm32_tdep ()
+INIT_GDB_FILE (lm32_tdep)
{
gdbarch_register (bfd_arch_lm32, lm32_gdbarch_init);
}
diff --git a/gdb/loongarch-linux-nat.c b/gdb/loongarch-linux-nat.c
index 3efaa5f..2b59b36 100644
--- a/gdb/loongarch-linux-nat.c
+++ b/gdb/loongarch-linux-nat.c
@@ -751,9 +751,7 @@ loongarch_linux_nat_target::low_forget_process (pid_t pid)
/* Initialize LoongArch Linux native support. */
-void _initialize_loongarch_linux_nat ();
-void
-_initialize_loongarch_linux_nat ()
+INIT_GDB_FILE (loongarch_linux_nat)
{
linux_target = &the_loongarch_linux_nat_target;
add_inf_child_target (&the_loongarch_linux_nat_target);
diff --git a/gdb/loongarch-linux-tdep.c b/gdb/loongarch-linux-tdep.c
index 38485e0..3766338 100644
--- a/gdb/loongarch-linux-tdep.c
+++ b/gdb/loongarch-linux-tdep.c
@@ -25,6 +25,7 @@
#include "inferior.h"
#include "linux-record.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "loongarch-tdep.h"
#include "record-full.h"
#include "regset.h"
@@ -1145,10 +1146,9 @@ loongarch_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
linux_init_abi (info, gdbarch, 0);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- info.bfd_arch_info->bits_per_address == 32
- ? linux_ilp32_fetch_link_map_offsets
- : linux_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, (info.bfd_arch_info->bits_per_address == 32
+ ? make_linux_ilp32_svr4_solib_ops
+ : make_linux_lp64_svr4_solib_ops));
/* GNU/Linux uses SVR4-style shared libraries. */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
@@ -1183,9 +1183,7 @@ loongarch_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* Initialize LoongArch Linux target support. */
-void _initialize_loongarch_linux_tdep ();
-void
-_initialize_loongarch_linux_tdep ()
+INIT_GDB_FILE (loongarch_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_loongarch, bfd_mach_loongarch32,
GDB_OSABI_LINUX, loongarch_linux_init_abi);
diff --git a/gdb/loongarch-tdep.c b/gdb/loongarch-tdep.c
index 092127dd..cc75cd4 100644
--- a/gdb/loongarch-tdep.c
+++ b/gdb/loongarch-tdep.c
@@ -74,7 +74,9 @@ loongarch_insn_is_cond_branch (insn_t insn)
|| (insn & 0xfc000000) == 0x68000000 /* bltu */
|| (insn & 0xfc000000) == 0x6c000000 /* bgeu */
|| (insn & 0xfc000000) == 0x40000000 /* beqz */
- || (insn & 0xfc000000) == 0x44000000) /* bnez */
+ || (insn & 0xfc000000) == 0x44000000 /* bnez */
+ || (insn & 0xfc000300) == 0x48000000 /* bceqz */
+ || (insn & 0xfc000300) == 0x48000100) /* bcnez */
return true;
return false;
}
@@ -314,6 +316,20 @@ loongarch_next_pc (struct regcache *regcache, CORE_ADDR cur_pc)
if (rj != 0)
next_pc = cur_pc + loongarch_decode_imm ("0:5|10:16<<2", insn, 1);
}
+ else if ((insn & 0xfc000300) == 0x48000000) /* bceqz cj, offs21 */
+ {
+ LONGEST cj = regcache_raw_get_signed (regcache,
+ loongarch_decode_imm ("5:3", insn, 0) + LOONGARCH_FIRST_FCC_REGNUM);
+ if (cj == 0)
+ next_pc = cur_pc + loongarch_decode_imm ("0:5|10:16<<2", insn, 1);
+ }
+ else if ((insn & 0xfc000300) == 0x48000100) /* bcnez cj, offs21 */
+ {
+ LONGEST cj = regcache_raw_get_signed (regcache,
+ loongarch_decode_imm ("5:3", insn, 0) + LOONGARCH_FIRST_FCC_REGNUM);
+ if (cj != 0)
+ next_pc = cur_pc + loongarch_decode_imm ("0:5|10:16<<2", insn, 1);
+ }
else if ((insn & 0xffff8000) == 0x002b0000) /* syscall */
{
if (tdep->syscall_next_pc != nullptr)
@@ -2405,9 +2421,7 @@ loongarch_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
return ret;
}
-void _initialize_loongarch_tdep ();
-void
-_initialize_loongarch_tdep ()
+INIT_GDB_FILE (loongarch_tdep)
{
gdbarch_register (bfd_arch_loongarch, loongarch_gdbarch_init, nullptr);
}
diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c
index f8937a2..8d99839 100644
--- a/gdb/m32c-tdep.c
+++ b/gdb/m32c-tdep.c
@@ -2653,9 +2653,7 @@ m32c_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
return gdbarch;
}
-void _initialize_m32c_tdep ();
-void
-_initialize_m32c_tdep ()
+INIT_GDB_FILE (m32c_tdep)
{
gdbarch_register (bfd_arch_m32c, m32c_gdbarch_init);
diff --git a/gdb/m32r-linux-nat.c b/gdb/m32r-linux-nat.c
index 7607bd2..c186693 100644
--- a/gdb/m32r-linux-nat.c
+++ b/gdb/m32r-linux-nat.c
@@ -234,9 +234,7 @@ m32r_linux_nat_target::store_registers (struct regcache *regcache, int regno)
internal_error (_("Got request to store bad register number %d."), regno);
}
-void _initialize_m32r_linux_nat ();
-void
-_initialize_m32r_linux_nat ()
+INIT_GDB_FILE (m32r_linux_nat)
{
/* Register the target. */
linux_target = &the_m32r_linux_nat_target;
diff --git a/gdb/m32r-linux-tdep.c b/gdb/m32r-linux-tdep.c
index 4fbe7d9..03000cc 100644
--- a/gdb/m32r-linux-tdep.c
+++ b/gdb/m32r-linux-tdep.c
@@ -36,6 +36,7 @@
#include "m32r-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "gdbarch.h"
@@ -461,8 +462,7 @@ m32r_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* GNU/Linux uses SVR4-style shared libraries. */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
/* Core file support. */
set_gdbarch_iterate_over_regset_sections
@@ -473,9 +473,7 @@ m32r_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
svr4_fetch_objfile_link_map);
}
-void _initialize_m32r_linux_tdep ();
-void
-_initialize_m32r_linux_tdep ()
+INIT_GDB_FILE (m32r_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_m32r, 0, GDB_OSABI_LINUX,
m32r_linux_init_abi);
diff --git a/gdb/m32r-tdep.c b/gdb/m32r-tdep.c
index 6b6ad03..4ac08fd 100644
--- a/gdb/m32r-tdep.c
+++ b/gdb/m32r-tdep.c
@@ -908,9 +908,7 @@ m32r_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
return gdbarch;
}
-void _initialize_m32r_tdep ();
-void
-_initialize_m32r_tdep ()
+INIT_GDB_FILE (m32r_tdep)
{
gdbarch_register (bfd_arch_m32r, m32r_gdbarch_init);
}
diff --git a/gdb/m68hc11-tdep.c b/gdb/m68hc11-tdep.c
index dd8cbda..5389fee 100644
--- a/gdb/m68hc11-tdep.c
+++ b/gdb/m68hc11-tdep.c
@@ -1527,9 +1527,7 @@ m68hc11_gdbarch_init (struct gdbarch_info info,
return gdbarch;
}
-void _initialize_m68hc11_tdep ();
-void
-_initialize_m68hc11_tdep ()
+INIT_GDB_FILE (m68hc11_tdep)
{
gdbarch_register (bfd_arch_m68hc11, m68hc11_gdbarch_init);
gdbarch_register (bfd_arch_m68hc12, m68hc11_gdbarch_init);
diff --git a/gdb/m68k-bsd-nat.c b/gdb/m68k-bsd-nat.c
index 04542fd..ae8fa4d 100644
--- a/gdb/m68k-bsd-nat.c
+++ b/gdb/m68k-bsd-nat.c
@@ -225,9 +225,7 @@ m68kbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
return 1;
}
-void _initialize_m68kbsd_nat ();
-void
-_initialize_m68kbsd_nat ()
+INIT_GDB_FILE (m68kbsd_nat)
{
add_inf_child_target (&the_m68k_bsd_nat_target);
diff --git a/gdb/m68k-bsd-tdep.c b/gdb/m68k-bsd-tdep.c
index 09c57c6..37c1464 100644
--- a/gdb/m68k-bsd-tdep.c
+++ b/gdb/m68k-bsd-tdep.c
@@ -147,13 +147,10 @@ m68kbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->struct_return = pcc_struct_return;
/* NetBSD ELF uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
}
-void _initialize_m68kbsd_tdep ();
-void
-_initialize_m68kbsd_tdep ()
+INIT_GDB_FILE (m68kbsd_tdep)
{
gdbarch_register_osabi (bfd_arch_m68k, 0, GDB_OSABI_NETBSD,
m68kbsd_init_abi);
diff --git a/gdb/m68k-linux-nat.c b/gdb/m68k-linux-nat.c
index d43ed68..02286ff 100644
--- a/gdb/m68k-linux-nat.c
+++ b/gdb/m68k-linux-nat.c
@@ -508,9 +508,7 @@ ps_get_thread_area (struct ps_prochandle *ph,
return PS_OK;
}
-void _initialize_m68k_linux_nat ();
-void
-_initialize_m68k_linux_nat ()
+INIT_GDB_FILE (m68k_linux_nat)
{
/* Register the target. */
linux_target = &the_m68k_linux_nat_target;
diff --git a/gdb/m68k-linux-tdep.c b/gdb/m68k-linux-tdep.c
index cfc37ab..bd2a14a 100644
--- a/gdb/m68k-linux-tdep.c
+++ b/gdb/m68k-linux-tdep.c
@@ -35,6 +35,7 @@
#include "observable.h"
#include "elf/common.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "regset.h"
/* Offsets (in target ints) into jmp_buf. */
@@ -407,8 +408,7 @@ m68k_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* Shared library handling. */
/* GNU/Linux uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
/* GNU/Linux uses the dynamic linker included in the GNU C Library. */
set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
@@ -424,9 +424,7 @@ m68k_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
svr4_fetch_objfile_link_map);
}
-void _initialize_m68k_linux_tdep ();
-void
-_initialize_m68k_linux_tdep ()
+INIT_GDB_FILE (m68k_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_m68k, 0, GDB_OSABI_LINUX,
m68k_linux_init_abi);
diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c
index 4e25518..94bfddb 100644
--- a/gdb/m68k-tdep.c
+++ b/gdb/m68k-tdep.c
@@ -1365,9 +1365,7 @@ m68k_osabi_sniffer (bfd *abfd)
return osabi;
}
-void _initialize_m68k_tdep ();
-void
-_initialize_m68k_tdep ()
+INIT_GDB_FILE (m68k_tdep)
{
gdbarch_register (bfd_arch_m68k, m68k_gdbarch_init, m68k_dump_tdep);
diff --git a/gdb/machoread.c b/gdb/machoread.c
index cc8aca3..ffee181 100644
--- a/gdb/machoread.c
+++ b/gdb/machoread.c
@@ -940,9 +940,7 @@ static const struct sym_fns macho_sym_fns = {
NULL, /* sym_get_probes */
};
-void _initialize_machoread ();
-void
-_initialize_machoread ()
+INIT_GDB_FILE (machoread)
{
add_symtab_fns (bfd_target_mach_o_flavour, &macho_sym_fns);
diff --git a/gdb/macrocmd.c b/gdb/macrocmd.c
index 0192a00..d805f3d 100644
--- a/gdb/macrocmd.c
+++ b/gdb/macrocmd.c
@@ -57,11 +57,11 @@ macro_expand_command (const char *exp, int from_tty)
" expression you\n"
"want to expand."));
- gdb::unique_xmalloc_ptr<macro_scope> ms = default_macro_scope ();
+ macro_scope ms = default_macro_scope ();
- if (ms != nullptr)
+ if (ms.is_valid ())
{
- gdb::unique_xmalloc_ptr<char> expanded = macro_expand (exp, *ms);
+ gdb::unique_xmalloc_ptr<char> expanded = macro_expand (exp, ms);
gdb_puts ("expands to: ");
gdb_puts (expanded.get ());
@@ -85,11 +85,11 @@ macro_expand_once_command (const char *exp, int from_tty)
" the expression\n"
"you want to expand."));
- gdb::unique_xmalloc_ptr<macro_scope> ms = default_macro_scope ();
+ macro_scope ms = default_macro_scope ();
- if (ms != nullptr)
+ if (ms.is_valid ())
{
- gdb::unique_xmalloc_ptr<char> expanded = macro_expand_once (exp, *ms);
+ gdb::unique_xmalloc_ptr<char> expanded = macro_expand_once (exp, ms);
gdb_puts ("expands to: ");
gdb_puts (expanded.get ());
@@ -169,7 +169,6 @@ print_macro_definition (const char *name,
static void
info_macro_command (const char *args, int from_tty)
{
- gdb::unique_xmalloc_ptr<struct macro_scope> ms;
const char *name;
int show_all_macros_named = 0;
const char *arg_start = args;
@@ -201,15 +200,15 @@ info_macro_command (const char *args, int from_tty)
" of the macro\n"
"whose definition you want to see."));
- ms = default_macro_scope ();
+ macro_scope ms = default_macro_scope ();
- if (! ms)
+ if (!ms.is_valid ())
macro_inform_no_debuginfo ();
else if (show_all_macros_named)
- macro_for_each (ms->file->table, [&] (const char *macro_name,
- const macro_definition *macro,
- macro_source_file *source,
- int line)
+ macro_for_each (ms.file->table, [&] (const char *macro_name,
+ const macro_definition *macro,
+ macro_source_file *source,
+ int line)
{
if (strcmp (name, macro_name) == 0)
print_macro_definition (name, macro, source, line);
@@ -218,12 +217,12 @@ info_macro_command (const char *args, int from_tty)
{
struct macro_definition *d;
- d = macro_lookup_definition (ms->file, ms->line, name);
+ d = macro_lookup_definition (ms.file, ms.line, name);
if (d)
{
int line;
struct macro_source_file *file
- = macro_definition_location (ms->file, ms->line, name, &line);
+ = macro_definition_location (ms.file, ms.line, name, &line);
print_macro_definition (name, d, file, line);
}
@@ -232,7 +231,7 @@ info_macro_command (const char *args, int from_tty)
gdb_printf ("The symbol `%s' has no definition as a C/C++"
" preprocessor macro\n"
"at ", name);
- show_pp_source_pos (gdb_stdout, ms->file, ms->line);
+ show_pp_source_pos (gdb_stdout, ms.file, ms.line);
}
}
}
@@ -241,7 +240,7 @@ info_macro_command (const char *args, int from_tty)
static void
info_macros_command (const char *args, int from_tty)
{
- gdb::unique_xmalloc_ptr<struct macro_scope> ms;
+ macro_scope ms;
if (args == NULL)
ms = default_macro_scope ();
@@ -254,10 +253,10 @@ info_macros_command (const char *args, int from_tty)
ms = sal_macro_scope (sals[0]);
}
- if (! ms || ! ms->file || ! ms->file->table)
+ if (!ms.is_valid () || ms.file->table == nullptr)
macro_inform_no_debuginfo ();
else
- macro_for_each_in_scope (ms->file, ms->line, print_macro_definition);
+ macro_for_each_in_scope (ms.file, ms.line, print_macro_definition);
}
@@ -409,9 +408,7 @@ macro_list_command (const char *exp, int from_tty)
/* Initializing the `macrocmd' module. */
-void _initialize_macrocmd ();
-void
-_initialize_macrocmd ()
+INIT_GDB_FILE (macrocmd)
{
/* We introduce a new command prefix, `macro', under which we'll put
the various commands for working with preprocessor macros. */
diff --git a/gdb/macroscope.c b/gdb/macroscope.c
index 97b41b6..7aa0784 100644
--- a/gdb/macroscope.c
+++ b/gdb/macroscope.c
@@ -34,28 +34,29 @@
struct macro_table *macro_user_macros;
-gdb::unique_xmalloc_ptr<struct macro_scope>
+macro_scope
sal_macro_scope (struct symtab_and_line sal)
{
+ macro_scope result;
struct macro_source_file *main_file, *inclusion;
struct compunit_symtab *cust;
if (sal.symtab == NULL)
- return NULL;
+ return result;
cust = sal.symtab->compunit ();
if (cust->macro_table () == NULL)
- return NULL;
+ return result;
- gdb::unique_xmalloc_ptr<struct macro_scope> ms (XNEW (struct macro_scope));
+ macro_scope ms;
main_file = macro_main (cust->macro_table ());
inclusion = macro_lookup_inclusion (main_file, sal.symtab->filename_for_id);
if (inclusion)
{
- ms->file = inclusion;
- ms->line = sal.line;
+ ms.file = inclusion;
+ ms.line = sal.line;
}
else
{
@@ -73,8 +74,8 @@ sal_macro_scope (struct symtab_and_line sal)
For the time being, though, we'll just treat these as
occurring at the end of the main source file. */
- ms->file = main_file;
- ms->line = -1;
+ ms.file = main_file;
+ ms.line = -1;
complaint (_("symtab found for `%s', but that file\n"
"is not covered in the compilation unit's macro information"),
@@ -85,20 +86,16 @@ sal_macro_scope (struct symtab_and_line sal)
}
-gdb::unique_xmalloc_ptr<struct macro_scope>
-user_macro_scope (void)
+macro_scope
+user_macro_scope ()
{
- gdb::unique_xmalloc_ptr<struct macro_scope> ms (XNEW (struct macro_scope));
- ms->file = macro_main (macro_user_macros);
- ms->line = -1;
- return ms;
+ return { macro_main (macro_user_macros), -1 };
}
-gdb::unique_xmalloc_ptr<struct macro_scope>
-default_macro_scope (void)
+macro_scope
+default_macro_scope ()
{
struct symtab_and_line sal;
- gdb::unique_xmalloc_ptr<struct macro_scope> ms;
frame_info_ptr frame;
CORE_ADDR pc;
@@ -128,8 +125,8 @@ default_macro_scope (void)
sal.line = cursal.line;
}
- ms = sal_macro_scope (sal);
- if (! ms)
+ macro_scope ms = sal_macro_scope (sal);
+ if (!ms.is_valid ())
ms = user_macro_scope ();
return ms;
@@ -152,9 +149,7 @@ standard_macro_lookup (const char *name, const macro_scope &ms)
return result;
}
-void _initialize_macroscope ();
-void
-_initialize_macroscope ()
+INIT_GDB_FILE (macroscope)
{
macro_user_macros = new_macro_table (NULL, NULL, NULL);
macro_set_main (macro_user_macros, "<user-defined>");
diff --git a/gdb/macroscope.h b/gdb/macroscope.h
index de3186d..2cb6a0f 100644
--- a/gdb/macroscope.h
+++ b/gdb/macroscope.h
@@ -31,21 +31,25 @@ extern struct macro_table *macro_user_macros;
in scope: a source file (either a main source file or an
#inclusion), and a line number in that file. */
struct macro_scope {
- struct macro_source_file *file;
- int line;
+ struct macro_source_file *file = nullptr;
+ int line = 0;
+
+ /* Return true if this scope is valid. */
+ bool is_valid () const
+ {
+ return file != nullptr;
+ }
};
/* Return a `struct macro_scope' object corresponding to the symtab
and line given in SAL. If we have no macro information for that
- location, or if SAL's pc is zero, return zero. */
-gdb::unique_xmalloc_ptr<struct macro_scope> sal_macro_scope
- (struct symtab_and_line sal);
-
+ location, or if SAL's pc is zero, return an invalid scope. */
+macro_scope sal_macro_scope (struct symtab_and_line sal);
/* Return a `struct macro_scope' object representing just the
user-defined macros. */
-gdb::unique_xmalloc_ptr<struct macro_scope> user_macro_scope (void);
+macro_scope user_macro_scope ();
/* Return a `struct macro_scope' object describing the scope the `macro
expand' and `macro expand-once' commands should use for looking up
@@ -54,7 +58,7 @@ gdb::unique_xmalloc_ptr<struct macro_scope> user_macro_scope (void);
If we have no macro information for the current location, return
the user macro scope. */
-gdb::unique_xmalloc_ptr<struct macro_scope> default_macro_scope (void);
+macro_scope default_macro_scope ();
/* Look up the definition of the macro named NAME in scope at the source
location given by MS. */
diff --git a/gdb/main.c b/gdb/main.c
index 2dcb67d..1806ca0 100644
--- a/gdb/main.c
+++ b/gdb/main.c
@@ -399,7 +399,7 @@ start_event_loop ()
try
{
- result = gdb_do_one_event ();
+ result = current_interpreter ()->do_one_event ();
}
catch (const gdb_exception_forced_quit &ex)
{
diff --git a/gdb/maint-test-options.c b/gdb/maint-test-options.c
index 25f609b..97236c9 100644
--- a/gdb/maint-test-options.c
+++ b/gdb/maint-test-options.c
@@ -429,9 +429,7 @@ maintenance_test_options_unknown_is_operand_command_completer
static cmd_list_element *maintenance_test_options_list;
-void _initialize_maint_test_options ();
-void
-_initialize_maint_test_options ()
+INIT_GDB_FILE (maint_test_options)
{
cmd_list_element *cmd;
diff --git a/gdb/maint-test-settings.c b/gdb/maint-test-settings.c
index 663190a..c7b12c6 100644
--- a/gdb/maint-test-settings.c
+++ b/gdb/maint-test-settings.c
@@ -78,9 +78,7 @@ maintenance_show_test_settings_value_cmd
}
-void _initialize_maint_test_settings ();
-void
-_initialize_maint_test_settings ()
+INIT_GDB_FILE (maint_test_settings)
{
maintenance_test_settings_filename = "/foo/bar";
diff --git a/gdb/maint.c b/gdb/maint.c
index c6f9b32..78dea22 100644
--- a/gdb/maint.c
+++ b/gdb/maint.c
@@ -920,9 +920,9 @@ maintenance_show_worker_threads (struct ui_file *file, int from_tty,
}
-/* If true, display time usage both at startup and for each command. */
+/* See maint.h. */
-static bool per_command_time;
+bool per_command_time;
/* If true, display space usage both at startup and for each command. */
@@ -1151,10 +1151,32 @@ set_per_command_cmd (const char *args, int from_tty)
}
}
+/* Handle "mt set per-command time". Warn if per-thread run time
+ information is not possible. */
+
+static void
+maintenance_set_command_time_cmd (const char *args, int from_tty,
+ cmd_list_element *c)
+{
+ /* No point warning if this platform can't use multiple threads at
+ all. */
+#if CXX_STD_THREAD
+ static bool already_warned = false;
+ if (per_command_time
+ && !get_run_time_thread_scope_available ()
+ && !already_warned)
+ {
+ warning (_("\
+per-thread run time information not available on this platform"));
+ already_warned = true;
+ }
+#endif
+}
+
/* See maint.h. */
-scoped_time_it::scoped_time_it (const char *what)
- : m_enabled (per_command_time),
+scoped_time_it::scoped_time_it (const char *what, bool enabled)
+ : m_enabled (enabled),
m_what (what),
m_start_wall (m_enabled
? std::chrono::steady_clock::now ()
@@ -1279,9 +1301,7 @@ Selftests have been disabled for this build.\n"));
}
-void _initialize_maint_cmds ();
-void
-_initialize_maint_cmds ()
+INIT_GDB_FILE (maint_cmds)
{
struct cmd_list_element *cmd;
@@ -1423,7 +1443,7 @@ Show whether to display per-command execution time."),
_("\
If enabled, the execution time for each command will be\n\
displayed following the command's output."),
- NULL, NULL,
+ maintenance_set_command_time_cmd, NULL,
&per_command_setlist, &per_command_showlist);
add_setshow_boolean_cmd ("space", class_maintenance,
diff --git a/gdb/maint.h b/gdb/maint.h
index 28e6280..6930018 100644
--- a/gdb/maint.h
+++ b/gdb/maint.h
@@ -61,7 +61,9 @@ class scoped_command_stats
bool m_symtab_enabled : 1;
run_time_clock::time_point m_start_cpu_time;
std::chrono::steady_clock::time_point m_start_wall_time;
+#ifdef HAVE_USEFUL_SBRK
long m_start_space;
+#endif
/* Total number of symtabs (over all objfiles). */
int m_start_nr_symtabs;
/* A count of the compunits. */
@@ -70,13 +72,17 @@ class scoped_command_stats
int m_start_nr_blocks;
};
+/* If true, display time usage both at startup and for each command. */
+
+extern bool per_command_time;
+
/* RAII structure used to measure the time spent by the current thread in a
given scope. */
struct scoped_time_it
{
/* WHAT is the prefix to show when the summary line is printed. */
- scoped_time_it (const char *what);
+ scoped_time_it (const char *what, bool enabled = per_command_time);
DISABLE_COPY_AND_ASSIGN (scoped_time_it);
~scoped_time_it ();
diff --git a/gdb/make-init-c b/gdb/make-init-c
index 4f0185c..6834b43 100755
--- a/gdb/make-init-c
+++ b/gdb/make-init-c
@@ -25,12 +25,13 @@
#
# Where SOURCE-FILES is the list of source files to extract init functions from.
#
-# Formatting conventions: The name of the initialization routines must begin
-# with `_initialize_`, must start in column zero, and be followed with exactly
-# ` ()`. For example:
+
+# An initialization function is introduced using the "INIT_GDB_FILE"
+# macro. In ordinary code this expands to a function declaration (to
+# avoid a warning) and then the start of a definition. In the
+# generated init.c, though, it is expanded differently. For example:
#
-# void
-# _initialize_foo ()
+# INIT_GDB_FILE (foo)
# {
# ...
# }
@@ -43,19 +44,21 @@ echo "/* Do not modify this file. */"
echo "/* It is created automatically by the Makefile. */"
echo "#include <algorithm>"
echo ""
-sed -n -e 's/^\(_initialize_[a-zA-Z0-9_]*\) ()$/\1/p' "$@" | while read -r name; do
- echo "extern initialize_file_ftype $name;"
-done
+echo "#undef INIT_GDB_FILE"
+echo "#define INIT_GDB_FILE(NAME) extern void _initialize_ ## NAME ();"
+grep -h '^[ ]*INIT_GDB_FILE\b' "$@"
echo ""
echo "void initialize_all_files ();"
echo "void"
echo "initialize_all_files ()"
echo "{"
+echo " typedef void initialize_file_ftype (void);"
+echo ""
echo " std::vector<initialize_file_ftype *> functions ="
echo " {"
-sed -n -e 's/^\(_initialize_[a-zA-Z0-9_]*\) ()$/\1/p' "$@" | while read -r name; do
- echo " $name,"
-done
+echo "#undef INIT_GDB_FILE"
+echo "#define INIT_GDB_FILE(NAME) _initialize_ ## NAME,"
+grep -h '^[ ]*INIT_GDB_FILE\b' "$@"
echo " };"
echo ""
echo " /* If GDB_REVERSE_INIT_FUNCTIONS is set (any value), reverse the"
diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c
index 72af117..5bb15c2 100644
--- a/gdb/mdebugread.c
+++ b/gdb/mdebugread.c
@@ -329,7 +329,7 @@ fdr_name (FDR *f)
/* Read in and parse the symtab of the file OBJFILE. Symbols from
different sections are relocated via the SECTION_OFFSETS. */
-void
+static void
mdebug_build_psymtabs (minimal_symbol_reader &reader,
struct objfile *objfile,
const struct ecoff_debug_swap *swap,
@@ -4792,9 +4792,28 @@ elfmdebug_build_psymtabs (struct objfile *objfile,
reader.install ();
}
-void _initialize_mdebugread ();
+/* see mdebugread.h. */
+
void
-_initialize_mdebugread ()
+mipsmdebug_build_psymtabs (struct objfile *objfile,
+ const struct ecoff_debug_swap *swap,
+ struct ecoff_debug_info *info)
+{
+ bfd *abfd = objfile->obfd.get ();
+
+ minimal_symbol_reader reader (objfile);
+
+ if (!(*swap->read_debug_info) (abfd, nullptr,
+ info))
+ error (_("Error reading ECOFF debugging information: %s"),
+ bfd_errmsg (bfd_get_error ()));
+
+ mdebug_build_psymtabs (reader, objfile, swap, info);
+
+ reader.install ();
+}
+
+INIT_GDB_FILE (mdebugread)
{
mdebug_register_index
= register_symbol_register_impl (LOC_REGISTER, &mdebug_register_funcs);
diff --git a/gdb/mdebugread.h b/gdb/mdebugread.h
index be26f46..f7e9f98 100644
--- a/gdb/mdebugread.h
+++ b/gdb/mdebugread.h
@@ -37,13 +37,38 @@ struct mdebug_extra_func_info
#define MDEBUG_EFI_SYMBOL_NAME "__GDB_EFI_INFO__"
-extern void mdebug_build_psymtabs (minimal_symbol_reader &,
- struct objfile *,
- const struct ecoff_debug_swap *,
- struct ecoff_debug_info *);
+#if defined(MDEBUG_FORMAT_AVAILABLE)
extern void elfmdebug_build_psymtabs (struct objfile *,
const struct ecoff_debug_swap *,
asection *);
+/* Read ECOFF debugging information from a BFD section. This is
+ called from mipsread.c. It parses the section into a
+ ecoff_debug_info struct, and then lets the rest of the file handle
+ it as normal. */
+extern void mipsmdebug_build_psymtabs (struct objfile *,
+ const struct ecoff_debug_swap *,
+ struct ecoff_debug_info *);
+
+#else /* MDEBUG_FORMAT_AVAILABLE */
+
+static inline void
+elfmdebug_build_psymtabs (struct objfile *,
+ const struct ecoff_debug_swap *,
+ asection *)
+{
+ warning (_("No mdebug support available"));
+}
+
+static inline void
+mipsmdebug_build_psymtabs (struct objfile *,
+ const struct ecoff_debug_swap *,
+ struct ecoff_debug_info *)
+{
+ warning (_("No mdebug support available"));
+}
+
+#endif /* MDEBUG_FORMAT_AVAILABLE */
+
#endif /* GDB_MDEBUGREAD_H */
diff --git a/gdb/memattr.c b/gdb/memattr.c
index 81d0de0..9d26d31 100644
--- a/gdb/memattr.c
+++ b/gdb/memattr.c
@@ -592,9 +592,7 @@ delete_mem_command (const char *args, int from_tty)
static struct cmd_list_element *mem_set_cmdlist;
static struct cmd_list_element *mem_show_cmdlist;
-void _initialize_mem ();
-void
-_initialize_mem ()
+INIT_GDB_FILE (mem)
{
add_com ("mem", class_vars, mem_command, _("\
Define or reset attributes for memory regions.\n\
diff --git a/gdb/mep-tdep.c b/gdb/mep-tdep.c
index 60bae3a..30a6018 100644
--- a/gdb/mep-tdep.c
+++ b/gdb/mep-tdep.c
@@ -2459,9 +2459,7 @@ mep_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
return gdbarch;
}
-void _initialize_mep_tdep ();
-void
-_initialize_mep_tdep ()
+INIT_GDB_FILE (mep_tdep)
{
mep_csr_reggroup = reggroup_new ("csr", USER_REGGROUP);
mep_cr_reggroup = reggroup_new ("cr", USER_REGGROUP);
diff --git a/gdb/mi/mi-cmd-env.c b/gdb/mi/mi-cmd-env.c
index e79af9c..bc2fe77 100644
--- a/gdb/mi/mi-cmd-env.c
+++ b/gdb/mi/mi-cmd-env.c
@@ -236,9 +236,7 @@ mi_cmd_inferior_tty_show (const char *command, const char *const *argv,
current_uiout->field_string ("inferior_tty_terminal", inferior_tty);
}
-void _initialize_mi_cmd_env ();
-void
-_initialize_mi_cmd_env ()
+INIT_GDB_FILE (mi_cmd_env)
{
const char *env;
diff --git a/gdb/mi/mi-cmd-file.c b/gdb/mi/mi-cmd-file.c
index 2354012..cf7991f 100644
--- a/gdb/mi/mi-cmd-file.c
+++ b/gdb/mi/mi-cmd-file.c
@@ -25,7 +25,6 @@
#include "symtab.h"
#include "source.h"
#include "solib.h"
-#include "solist.h"
/* Return to the client the absolute path and line number of the
current file being executed. */
@@ -163,10 +162,10 @@ mi_cmd_file_list_shared_libraries (const char *command,
for (const solib &so : current_program_space->solibs ())
{
- if (so.so_name.empty ())
+ if (so.name.empty ())
continue;
- if (pattern != nullptr && !re_exec (so.so_name.c_str ()))
+ if (pattern != nullptr && !re_exec (so.name.c_str ()))
continue;
ui_out_emit_tuple tuple_emitter (uiout, NULL);
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index 53cdcc9..abd3fb9 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -369,9 +369,7 @@ mi_cmd_lookup (const char *command)
return it->second.get ();
}
-void _initialize_mi_cmds ();
-void
-_initialize_mi_cmds ()
+INIT_GDB_FILE (mi_cmds)
{
add_builtin_mi_commands ();
}
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index ae1070e..8373e1a 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -34,7 +34,7 @@
#include "mi-common.h"
#include "observable.h"
#include "gdbthread.h"
-#include "solist.h"
+#include "solib.h"
#include "objfiles.h"
#include "tracepoint.h"
#include "cli-out.h"
@@ -726,9 +726,9 @@ mi_output_solib_attribs_1 (ui_out *uiout, const solib &solib,
{
gdbarch *gdbarch = current_inferior ()->arch ();
- uiout->field_string ("id", solib.so_original_name);
- uiout->field_string ("target-name", solib.so_original_name);
- uiout->field_string ("host-name", solib.so_name);
+ uiout->field_string ("id", solib.original_name);
+ uiout->field_string ("target-name", solib.original_name);
+ uiout->field_string ("host-name", solib.name);
if (include_symbols_loaded_p)
uiout->field_signed ("symbols-loaded", solib.symbols_loaded);
if (!gdbarch_has_global_solist (current_inferior ()->arch ()))
@@ -935,9 +935,7 @@ mi_interp_factory (const char *name)
return new mi_interp (name);
}
-void _initialize_mi_interp ();
-void
-_initialize_mi_interp ()
+INIT_GDB_FILE (mi_interp)
{
/* The various interpreter levels. */
interp_factory_register (INTERP_MI2, mi_interp_factory);
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index cda72ca..789e6fa 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -2768,9 +2768,7 @@ mi_parse_thread_group_id (const char *id)
return (int) num;
}
-void _initialize_mi_main ();
-void
-_initialize_mi_main ()
+INIT_GDB_FILE (mi_main)
{
set_show_commands mi_async_cmds
= add_setshow_boolean_cmd ("mi-async", class_run,
diff --git a/gdb/microblaze-linux-tdep.c b/gdb/microblaze-linux-tdep.c
index 8dcbeaa..0fdda18 100644
--- a/gdb/microblaze-linux-tdep.c
+++ b/gdb/microblaze-linux-tdep.c
@@ -35,6 +35,7 @@
#include "frame-unwind.h"
#include "tramp-frame.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
static int
microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
@@ -125,17 +126,14 @@ microblaze_linux_init_abi (struct gdbarch_info info,
microblaze_linux_memory_remove_breakpoint);
/* Shared library handling. */
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
/* Trampolines. */
tramp_frame_prepend_unwinder (gdbarch,
&microblaze_linux_sighandler_tramp_frame);
}
-void _initialize_microblaze_linux_tdep ();
-void
-_initialize_microblaze_linux_tdep ()
+INIT_GDB_FILE (microblaze_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_microblaze, 0, GDB_OSABI_LINUX,
microblaze_linux_init_abi);
diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
index bc728b6..7b58220 100644
--- a/gdb/microblaze-tdep.c
+++ b/gdb/microblaze-tdep.c
@@ -736,9 +736,7 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
return gdbarch;
}
-void _initialize_microblaze_tdep ();
-void
-_initialize_microblaze_tdep ()
+INIT_GDB_FILE (microblaze_tdep)
{
gdbarch_register (bfd_arch_microblaze, microblaze_gdbarch_init);
diff --git a/gdb/mingw-hdep.c b/gdb/mingw-hdep.c
index 84a7b9f..481bd41 100644
--- a/gdb/mingw-hdep.c
+++ b/gdb/mingw-hdep.c
@@ -23,6 +23,8 @@
#include "gdbsupport/gdb_select.h"
#include "inferior.h"
#include "cli/cli-style.h"
+#include "command.h"
+#include "cli/cli-cmds.h"
#include <windows.h>
#include <signal.h>
@@ -445,3 +447,65 @@ install_sigint_handler (c_c_handler_ftype *fn)
current_handler = fn;
return result;
}
+
+/* Set stdout and stderr handles to translation mode MODE. */
+
+static void
+set_console_translation_mode (int mode)
+{
+ setmode (fileno (stdout), mode);
+ setmode (fileno (stderr), mode);
+}
+
+/* Arg in "maint set console-translation-mode <arg>. */
+
+static std::string maint_console_translation_mode;
+
+/* Current value of "maint set/show console-translation-mode". */
+
+static std::string console_translation_mode = "unknown";
+
+/* Sets the console translation mode. */
+
+static void
+set_maint_console_translation_mode (const char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ if (maint_console_translation_mode == "binary")
+ set_console_translation_mode (O_BINARY);
+ else if (maint_console_translation_mode == "text")
+ set_console_translation_mode (O_TEXT);
+ else
+ error (_("Invalid console translation mode: %s"),
+ maint_console_translation_mode.c_str ());
+
+ console_translation_mode = maint_console_translation_mode;
+}
+
+/* Shows the console translation mode. */
+
+static void
+show_maint_console_translation_mode (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c,
+ const char *value)
+{
+ gdb_printf (file, _("Console translation mode is %s.\n"),
+ console_translation_mode.c_str ());
+}
+
+extern void _initialize_mingw_hdep ();
+
+void
+_initialize_mingw_hdep ()
+{
+ add_setshow_string_cmd ("console-translation-mode",
+ class_maintenance,
+ &maint_console_translation_mode, _("\
+Set the translation mode of stdout/stderr."), _("\
+Show the translation mode of stdout/stderr."), _("\
+Use \"binary\", or \"text\""),
+ set_maint_console_translation_mode,
+ show_maint_console_translation_mode,
+ &maintenance_set_cmdlist,
+ &maintenance_show_cmdlist);
+}
diff --git a/gdb/minsyms.c b/gdb/minsyms.c
index 124d96d..4a6459a 100644
--- a/gdb/minsyms.c
+++ b/gdb/minsyms.c
@@ -1479,7 +1479,7 @@ minimal_symbol_reader::install ()
msymbols = m_objfile->per_bfd->msymbols.get ();
/* Arbitrarily require at least 10 elements in a thread. */
- gdb::parallel_for_each (10, &msymbols[0], &msymbols[mcount],
+ gdb::parallel_for_each<10> (&msymbols[0], &msymbols[mcount],
[&] (minimal_symbol *start, minimal_symbol *end)
{
scoped_time_it time_it ("minsyms install worker");
diff --git a/gdb/mips-fbsd-nat.c b/gdb/mips-fbsd-nat.c
index 667a4bc..8d97849 100644
--- a/gdb/mips-fbsd-nat.c
+++ b/gdb/mips-fbsd-nat.c
@@ -125,9 +125,7 @@ mips_fbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
}
}
-void _initialize_mips_fbsd_nat ();
-void
-_initialize_mips_fbsd_nat ()
+INIT_GDB_FILE (mips_fbsd_nat)
{
add_inf_child_target (&the_mips_fbsd_nat_target);
}
diff --git a/gdb/mips-fbsd-tdep.c b/gdb/mips-fbsd-tdep.c
index c280527..c1b5f9c 100644
--- a/gdb/mips-fbsd-tdep.c
+++ b/gdb/mips-fbsd-tdep.c
@@ -476,12 +476,28 @@ mips_fbsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
return fbsd_skip_solib_resolver (gdbarch, pc);
}
-/* FreeBSD/mips uses a slightly different `struct link_map' than the
- other FreeBSD platforms as it includes an additional `l_off'
- member. */
+/* solib_ops for ILP32 FreeBSD/MIPS systems. */
-static struct link_map_offsets *
-mips_fbsd_ilp32_fetch_link_map_offsets (void)
+struct mips_fbsd_ilp32_solib_ops : public svr4_solib_ops
+{
+ /* FreeBSD/MIPS uses a slightly different `struct link_map' than the
+ other FreeBSD platforms as it includes an additional `l_off' member. */
+
+ link_map_offsets *fetch_link_map_offsets () const override;
+};
+
+/* Return a new solib_ops for ILP32 FreeBSD/MIPS systems. */
+
+static solib_ops_up
+make_mips_fbsd_ilp32_solib_ops ()
+{
+ return std::make_unique<mips_fbsd_ilp32_solib_ops> ();
+}
+
+/* See mips_fbsd_ilp32_solib_ops. */
+
+link_map_offsets *
+mips_fbsd_ilp32_solib_ops::fetch_link_map_offsets () const
{
static struct link_map_offsets lmo;
static struct link_map_offsets *lmp = NULL;
@@ -508,8 +524,28 @@ mips_fbsd_ilp32_fetch_link_map_offsets (void)
return lmp;
}
-static struct link_map_offsets *
-mips_fbsd_lp64_fetch_link_map_offsets (void)
+/* solib_ops for LP64 FreeBSD/MIPS systems. */
+
+struct mips_fbsd_lp64_solib_ops : public svr4_solib_ops
+{
+ /* FreeBSD/MIPS uses a slightly different `struct link_map' than the
+ other FreeBSD platforms as it includes an additional `l_off' member. */
+
+ link_map_offsets *fetch_link_map_offsets () const override;
+};
+
+/* Return a new solib_ops for LP64 FreeBSD/MIPS systems. */
+
+static solib_ops_up
+make_mips_fbsd_lp64_solib_ops ()
+{
+ return std::make_unique<mips_fbsd_lp64_solib_ops> ();
+}
+
+/* See mips_fbsd_lp64_solib_ops. */
+
+link_map_offsets *
+mips_fbsd_lp64_solib_ops::fetch_link_map_offsets () const
{
static struct link_map_offsets lmo;
static struct link_map_offsets *lmp = NULL;
@@ -565,15 +601,12 @@ mips_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_skip_solib_resolver (gdbarch, mips_fbsd_skip_solib_resolver);
/* FreeBSD/mips has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32 ?
- mips_fbsd_ilp32_fetch_link_map_offsets :
- mips_fbsd_lp64_fetch_link_map_offsets));
+ set_solib_svr4_ops (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32
+ ? make_mips_fbsd_ilp32_solib_ops
+ : make_mips_fbsd_lp64_solib_ops));
}
-void _initialize_mips_fbsd_tdep ();
-void
-_initialize_mips_fbsd_tdep ()
+INIT_GDB_FILE (mips_fbsd_tdep)
{
gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_FREEBSD,
mips_fbsd_init_abi);
diff --git a/gdb/mips-linux-nat.c b/gdb/mips-linux-nat.c
index b4b5788..e22e904 100644
--- a/gdb/mips-linux-nat.c
+++ b/gdb/mips-linux-nat.c
@@ -784,9 +784,7 @@ mips_linux_nat_target::close ()
linux_nat_trad_target::close ();
}
-void _initialize_mips_linux_nat ();
-void
-_initialize_mips_linux_nat ()
+INIT_GDB_FILE (mips_linux_nat)
{
add_setshow_boolean_cmd ("show-debug-regs", class_maintenance,
&show_debug_regs, _("\
diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c
index 418892b..e4fa243 100644
--- a/gdb/mips-linux-tdep.c
+++ b/gdb/mips-linux-tdep.c
@@ -30,13 +30,13 @@
#include "gdbtypes.h"
#include "objfiles.h"
#include "solib.h"
-#include "solist.h"
#include "symtab.h"
#include "target-descriptions.h"
#include "regset.h"
#include "mips-linux-tdep.h"
#include "glibc-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "xml-syscall.h"
#include "gdbsupport/gdb_signals.h"
#include "inferior.h"
@@ -46,8 +46,6 @@
#include "features/mips64-linux.c"
#include "features/mips64-dsp-linux.c"
-static solib_ops mips_svr4_so_ops;
-
/* This enum represents the signals' numbers on the MIPS
architecture. It just contains the signal definitions which are
different from the generic implementation.
@@ -667,24 +665,57 @@ mips_linux_in_dynsym_stub (CORE_ADDR pc)
return 1;
}
-/* Return non-zero iff PC belongs to the dynamic linker resolution
- code, a PLT entry, or a lazy binding stub. */
+/* Mix-in class to add Linux/MIPS-specific methods to a base solib_ops
+ class. */
-static int
-mips_linux_in_dynsym_resolve_code (CORE_ADDR pc)
+template <typename Base>
+struct mips_linux_svr4_solib_ops : public Base
+{
+ bool in_dynsym_resolve_code (CORE_ADDR pc) const override;
+};
+
+template <typename Base>
+bool
+mips_linux_svr4_solib_ops<Base>::in_dynsym_resolve_code (CORE_ADDR pc) const
{
/* Check whether PC is in the dynamic linker. This also checks
whether it is in the .plt section, used by non-PIC executables. */
- if (svr4_in_dynsym_resolve_code (pc))
- return 1;
+ if (Base::in_dynsym_resolve_code (pc))
+ return true;
/* Likewise for the stubs. They live in the .MIPS.stubs section these
days, so we check if the PC is within, than fall back to a pattern
match. */
if (mips_linux_in_dynsym_stub (pc))
- return 1;
+ return true;
- return 0;
+ return false;
+}
+
+/* solib_ops for ILP32 Linux/MIPS systems. */
+
+using mips_linux_ilp32_svr4_solib_ops
+ = mips_linux_svr4_solib_ops<linux_ilp32_svr4_solib_ops>;
+
+/* Return a new solib_ops for ILP32 Linux/MIPS systems. */
+
+static solib_ops_up
+make_mips_linux_ilp32_svr4_solib_ops ()
+{
+ return std::make_unique<mips_linux_ilp32_svr4_solib_ops> ();
+}
+
+/* solib_ops for LP64 Linux/MIPS systems. */
+
+using mips_linux_lp64_svr4_solib_ops
+ = mips_linux_svr4_solib_ops<linux_lp64_svr4_solib_ops>;
+
+/* Return a new solib_ops for LP64 Linux/MIPS systems. */
+
+static solib_ops_up
+make_mips_linux_lp64_svr4_solib_ops ()
+{
+ return std::make_unique<mips_linux_lp64_svr4_solib_ops> ();
}
/* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c,
@@ -1538,8 +1569,7 @@ mips_linux_init_abi (struct gdbarch_info info,
case MIPS_ABI_O32:
set_gdbarch_get_longjmp_target (gdbarch,
mips_linux_get_longjmp_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_mips_linux_ilp32_svr4_solib_ops);
tramp_frame_prepend_unwinder (gdbarch, &micromips_linux_o32_sigframe);
tramp_frame_prepend_unwinder (gdbarch,
&micromips_linux_o32_rt_sigframe);
@@ -1550,8 +1580,7 @@ mips_linux_init_abi (struct gdbarch_info info,
case MIPS_ABI_N32:
set_gdbarch_get_longjmp_target (gdbarch,
mips_linux_get_longjmp_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_mips_linux_ilp32_svr4_solib_ops);
set_gdbarch_long_double_bit (gdbarch, 128);
set_gdbarch_long_double_format (gdbarch, floatformats_ieee_quad);
tramp_frame_prepend_unwinder (gdbarch,
@@ -1562,8 +1591,7 @@ mips_linux_init_abi (struct gdbarch_info info,
case MIPS_ABI_N64:
set_gdbarch_get_longjmp_target (gdbarch,
mips64_linux_get_longjmp_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_mips_linux_lp64_svr4_solib_ops);
set_gdbarch_long_double_bit (gdbarch, 128);
set_gdbarch_long_double_format (gdbarch, floatformats_ieee_quad);
tramp_frame_prepend_unwinder (gdbarch,
@@ -1583,16 +1611,6 @@ mips_linux_init_abi (struct gdbarch_info info,
set_gdbarch_fetch_tls_load_module_address (gdbarch,
svr4_fetch_objfile_link_map);
- /* Initialize this lazily, to avoid an initialization order
- dependency on solib-svr4.c's _initialize routine. */
- if (mips_svr4_so_ops.in_dynsym_resolve_code == NULL)
- {
- mips_svr4_so_ops = svr4_so_ops;
- mips_svr4_so_ops.in_dynsym_resolve_code
- = mips_linux_in_dynsym_resolve_code;
- }
- set_gdbarch_so_ops (gdbarch, &mips_svr4_so_ops);
-
set_gdbarch_write_pc (gdbarch, mips_linux_write_pc);
set_gdbarch_core_read_description (gdbarch,
@@ -1629,9 +1647,7 @@ mips_linux_init_abi (struct gdbarch_info info,
}
}
-void _initialize_mips_linux_tdep ();
-void
-_initialize_mips_linux_tdep ()
+INIT_GDB_FILE (mips_linux_tdep)
{
const struct bfd_arch_info *arch_info;
diff --git a/gdb/mips-netbsd-nat.c b/gdb/mips-netbsd-nat.c
index 51e3878..91b870b 100644
--- a/gdb/mips-netbsd-nat.c
+++ b/gdb/mips-netbsd-nat.c
@@ -115,9 +115,7 @@ mips_nbsd_nat_target::store_registers (struct regcache *regcache, int regno)
}
}
-void _initialize_mipsnbsd_nat ();
-void
-_initialize_mipsnbsd_nat ()
+INIT_GDB_FILE (mipsnbsd_nat)
{
add_inf_child_target (&the_mips_nbsd_nat_target);
}
diff --git a/gdb/mips-netbsd-tdep.c b/gdb/mips-netbsd-tdep.c
index c9bdaa6..42eb515 100644
--- a/gdb/mips-netbsd-tdep.c
+++ b/gdb/mips-netbsd-tdep.c
@@ -288,13 +288,27 @@ mipsnbsd_cannot_store_register (struct gdbarch *gdbarch, int regno)
|| regno == mips_regnum (gdbarch)->fp_implementation_revision);
}
-/* Shared library support. */
+/* solib_ops for ILP32 NetBSD/MIPS systems. */
-/* NetBSD/mips uses a slightly different `struct link_map' than the
- other NetBSD platforms. */
+struct mips_nbsd_ilp32_svr4_solib_ops : public svr4_solib_ops
+{
+ /* NetBSD/MIPS uses a slightly different `struct link_map' than the
+ other NetBSD platforms. */
+ link_map_offsets *fetch_link_map_offsets () const override;
+};
+
+/* Return a new solib_ops for ILP32 NetBSD/MIPS systems. */
-static struct link_map_offsets *
-mipsnbsd_ilp32_fetch_link_map_offsets (void)
+static solib_ops_up
+make_mips_nbsd_ilp32_svr4_solib_ops ()
+{
+ return std::make_unique<mips_nbsd_ilp32_svr4_solib_ops> ();
+}
+
+/* See mips_nbsd_ilp32_svr4_solib_ops. */
+
+link_map_offsets *
+mips_nbsd_ilp32_svr4_solib_ops::fetch_link_map_offsets () const
{
static struct link_map_offsets lmo;
static struct link_map_offsets *lmp = NULL;
@@ -322,8 +336,27 @@ mipsnbsd_ilp32_fetch_link_map_offsets (void)
return lmp;
}
-static struct link_map_offsets *
-mipsnbsd_lp64_fetch_link_map_offsets (void)
+/* solib_ops for LP64 NetBSD/MIPS systems. */
+
+struct mips_nbsd_lp64_svr4_solib_ops : public svr4_solib_ops
+{
+ /* NetBSD/MIPS uses a slightly different `struct link_map' than the
+ other NetBSD platforms. */
+ link_map_offsets *fetch_link_map_offsets () const override;
+};
+
+/* Return a new solib_ops for LP64 NetBSD/MIPS systems. */
+
+static solib_ops_up
+make_mips_nbsd_lp64_svr4_solib_ops ()
+{
+ return std::make_unique<mips_nbsd_lp64_svr4_solib_ops> ();
+}
+
+/* See mips_nbsd_lp64_svr4_solib_ops. */
+
+link_map_offsets *
+mips_nbsd_lp64_svr4_solib_ops::fetch_link_map_offsets () const
{
static struct link_map_offsets lmo;
static struct link_map_offsets *lmp = NULL;
@@ -369,15 +402,12 @@ mipsnbsd_init_abi (struct gdbarch_info info,
set_gdbarch_software_single_step (gdbarch, mips_software_single_step);
/* NetBSD/mips has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32 ?
- mipsnbsd_ilp32_fetch_link_map_offsets :
- mipsnbsd_lp64_fetch_link_map_offsets));
+ set_solib_svr4_ops (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32
+ ? make_mips_nbsd_ilp32_svr4_solib_ops
+ : make_mips_nbsd_lp64_svr4_solib_ops));
}
-void _initialize_mipsnbsd_tdep ();
-void
-_initialize_mipsnbsd_tdep ()
+INIT_GDB_FILE (mipsnbsd_tdep)
{
gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_NETBSD,
mipsnbsd_init_abi);
diff --git a/gdb/mips-sde-tdep.c b/gdb/mips-sde-tdep.c
index 1f50ef0..5278afb 100644
--- a/gdb/mips-sde-tdep.c
+++ b/gdb/mips-sde-tdep.c
@@ -254,9 +254,7 @@ mips_sde_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
frame_base_append_sniffer (gdbarch, mips_sde_frame_base_sniffer);
}
-void _initialize_mips_sde_tdep ();
-void
-_initialize_mips_sde_tdep ()
+INIT_GDB_FILE (mips_sde_tdep)
{
gdbarch_register_osabi_sniffer (bfd_arch_mips,
bfd_target_elf_flavour,
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index c64cd47..32f832b 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -8972,9 +8972,7 @@ mips_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
mips_fpu_type_str (mips_get_fpu_type (gdbarch)));
}
-void _initialize_mips_tdep ();
-void
-_initialize_mips_tdep ()
+INIT_GDB_FILE (mips_tdep)
{
static struct cmd_list_element *mipsfpulist = NULL;
diff --git a/gdb/mips64-obsd-nat.c b/gdb/mips64-obsd-nat.c
index 26fc1b9..d77c77e 100644
--- a/gdb/mips64-obsd-nat.c
+++ b/gdb/mips64-obsd-nat.c
@@ -114,9 +114,7 @@ mips64_obsd_nat_target::store_registers (struct regcache *regcache, int regnum)
perror_with_name (_("Couldn't write registers"));
}
-void _initialize_mips64obsd_nat ();
-void
-_initialize_mips64obsd_nat ()
+INIT_GDB_FILE (mips64obsd_nat)
{
add_inf_child_target (&the_mips64_obsd_nat_target);
}
diff --git a/gdb/mips64-obsd-tdep.c b/gdb/mips64-obsd-tdep.c
index d0c9a1c..b9a6fe5 100644
--- a/gdb/mips64-obsd-tdep.c
+++ b/gdb/mips64-obsd-tdep.c
@@ -150,13 +150,10 @@ mips64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
obsd_init_abi(info, gdbarch);
/* OpenBSD/mips64 has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
}
-void _initialize_mips64obsd_tdep ();
-void
-_initialize_mips64obsd_tdep ()
+INIT_GDB_FILE (mips64obsd_tdep)
{
gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_OPENBSD,
mips64obsd_init_abi);
diff --git a/gdb/mipsread.c b/gdb/mipsread.c
index 5ffb97f..1d76b8f 100644
--- a/gdb/mipsread.c
+++ b/gdb/mipsread.c
@@ -66,20 +66,16 @@ mipscoff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
{
bfd *abfd = objfile->obfd.get ();
- minimal_symbol_reader reader (objfile);
-
/* Now that the executable file is positioned at symbol table,
process it and define symbols accordingly. */
- if (!((*ecoff_backend (abfd)->debug_swap.read_debug_info)
- (abfd, NULL, &ecoff_data (abfd)->debug_info)))
- error (_("Error reading symbol table: %s"), bfd_errmsg (bfd_get_error ()));
-
- mdebug_build_psymtabs (reader, objfile, &ecoff_backend (abfd)->debug_swap,
- &ecoff_data (abfd)->debug_info);
+ mipsmdebug_build_psymtabs (objfile, &ecoff_backend (abfd)->debug_swap,
+ &ecoff_data (abfd)->debug_info);
/* Add alpha coff dynamic symbols. */
+ minimal_symbol_reader reader (objfile);
+
read_alphacoff_dynamic_symtab (reader, objfile);
/* Install any minimal symbols that have been collected as the current
@@ -374,9 +370,7 @@ static const struct sym_fns ecoff_sym_fns =
NULL, /* sym_probe_fns */
};
-void _initialize_mipsread ();
-void
-_initialize_mipsread ()
+INIT_GDB_FILE (mipsread)
{
add_symtab_fns (bfd_target_ecoff_flavour, &ecoff_sym_fns);
}
diff --git a/gdb/mn10300-linux-tdep.c b/gdb/mn10300-linux-tdep.c
index 3334ca0..6c31241 100644
--- a/gdb/mn10300-linux-tdep.c
+++ b/gdb/mn10300-linux-tdep.c
@@ -29,6 +29,7 @@
#include "trad-frame.h"
#include "tramp-frame.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "gdbarch.h"
/* Transliterated from <asm-mn10300/elf.h>... */
@@ -707,16 +708,13 @@ am33_linux_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_iterate_over_regset_sections
(gdbarch, am33_iterate_over_regset_sections);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
tramp_frame_prepend_unwinder (gdbarch, &am33_linux_sigframe);
tramp_frame_prepend_unwinder (gdbarch, &am33_linux_rt_sigframe);
}
-void _initialize_mn10300_linux_tdep ();
-void
-_initialize_mn10300_linux_tdep ()
+INIT_GDB_FILE (mn10300_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_mn10300, 0,
GDB_OSABI_LINUX, am33_linux_init_osabi);
diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c
index c82a302..fbaeacf 100644
--- a/gdb/mn10300-tdep.c
+++ b/gdb/mn10300-tdep.c
@@ -1413,9 +1413,7 @@ mn10300_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
tdep->am33_mode);
}
-void _initialize_mn10300_tdep ();
-void
-_initialize_mn10300_tdep ()
+INIT_GDB_FILE (mn10300_tdep)
{
gdbarch_register (bfd_arch_mn10300, mn10300_gdbarch_init, mn10300_dump_tdep);
}
diff --git a/gdb/moxie-tdep.c b/gdb/moxie-tdep.c
index ddb9efb..2239406 100644
--- a/gdb/moxie-tdep.c
+++ b/gdb/moxie-tdep.c
@@ -1101,9 +1101,7 @@ moxie_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
/* Register this machine's init routine. */
-void _initialize_moxie_tdep ();
-void
-_initialize_moxie_tdep ()
+INIT_GDB_FILE (moxie_tdep)
{
gdbarch_register (bfd_arch_moxie, moxie_gdbarch_init);
}
diff --git a/gdb/msp430-tdep.c b/gdb/msp430-tdep.c
index 441831e..7ac26b9 100644
--- a/gdb/msp430-tdep.c
+++ b/gdb/msp430-tdep.c
@@ -996,9 +996,7 @@ msp430_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
/* Register the initialization routine. */
-void _initialize_msp430_tdep ();
-void
-_initialize_msp430_tdep ()
+INIT_GDB_FILE (msp430_tdep)
{
gdbarch_register (bfd_arch_msp430, msp430_gdbarch_init);
}
diff --git a/gdb/nat/linux-namespaces.c b/gdb/nat/linux-namespaces.c
index ea94fdd..2a65fb0 100644
--- a/gdb/nat/linux-namespaces.c
+++ b/gdb/nat/linux-namespaces.c
@@ -233,6 +233,12 @@ enum mnsh_msg_type
MNSH_RET_INT. */
MNSH_REQ_SETNS,
+ /* A request that the helper call lstat. The single
+ argument (the filename) should be passed in BUF, and
+ should include a terminating NUL character. The helper
+ should respond with a MNSH_RET_INTSTR. */
+ MNSH_REQ_LSTAT,
+
/* A request that the helper call open. Arguments should
be passed in BUF, INT1 and INT2. The filename (in BUF)
should include a terminating NUL character. The helper
@@ -265,62 +271,69 @@ enum mnsh_msg_type
MNSH_RET_INTSTR,
};
-/* Print a string representation of a message using debug_printf.
- This function is not async-signal-safe so should never be
- called from the helper. */
+/* Return a string representation of a message. This function is not
+ async-signal-safe so should never be called from the helper. */
-static void
+static std::string
mnsh_debug_print_message (enum mnsh_msg_type type,
int fd, int int1, int int2,
const void *buf, int bufsiz)
{
+ std::string res;
+
gdb_byte *c = (gdb_byte *) buf;
gdb_byte *cl = c + bufsiz;
switch (type)
{
case MNSH_MSG_ERROR:
- debug_printf ("ERROR");
+ res += "ERROR";
+ break;
+
+ case MNSH_REQ_LSTAT:
+ res += "LSTAT";
break;
case MNSH_REQ_SETNS:
- debug_printf ("SETNS");
+ res += "SETNS";
break;
case MNSH_REQ_OPEN:
- debug_printf ("OPEN");
+ res += "OPEN";
break;
case MNSH_REQ_UNLINK:
- debug_printf ("UNLINK");
+ res += "UNLINK";
break;
case MNSH_REQ_READLINK:
- debug_printf ("READLINK");
+ res += "READLINK";
break;
case MNSH_RET_INT:
- debug_printf ("INT");
+ res += "INT";
break;
case MNSH_RET_FD:
- debug_printf ("FD");
+ res += "FD";
break;
case MNSH_RET_INTSTR:
- debug_printf ("INTSTR");
+ res += "INTSTR";
break;
default:
- debug_printf ("unknown-packet-%d", type);
+ res += string_printf ("unknown-packet-%d", type);
}
- debug_printf (" %d %d %d \"", fd, int1, int2);
+ res += string_printf (" %d %d %d \"", fd, int1, int2);
for (; c < cl; c++)
- debug_printf (*c >= ' ' && *c <= '~' ? "%c" : "\\%o", *c);
+ res += string_printf (*c >= ' ' && *c <= '~' ? "%c" : "\\%o", *c);
- debug_printf ("\"");
+ res += "\"";
+
+ return res;
}
/* Forward declaration. */
@@ -390,12 +403,10 @@ mnsh_send_message (int sock, enum mnsh_msg_type type,
if (size < 0)
mnsh_maybe_mourn_peer ();
- if (debug_linux_namespaces)
- {
- debug_printf ("mnsh: send: ");
- mnsh_debug_print_message (type, fd, int1, int2, buf, bufsiz);
- debug_printf (" -> %s\n", pulongest (size));
- }
+ linux_namespaces_debug_printf
+ ("send: %s -> %s",
+ mnsh_debug_print_message (type, fd, int1, int2, buf, bufsiz).c_str (),
+ pulongest (size));
return size;
}
@@ -445,9 +456,8 @@ mnsh_recv_message (int sock, enum mnsh_msg_type *type,
size = recvmsg (sock, &msg, MSG_CMSG_CLOEXEC);
if (size < 0)
{
- if (debug_linux_namespaces)
- debug_printf ("namespace-helper: recv failed (%s)\n",
- pulongest (size));
+ linux_namespaces_debug_printf
+ ("namespace-helper: recv failed (%s)", pulongest (size));
mnsh_maybe_mourn_peer ();
@@ -457,9 +467,9 @@ mnsh_recv_message (int sock, enum mnsh_msg_type *type,
/* Check for truncation. */
if (size < fixed_size || (msg.msg_flags & (MSG_TRUNC | MSG_CTRUNC)))
{
- if (debug_linux_namespaces)
- debug_printf ("namespace-helper: recv truncated (%s 0x%x)\n",
- pulongest (size), msg.msg_flags);
+ linux_namespaces_debug_printf
+ ("namespace-helper: recv truncated (%s 0x%x)",
+ pulongest (size), msg.msg_flags);
mnsh_maybe_mourn_peer ();
@@ -477,13 +487,10 @@ mnsh_recv_message (int sock, enum mnsh_msg_type *type,
else
*fd = -1;
- if (debug_linux_namespaces)
- {
- debug_printf ("mnsh: recv: ");
- mnsh_debug_print_message (*type, *fd, *int1, *int2, buf,
- size - fixed_size);
- debug_printf ("\n");
- }
+ linux_namespaces_debug_printf
+ ("recv: %s",
+ mnsh_debug_print_message (*type, *fd, *int1, *int2, buf,
+ size - fixed_size).c_str ());
/* Return the number of bytes of data in BUF. */
return size - fixed_size;
@@ -514,6 +521,20 @@ mnsh_handle_setns (int sock, int fd, int nstype)
return mnsh_return_int (sock, result, errno);
}
+
+/* Handle a MNSH_REQ_LSTAT message. Must be async-signal-safe. */
+
+static ssize_t
+mnsh_handle_lstat (int sock, const char *filename)
+{
+ struct stat sb;
+ int stat_ok = lstat (filename, &sb);
+
+ return mnsh_return_intstr (sock, stat_ok, &sb,
+ stat_ok == -1 ? 0 : sizeof (sb),
+ errno);
+}
+
/* Handle a MNSH_REQ_OPEN message. Must be async-signal-safe. */
static ssize_t
@@ -574,6 +595,11 @@ mnsh_main (int sock)
response = mnsh_handle_setns (sock, fd, int1);
break;
+ case MNSH_REQ_LSTAT:
+ if (size > 0 && buf[size - 1] == '\0')
+ response = mnsh_handle_lstat (sock, buf);
+ break;
+
case MNSH_REQ_OPEN:
if (size > 0 && buf[size - 1] == '\0')
response = mnsh_handle_open (sock, buf, int1, int2);
@@ -673,7 +699,7 @@ linux_mntns_get_helper (void)
mnsh_creator_pid = helper_creator;
/* Debug printing isn't async-signal-safe. */
- debug_linux_namespaces = 0;
+ debug_linux_namespaces = false;
mnsh_main (sv[1]);
}
@@ -685,9 +711,8 @@ linux_mntns_get_helper (void)
helper->sock = sv[0];
helper->nsid = ns->id;
- if (debug_linux_namespaces)
- debug_printf ("Started mount namespace helper process %d\n",
- helper->pid);
+ linux_namespaces_debug_printf
+ ("Started mount namespace helper process %d", helper->pid);
}
return helper;
@@ -765,6 +790,10 @@ mnsh_maybe_mourn_peer (void)
mnsh_send_message (helper->sock, MNSH_REQ_OPEN, -1, flags, mode, \
filename, strlen (filename) + 1)
+#define mnsh_send_lstat(helper, filename) \
+ mnsh_send_message (helper->sock, MNSH_REQ_LSTAT, -1, 0, 0, \
+ filename, strlen (filename) + 1)
+
#define mnsh_send_unlink(helper, filename) \
mnsh_send_message (helper->sock, MNSH_REQ_UNLINK, -1, 0, 0, \
filename, strlen (filename) + 1)
@@ -884,7 +913,7 @@ linux_mntns_access_fs (pid_t pid)
struct stat sb;
struct linux_mnsh *helper;
ssize_t size;
- int fd;
+ int fd, fd_user = -1;
if (pid == getpid ())
return MNSH_FS_DIRECT;
@@ -901,6 +930,8 @@ linux_mntns_access_fs (pid_t pid)
{
int save_errno = errno;
close (fd);
+ if (fd_user >= 0)
+ close (fd_user);
errno = save_errno;
};
@@ -910,6 +941,13 @@ linux_mntns_access_fs (pid_t pid)
if (sb.st_ino == ns->id)
return MNSH_FS_DIRECT;
+ struct linux_ns *ns_user = linux_ns_get_namespace (LINUX_NS_USER);
+ if (ns_user != nullptr)
+ {
+ const char *ns_filename = linux_ns_filename (ns_user, pid);
+ fd_user = gdb_open_cloexec (ns_filename, O_RDONLY, 0).release ();
+ }
+
helper = linux_mntns_get_helper ();
if (helper == NULL)
return MNSH_FS_ERROR;
@@ -918,6 +956,19 @@ linux_mntns_access_fs (pid_t pid)
{
int result, error;
+ /* Try to enter the user namespace first. The current user might
+ have elevated privileges within the user namespace, which would
+ then allow the attempt to enter the mount namespace to succeed. */
+ if (fd_user >= 0)
+ {
+ size = mnsh_send_setns (helper, fd_user, 0);
+ if (size < 0)
+ return MNSH_FS_ERROR;
+
+ if (mnsh_recv_int (helper, &result, &error) != 0)
+ return MNSH_FS_ERROR;
+ }
+
size = mnsh_send_setns (helper, fd, 0);
if (size < 0)
return MNSH_FS_ERROR;
@@ -948,6 +999,42 @@ linux_mntns_access_fs (pid_t pid)
/* See nat/linux-namespaces.h. */
int
+linux_mntns_lstat (pid_t pid, const char *filename,
+ struct stat *sb)
+{
+ enum mnsh_fs_code access = linux_mntns_access_fs (pid);
+
+ if (access == MNSH_FS_ERROR)
+ return -1;
+
+ if (access == MNSH_FS_DIRECT)
+ return lstat (filename, sb);
+
+ gdb_assert (access == MNSH_FS_HELPER);
+
+ struct linux_mnsh *helper = linux_mntns_get_helper ();
+
+ ssize_t size = mnsh_send_lstat (helper, filename);
+ if (size < 0)
+ return -1;
+
+ int stat_ok, error;
+ size = mnsh_recv_intstr (helper, &stat_ok, &error, sb, sizeof (*sb));
+
+ if (size < 0)
+ {
+ stat_ok = -1;
+ errno = error;
+ }
+ else
+ gdb_assert (stat_ok == -1 || size == sizeof (*sb));
+
+ return stat_ok;
+}
+
+/* See nat/linux-namespaces.h. */
+
+int
linux_mntns_open_cloexec (pid_t pid, const char *filename,
int flags, mode_t mode)
{
diff --git a/gdb/nat/linux-namespaces.h b/gdb/nat/linux-namespaces.h
index a548d83..a9a99f1 100644
--- a/gdb/nat/linux-namespaces.h
+++ b/gdb/nat/linux-namespaces.h
@@ -24,6 +24,12 @@
extern bool debug_linux_namespaces;
+/* Print a "linux-namespaces" debug statement. */
+
+#define linux_namespaces_debug_printf(fmt, ...) \
+ debug_prefixed_printf_cond (debug_linux_namespaces, "linux-namespaces", \
+ fmt, ##__VA_ARGS__)
+
/* Enumeration of Linux namespace types. */
enum linux_ns_type
@@ -58,6 +64,11 @@ enum linux_ns_type
extern int linux_ns_same (pid_t pid, enum linux_ns_type type);
+/* Like lstat(2), but in the mount namespace of process PID. */
+
+extern int linux_mntns_lstat (pid_t pid, const char *filename,
+ struct stat *sb);
+
/* Like gdb_open_cloexec, but in the mount namespace of process
PID. */
diff --git a/gdb/nat/linux-procfs.c b/gdb/nat/linux-procfs.c
index a72df2a..d4f9af3 100644
--- a/gdb/nat/linux-procfs.c
+++ b/gdb/nat/linux-procfs.c
@@ -424,7 +424,7 @@ linux_proc_task_list_dir_exists (pid_t pid)
/* See linux-procfs.h. */
const char *
-linux_proc_pid_to_exec_file (int pid)
+linux_proc_pid_to_exec_file (int pid, bool is_local_fs)
{
static char buf[PATH_MAX];
char name[PATH_MAX];
@@ -437,9 +437,31 @@ linux_proc_pid_to_exec_file (int pid)
else
buf[len] = '\0';
- /* Use /proc/PID/exe if the actual file can't be read, but /proc/PID/exe
- can be. */
- if (access (buf, R_OK) != 0 && access (name, R_OK) == 0)
+ /* If the inferior and GDB can see the same filesystem, and NAME
+ cannot be read, maybe the file has been deleted, then we can
+ potentially use /proc/PID/exe instead.
+
+ GDB always interprets the results of this function within the
+ current sysroot (which is 'target:' by default). This means
+ that, if we return /proc/PID/exe, GDB will try to find this file
+ within the sysroot.
+
+ This doesn't make sense if GDB is using a sysroot like:
+ '/some/random/directory/', not only is it possible that NAME
+ could be found within the sysroot, it is unlikely that
+ /proc/PID/exe will exist within the sysroot.
+
+ Similarly, if the sysroot is 'target:', but the inferior is
+ running within a separate MNT namespace, then it is more than
+ likely that the inferior will also be running in a separate PID
+ namespace, in this case PID is the pid on the host system,
+ /proc/PID/exe will not be correct within the inferiors MNT/PID
+ namespace.
+
+ So, we can fallback to use /proc/PID/exe only if IS_LOCAL_FS is
+ true, this indicates that GDB and the inferior are using the same
+ MNT namespace, and GDB's sysroot is either empty, or 'target:'. */
+ if (is_local_fs && access (buf, R_OK) != 0 && access (name, R_OK) == 0)
strcpy (buf, name);
return buf;
diff --git a/gdb/nat/linux-procfs.h b/gdb/nat/linux-procfs.h
index 0c80622..4b02d31 100644
--- a/gdb/nat/linux-procfs.h
+++ b/gdb/nat/linux-procfs.h
@@ -87,9 +87,19 @@ extern int linux_proc_task_list_dir_exists (pid_t pid);
/* Return the full absolute name of the executable file that was run
to create the process PID. The returned value persists until this
- function is next called. */
+ function is next called.
-extern const char *linux_proc_pid_to_exec_file (int pid);
+ LOCAL_FS should be true if the file returned from the function will
+ be searched for in the same filesystem as GDB itself is running.
+ In practice, this means LOCAL_FS should be true if PID and GDB are
+ running in the same MNT namespace and GDB's sysroot is either the
+ empty string, or is 'target:'.
+
+ When used from gdbserver, where there is no sysroot, the only check
+ that matters is that PID and gdbserver are running in the same MNT
+ namespace. */
+
+extern const char *linux_proc_pid_to_exec_file (int pid, bool local_fs);
/* Display possible problems on this system. Display them only once
per GDB execution. */
diff --git a/gdb/nat/linux-ptrace.c b/gdb/nat/linux-ptrace.c
index 0510b39..f73058b 100644
--- a/gdb/nat/linux-ptrace.c
+++ b/gdb/nat/linux-ptrace.c
@@ -23,6 +23,7 @@
#include <sys/procfs.h>
#endif
#include "gdbsupport/eintr.h"
+#include "gdbsupport/signals-state-save-restore.h"
/* Stores the ptrace options supported by the running kernel.
A value of -1 means we did not check for features yet. A value
@@ -148,6 +149,9 @@ linux_ptrace_test_ret_to_nx (void)
return;
case 0:
+ /* Set signal handlers to their default because it doesn't make sense
+ to call GDB-specific handlers any more in the child process. */
+ restore_original_signals_state ();
l = ptrace (PTRACE_TRACEME, 0, (PTRACE_TYPE_ARG3) NULL,
(PTRACE_TYPE_ARG4) NULL);
if (l != 0)
diff --git a/gdb/nds32-tdep.c b/gdb/nds32-tdep.c
index 7d826fc..9180cd0 100644
--- a/gdb/nds32-tdep.c
+++ b/gdb/nds32-tdep.c
@@ -2086,9 +2086,7 @@ nds32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
return gdbarch;
}
-void _initialize_nds32_tdep ();
-void
-_initialize_nds32_tdep ()
+INIT_GDB_FILE (nds32_tdep)
{
/* Initialize gdbarch. */
gdbarch_register (bfd_arch_nds32, nds32_gdbarch_init);
diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c
index 5341b05..6bba8d3 100644
--- a/gdb/objc-lang.c
+++ b/gdb/objc-lang.c
@@ -1327,9 +1327,7 @@ find_objc_msgcall (CORE_ADDR pc, CORE_ADDR *new_pc)
return 0;
}
-void _initialize_objc_language ();
-void
-_initialize_objc_language ()
+INIT_GDB_FILE (objc_language)
{
add_info ("selectors", info_selectors_command,
_("All Objective-C selectors, or those matching REGEXP."));
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index 3c5a554..d25d1a0 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -673,18 +673,18 @@ objfile_rebase (struct objfile *objfile, CORE_ADDR slide)
/* See objfiles.h. */
bool
-objfile_has_full_symbols (objfile *objfile)
+objfile::has_full_symbols ()
{
- return objfile->compunit_symtabs != nullptr;
+ return this->compunit_symtabs != nullptr;
}
/* See objfiles.h. */
bool
-objfile_has_symbols (objfile *objfile)
+objfile::has_symbols ()
{
- for (::objfile *o : objfile->separate_debug_objfiles ())
- if (o->has_partial_symbols () || objfile_has_full_symbols (o))
+ for (::objfile *o : this->separate_debug_objfiles ())
+ if (o->has_partial_symbols () || o->has_full_symbols ())
return true;
return false;
@@ -708,7 +708,7 @@ bool
have_full_symbols (program_space *pspace)
{
for (objfile *ofp : pspace->objfiles ())
- if (objfile_has_full_symbols (ofp))
+ if (ofp->has_full_symbols ())
return true;
return false;
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index bb2f05d..4a34758 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -515,10 +515,16 @@ public:
return per_bfd->gdbarch;
}
- /* Return true if OBJFILE has partial symbols. */
-
+ /* Return true if this objfile has partial symbols. */
bool has_partial_symbols ();
+ /* Return true if this objfile has full symbols. */
+ bool has_full_symbols ();
+
+ /* Return true if this objfile has full or partial symbols, either directly
+ or through a separate debug file. */
+ bool has_symbols ();
+
/* Look for a separate debug symbol file for this objfile, make use of
build-id, debug-link, and debuginfod as necessary. If a suitable
separate debug symbol file is found then it is loaded using a call to
@@ -938,15 +944,6 @@ extern void free_objfile_separate_debug (struct objfile *);
extern void objfile_relocate (struct objfile *, const section_offsets &);
extern void objfile_rebase (struct objfile *, CORE_ADDR);
-/* Return true if OBJFILE has full symbols. */
-
-extern bool objfile_has_full_symbols (objfile *objfile);
-
-/* Return true if OBJFILE has full or partial symbols, either directly
- or through a separate debug file. */
-
-extern bool objfile_has_symbols (objfile *objfile);
-
/* Return true if any objfile of PSPACE has partial symbols. */
extern bool have_partial_symbols (program_space *pspace);
@@ -992,10 +989,10 @@ extern struct obj_section *find_pc_section (CORE_ADDR pc);
/* Return true if PC is in a section called NAME. */
extern bool pc_in_section (CORE_ADDR, const char *);
-/* Return non-zero if PC is in a SVR4-style procedure linkage table
+/* Return true if PC is in a SVR4-style procedure linkage table
section. */
-static inline int
+static inline bool
in_plt_section (CORE_ADDR pc)
{
return (pc_in_section (pc, ".plt")
diff --git a/gdb/observable.c b/gdb/observable.c
index 734a5f6..1233a19 100644
--- a/gdb/observable.c
+++ b/gdb/observable.c
@@ -87,9 +87,7 @@ show_observer_debug (struct ui_file *file, int from_tty,
gdb_printf (file, _("Observer debugging is %s.\n"), value);
}
-void _initialize_observer ();
-void
-_initialize_observer ()
+INIT_GDB_FILE (observer)
{
add_setshow_boolean_cmd ("observer", class_maintenance,
&gdb::observers::observer_debug, _("\
diff --git a/gdb/or1k-linux-nat.c b/gdb/or1k-linux-nat.c
index 3a80dc9..cc682ea 100644
--- a/gdb/or1k-linux-nat.c
+++ b/gdb/or1k-linux-nat.c
@@ -199,9 +199,7 @@ or1k_linux_nat_target::store_registers (struct regcache *regcache, int regnum)
/* Initialize OpenRISC Linux native support. */
-void _initialize_or1k_linux_nat ();
-void
-_initialize_or1k_linux_nat ()
+INIT_GDB_FILE (or1k_linux_nat)
{
/* Register the target. */
linux_target = &the_or1k_linux_nat_target;
diff --git a/gdb/or1k-linux-tdep.c b/gdb/or1k-linux-tdep.c
index 4784e0b..afefefe 100644
--- a/gdb/or1k-linux-tdep.c
+++ b/gdb/or1k-linux-tdep.c
@@ -20,6 +20,7 @@
#include "osabi.h"
#include "glibc-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "solib-svr4.h"
#include "regset.h"
#include "tramp-frame.h"
@@ -144,8 +145,7 @@ or1k_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
linux_init_abi (info, gdbarch, 0);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
/* GNU/Linux uses SVR4-style shared libraries. */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
@@ -167,9 +167,7 @@ or1k_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* Initialize OpenRISC Linux target support. */
-void _initialize_or1k_linux_tdep ();
-void
-_initialize_or1k_linux_tdep ()
+INIT_GDB_FILE (or1k_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_or1k, 0, GDB_OSABI_LINUX,
or1k_linux_init_abi);
diff --git a/gdb/or1k-tdep.c b/gdb/or1k-tdep.c
index 8e76419..2774840 100644
--- a/gdb/or1k-tdep.c
+++ b/gdb/or1k-tdep.c
@@ -1286,9 +1286,7 @@ or1k_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
}
-void _initialize_or1k_tdep ();
-void
-_initialize_or1k_tdep ()
+INIT_GDB_FILE (or1k_tdep)
{
/* Register this architecture. */
gdbarch_register (bfd_arch_or1k, or1k_gdbarch_init, or1k_dump_tdep);
diff --git a/gdb/osabi.c b/gdb/osabi.c
index ae14f74..1459368 100644
--- a/gdb/osabi.c
+++ b/gdb/osabi.c
@@ -609,9 +609,7 @@ show_osabi (struct ui_file *file, int from_tty, struct cmd_list_element *c,
gdbarch_osabi_name (GDB_OSABI_DEFAULT));
}
-void _initialize_gdb_osabi ();
-void
-_initialize_gdb_osabi ()
+INIT_GDB_FILE (gdb_osabi)
{
/* Register a generic sniffer for ELF flavoured files. */
gdbarch_register_osabi_sniffer (bfd_arch_unknown,
diff --git a/gdb/osdata.c b/gdb/osdata.c
index 5cc584d..788dd2a 100644
--- a/gdb/osdata.c
+++ b/gdb/osdata.c
@@ -287,9 +287,7 @@ info_osdata_command (const char *arg, int from_tty)
info_osdata (arg);
}
-void _initialize_osdata ();
-void
-_initialize_osdata ()
+INIT_GDB_FILE (osdata)
{
add_info ("os", info_osdata_command,
_("Show OS data ARG."));
diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c
index 5dcdbcd..8228ca0 100644
--- a/gdb/p-valprint.c
+++ b/gdb/p-valprint.c
@@ -860,9 +860,7 @@ pascal_object_print_static_field (struct value *val,
common_val_print (val, stream, recurse, &opts, current_language);
}
-void _initialize_pascal_valprint ();
-void
-_initialize_pascal_valprint ()
+INIT_GDB_FILE (pascal_valprint)
{
add_setshow_boolean_cmd ("pascal_static-members", class_support,
&user_print_options.pascal_static_field_print, _("\
diff --git a/gdb/pager.h b/gdb/pager.h
index 052337d..b5425d4 100644
--- a/gdb/pager.h
+++ b/gdb/pager.h
@@ -68,6 +68,16 @@ private:
/* Flush the wrap buffer to STREAM, if necessary. */
void flush_wrap_buffer ();
+ /* Set the style of m_stream to STYLE. */
+ void set_stream_style (const ui_file_style &style)
+ {
+ if (m_stream->can_emit_style_escape () && m_stream_style != style)
+ {
+ m_stream->puts (style.to_ansi ().c_str ());
+ m_stream_style = style;
+ }
+ }
+
/* Contains characters which are waiting to be output (they have
already been counted in chars_printed). */
std::string m_wrap_buffer;
@@ -82,6 +92,12 @@ private:
/* The style applied at the time that wrap_here was called. */
ui_file_style m_wrap_style;
+ /* The style currently applied to m_stream. While m_applied_style is the
+ style that is applied to new content added to m_wrap_buffer, the
+ m_stream_style reflects changes that have been flushed to the managed
+ stream. */
+ ui_file_style m_stream_style;
+
/* This is temporarily set when paging. This will cause some
methods to change their behavior to ignore the wrap buffer. */
bool m_paging = false;
diff --git a/gdb/parse.c b/gdb/parse.c
index 64653c8..6ad4e71 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -617,9 +617,7 @@ parser_fprintf (FILE *x, const char *y, ...)
va_end (args);
}
-void _initialize_parse ();
-void
-_initialize_parse ()
+INIT_GDB_FILE (parse)
{
add_setshow_zuinteger_cmd ("expression", class_maintenance,
&expressiondebug,
diff --git a/gdb/ppc-fbsd-nat.c b/gdb/ppc-fbsd-nat.c
index e8853cf..e59791d 100644
--- a/gdb/ppc-fbsd-nat.c
+++ b/gdb/ppc-fbsd-nat.c
@@ -200,9 +200,7 @@ ppcfbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
return 1;
}
-void _initialize_ppcfbsd_nat ();
-void
-_initialize_ppcfbsd_nat ()
+INIT_GDB_FILE (ppcfbsd_nat)
{
add_inf_child_target (&the_ppc_fbsd_nat_target);
diff --git a/gdb/ppc-fbsd-tdep.c b/gdb/ppc-fbsd-tdep.c
index 3bab031..a666509 100644
--- a/gdb/ppc-fbsd-tdep.c
+++ b/gdb/ppc-fbsd-tdep.c
@@ -332,8 +332,7 @@ ppcfbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_return_value (gdbarch, ppcfbsd_return_value);
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
frame_unwind_append_unwinder (gdbarch, &ppcfbsd_sigtramp_frame_unwind);
set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpc");
@@ -347,8 +346,7 @@ ppcfbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
ppc64_elf_make_msymbol_special);
set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpc");
}
@@ -361,9 +359,7 @@ ppcfbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
ppcfbsd_get_thread_local_address);
}
-void _initialize_ppcfbsd_tdep ();
-void
-_initialize_ppcfbsd_tdep ()
+INIT_GDB_FILE (ppcfbsd_tdep)
{
gdbarch_register_osabi (bfd_arch_powerpc, bfd_mach_ppc, GDB_OSABI_FREEBSD,
ppcfbsd_init_abi);
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
index 0397ccb..568202a 100644
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -3232,9 +3232,7 @@ ppc_linux_nat_target::get_arch_lwp_info (struct lwp_info *lp)
return lwp_arch_private_info (lp);
}
-void _initialize_ppc_linux_nat ();
-void
-_initialize_ppc_linux_nat ()
+INIT_GDB_FILE (ppc_linux_nat)
{
linux_target = &the_ppc_linux_nat_target;
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index 441f317..5067b89 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -32,7 +32,6 @@
#include "regset.h"
#include "solib-svr4.h"
#include "solib.h"
-#include "solist.h"
#include "ppc-tdep.h"
#include "ppc64-tdep.h"
#include "ppc-linux-tdep.h"
@@ -49,6 +48,7 @@
#include "arch-utils.h"
#include "xml-syscall.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "svr4-tls-tdep.h"
#include "linux-record.h"
#include "record-full.h"
@@ -87,8 +87,6 @@
#include "features/rs6000/powerpc-e500l.c"
#include "dwarf2/frame.h"
-/* Shared library operations for PowerPC-Linux. */
-static solib_ops powerpc_so_ops;
/* The syscall's XML filename for PPC and PPC64. */
#define XML_SYSCALL_FILENAME_PPC "syscalls/ppc-linux.xml"
@@ -307,26 +305,43 @@ static const struct ppc_insn_pattern powerpc32_plt_stub_so_2[] =
/* The max number of insns we check using ppc_insns_match_pattern. */
#define POWERPC32_PLT_CHECK_LEN (ARRAY_SIZE (powerpc32_plt_stub) - 1)
-/* Check if PC is in PLT stub. For non-secure PLT, stub is in .plt
- section. For secure PLT, stub is in .text and we need to check
- instruction patterns. */
+/* solib_ops for ILP32 PowerPC/Linux systems. */
-static int
-powerpc_linux_in_dynsym_resolve_code (CORE_ADDR pc)
+struct ppc_linux_ilp32_svr4_solib_ops : public linux_ilp32_svr4_solib_ops
+{
+ /* Check if PC is in PLT stub. For non-secure PLT, stub is in .plt
+ section. For secure PLT, stub is in .text and we need to check
+ instruction patterns. */
+
+ bool in_dynsym_resolve_code (CORE_ADDR pc) const override;
+};
+
+/* Return a new solib_ops for ILP32 PowerPC/Linux systems. */
+
+static solib_ops_up
+make_ppc_linux_ilp32_svr4_solib_ops ()
+{
+ return std::make_unique<ppc_linux_ilp32_svr4_solib_ops> ();
+}
+
+/* See ppc_linux_ilp32_svr4_solib_ops. */
+
+bool
+ppc_linux_ilp32_svr4_solib_ops::in_dynsym_resolve_code (CORE_ADDR pc) const
{
/* Check whether PC is in the dynamic linker. This also checks
whether it is in the .plt section, used by non-PIC executables. */
- if (svr4_in_dynsym_resolve_code (pc))
- return 1;
+ if (linux_ilp32_svr4_solib_ops::in_dynsym_resolve_code (pc))
+ return true;
/* Check if we are in the resolver. */
bound_minimal_symbol sym = lookup_minimal_symbol_by_pc (pc);
- if (sym.minsym != NULL
- && (strcmp (sym.minsym->linkage_name (), "__glink") == 0
- || strcmp (sym.minsym->linkage_name (), "__glink_PLTresolve") == 0))
- return 1;
- return 0;
+ if (sym.minsym == nullptr)
+ return false;
+
+ return (strcmp (sym.minsym->linkage_name (), "__glink") == 0
+ || strcmp (sym.minsym->linkage_name (), "__glink_PLTresolve") == 0);
}
/* Follow PLT stub to actual routine.
@@ -2266,8 +2281,6 @@ ppc_linux_init_abi (struct gdbarch_info info,
/* Shared library handling. */
set_gdbarch_skip_trampoline_code (gdbarch, ppc_skip_trampoline_code);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
/* Setting the correct XML syscall filename. */
set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_PPC);
@@ -2284,14 +2297,7 @@ ppc_linux_init_abi (struct gdbarch_info info,
else
set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpc");
- if (powerpc_so_ops.in_dynsym_resolve_code == NULL)
- {
- powerpc_so_ops = svr4_so_ops;
- /* Override dynamic resolve function. */
- powerpc_so_ops.in_dynsym_resolve_code =
- powerpc_linux_in_dynsym_resolve_code;
- }
- set_gdbarch_so_ops (gdbarch, &powerpc_so_ops);
+ set_solib_svr4_ops (gdbarch, make_ppc_linux_ilp32_svr4_solib_ops);
set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
}
@@ -2318,8 +2324,7 @@ ppc_linux_init_abi (struct gdbarch_info info,
/* Shared library handling. */
set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_lp64_svr4_solib_ops);
/* Setting the correct XML syscall filename. */
set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_PPC64);
@@ -2393,9 +2398,7 @@ ppc_linux_init_abi (struct gdbarch_info info,
}
-void _initialize_ppc_linux_tdep ();
-void
-_initialize_ppc_linux_tdep ()
+INIT_GDB_FILE (ppc_linux_tdep)
{
/* Register for all sub-families of the POWER/PowerPC: 32-bit and
64-bit PowerPC, and the older rs6k. */
diff --git a/gdb/ppc-netbsd-nat.c b/gdb/ppc-netbsd-nat.c
index a8e65bb..dfb855a 100644
--- a/gdb/ppc-netbsd-nat.c
+++ b/gdb/ppc-netbsd-nat.c
@@ -183,9 +183,7 @@ ppcnbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
return 1;
}
-void _initialize_ppcnbsd_nat ();
-void
-_initialize_ppcnbsd_nat ()
+INIT_GDB_FILE (ppcnbsd_nat)
{
/* Support debugging kernel virtual memory images. */
bsd_kvm_add_target (ppcnbsd_supply_pcb);
diff --git a/gdb/ppc-netbsd-tdep.c b/gdb/ppc-netbsd-tdep.c
index 911c012..9913592 100644
--- a/gdb/ppc-netbsd-tdep.c
+++ b/gdb/ppc-netbsd-tdep.c
@@ -179,8 +179,7 @@ ppcnbsd_init_abi (struct gdbarch_info info,
set_gdbarch_return_value (gdbarch, ppcnbsd_return_value);
/* NetBSD uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
set_gdbarch_iterate_over_regset_sections
(gdbarch, ppcnbsd_iterate_over_regset_sections);
@@ -189,9 +188,7 @@ ppcnbsd_init_abi (struct gdbarch_info info,
tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd2_sigtramp);
}
-void _initialize_ppcnbsd_tdep ();
-void
-_initialize_ppcnbsd_tdep ()
+INIT_GDB_FILE (ppcnbsd_tdep)
{
gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_NETBSD,
ppcnbsd_init_abi);
diff --git a/gdb/ppc-obsd-nat.c b/gdb/ppc-obsd-nat.c
index 1431aa6..48df9d7 100644
--- a/gdb/ppc-obsd-nat.c
+++ b/gdb/ppc-obsd-nat.c
@@ -186,9 +186,7 @@ ppcobsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
return 1;
}
-void _initialize_ppcobsd_nat ();
-void
-_initialize_ppcobsd_nat ()
+INIT_GDB_FILE (ppcobsd_nat)
{
add_inf_child_target (&the_ppc_obsd_nat_target);
diff --git a/gdb/ppc-obsd-tdep.c b/gdb/ppc-obsd-tdep.c
index 5e271c1..18f4d79 100644
--- a/gdb/ppc-obsd-tdep.c
+++ b/gdb/ppc-obsd-tdep.c
@@ -254,8 +254,7 @@ ppcobsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_return_value (gdbarch, ppc_sysv_abi_broken_return_value);
/* OpenBSD uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
set_gdbarch_iterate_over_regset_sections
(gdbarch, ppcobsd_iterate_over_regset_sections);
@@ -263,9 +262,7 @@ ppcobsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
frame_unwind_append_unwinder (gdbarch, &ppcobsd_sigtramp_frame_unwind);
}
-void _initialize_ppcobsd_tdep ();
-void
-_initialize_ppcobsd_tdep ()
+INIT_GDB_FILE (ppcobsd_tdep)
{
gdbarch_register_osabi (bfd_arch_rs6000, 0, GDB_OSABI_OPENBSD,
ppcobsd_init_abi);
diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c
index bcf4e2a..cae5aa6 100644
--- a/gdb/ppc-sysv-tdep.c
+++ b/gdb/ppc-sysv-tdep.c
@@ -2112,6 +2112,7 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct value *function,
/* In the ELFv2 ABI, aggregate types of up to 16 bytes are
returned in registers r3:r4. */
if (tdep->elf_abi == POWERPC_ELF_V2
+ && !TYPE_HAS_DYNAMIC_LENGTH (valtype)
&& valtype->length () <= 16
&& (valtype->code () == TYPE_CODE_STRUCT
|| valtype->code () == TYPE_CODE_UNION
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 6659c5a..19fbc20 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -2394,7 +2394,7 @@ printf_c_string (struct ui_file *stream, const char *format,
}
else
{
- CORE_ADDR tem = value_as_address (value);;
+ CORE_ADDR tem = value_as_address (value);
if (tem == 0)
{
@@ -3183,9 +3183,7 @@ memory_tag_check_command (const char *args, int from_tty)
}
}
-void _initialize_printcmd ();
-void
-_initialize_printcmd ()
+INIT_GDB_FILE (printcmd)
{
struct cmd_list_element *c;
diff --git a/gdb/probe.c b/gdb/probe.c
index e6788ff..6679f39 100644
--- a/gdb/probe.c
+++ b/gdb/probe.c
@@ -973,9 +973,7 @@ static const struct internalvar_funcs probe_funcs =
std::vector<const static_probe_ops *> all_static_probe_ops;
-void _initialize_probe ();
-void
-_initialize_probe ()
+INIT_GDB_FILE (probe)
{
all_static_probe_ops.push_back (&any_static_probe_ops);
diff --git a/gdb/proc-api.c b/gdb/proc-api.c
index 7a45ba9..f3d4e14 100644
--- a/gdb/proc-api.c
+++ b/gdb/proc-api.c
@@ -413,9 +413,7 @@ proc_prettyfprint_status (long flags, int why, int what, int thread)
}
}
-void _initialize_proc_api ();
-void
-_initialize_proc_api ()
+INIT_GDB_FILE (proc_api)
{
add_setshow_boolean_cmd ("procfs-trace", no_class, &procfs_trace, _("\
Set tracing for /proc api calls."), _("\
diff --git a/gdb/proc-events.c b/gdb/proc-events.c
index 23af639..c6ed1f4 100644
--- a/gdb/proc-events.c
+++ b/gdb/proc-events.c
@@ -759,9 +759,7 @@ proc_prettyprint_actionset (struct sigaction *actions, int verbose)
{
}
-void _initialize_proc_events ();
-void
-_initialize_proc_events ()
+INIT_GDB_FILE (proc_events)
{
init_syscall_table ();
}
diff --git a/gdb/proc-service.c b/gdb/proc-service.c
index af92335..4f2be0f 100644
--- a/gdb/proc-service.c
+++ b/gdb/proc-service.c
@@ -206,9 +206,7 @@ ps_getpid (struct ps_prochandle *ph)
return ph->thread->ptid.pid ();
}
-void _initialize_proc_service ();
-void
-_initialize_proc_service ()
+INIT_GDB_FILE (proc_service)
{
/* This function solely exists to make sure this module is linked
into the final binary. */
diff --git a/gdb/procfs.c b/gdb/procfs.c
index 76a6168..a10574a 100644
--- a/gdb/procfs.c
+++ b/gdb/procfs.c
@@ -3447,9 +3447,7 @@ proc_untrace_sysexit_cmd (const char *args, int from_tty)
proc_trace_syscalls (args, from_tty, PR_SYSEXIT, FLAG_RESET);
}
-void _initialize_procfs ();
-void
-_initialize_procfs ()
+INIT_GDB_FILE (procfs)
{
add_com ("proc-trace-entry", no_class, proc_trace_sysentry_cmd,
_("Give a trace of entries into the syscall."));
@@ -3550,21 +3548,17 @@ procfs_corefile_thread_callback (procinfo *pi, procinfo *thread, void *data)
return 0;
}
-static int
-find_signalled_thread (struct thread_info *info, void *data)
+static bool
+find_signalled_thread (struct thread_info *info)
{
- if (info->stop_signal () != GDB_SIGNAL_0
- && info->ptid.pid () == inferior_ptid.pid ())
- return 1;
-
- return 0;
+ return (info->stop_signal () != GDB_SIGNAL_0
+ && info->ptid.pid () == inferior_ptid.pid ());
}
static enum gdb_signal
find_stop_signal (void)
{
- struct thread_info *info =
- iterate_over_threads (find_signalled_thread, NULL);
+ struct thread_info *info = iterate_over_threads (find_signalled_thread);
if (info)
return info->stop_signal ();
diff --git a/gdb/producer.c b/gdb/producer.c
index d8cbded..5d754fa 100644
--- a/gdb/producer.c
+++ b/gdb/producer.c
@@ -335,9 +335,7 @@ Version 18.0 Beta";
}
#endif
-void _initialize_producer ();
-void
-_initialize_producer ()
+INIT_GDB_FILE (producer)
{
#if defined GDB_SELF_TEST
selftests::register_test
diff --git a/gdb/progspace.c b/gdb/progspace.c
index eda6379..1c27165 100644
--- a/gdb/progspace.c
+++ b/gdb/progspace.c
@@ -21,7 +21,6 @@
#include "objfiles.h"
#include "gdbcore.h"
#include "solib.h"
-#include "solist.h"
#include "gdbthread.h"
#include "inferior.h"
#include <algorithm>
diff --git a/gdb/progspace.h b/gdb/progspace.h
index 1ae826d..a761e62 100644
--- a/gdb/progspace.h
+++ b/gdb/progspace.h
@@ -21,12 +21,13 @@
#ifndef GDB_PROGSPACE_H
#define GDB_PROGSPACE_H
+#include "solib.h"
#include "target.h"
#include "gdb_bfd.h"
#include "registry.h"
-#include "solist.h"
#include "gdbsupport/safe-iterator.h"
#include "gdbsupport/intrusive_list.h"
+#include "gdbsupport/owning_intrusive_list.h"
#include "gdbsupport/refcounted-object.h"
#include "gdbsupport/gdb_ref_ptr.h"
#include <vector>
@@ -231,9 +232,30 @@ struct program_space
is outside all objfiles in this progspace. */
struct objfile *objfile_for_address (CORE_ADDR address);
- /* Return the list of all the solibs in this program space. */
+ /* Set this program space's solib provider.
+
+ The solib provider must be unset prior to calling this method. */
+ void set_solib_ops (solib_ops_up ops)
+ {
+ gdb_assert (m_solib_ops == nullptr);
+ m_solib_ops = std::move (ops);
+ };
+
+ /* Unset and free this program space's solib provider. */
+ void unset_solib_ops ()
+ { m_solib_ops = nullptr; }
+
+ /* Unset and return this program space's solib provider. */
+ solib_ops_up release_solib_ops ()
+ { return std::move (m_solib_ops); }
+
+ /* Get this program space's solib provider. */
+ const struct solib_ops *solib_ops () const
+ { return m_solib_ops.get (); }
+
+ /* Return the list of all the solibs in this program space. */
owning_intrusive_list<solib> &solibs ()
- { return so_list; }
+ { return m_solib_list; }
/* Similar to `bfd_get_filename (exec_bfd ())` but in original form given
by user, without symbolic links and pathname resolved. It is not nullptr
@@ -337,10 +359,6 @@ struct program_space
(e.g. the argument to the "symbol-file" or "file" command). */
struct objfile *symfile_object_file = NULL;
- /* List of shared objects mapped into this space. Managed by
- solib.c. */
- owning_intrusive_list<solib> so_list;
-
/* Number of calls to solib_add. */
unsigned int solib_add_generation = 0;
@@ -359,6 +377,13 @@ private:
/* All known objfiles are kept in a linked list. */
owning_intrusive_list<objfile> m_objfiles_list;
+ /* solib_ops implementation used to provide solibs in this program space. */
+ solib_ops_up m_solib_ops;
+
+ /* List of shared objects mapped into this space. Managed by
+ solib.c. */
+ owning_intrusive_list<solib> m_solib_list;
+
/* The set of target sections matching the sections mapped into
this program space. Managed by both exec_ops and solib.c. */
std::vector<target_section> m_target_sections;
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index 986ef44..516ba72 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -1552,9 +1552,7 @@ maintenance_check_psymtabs (const char *ignore, int from_tty)
}
}
-void _initialize_psymtab ();
-void
-_initialize_psymtab ()
+INIT_GDB_FILE (psymtab)
{
add_cmd ("psymbols", class_maintenance, maintenance_print_psymbols, _("\
Print dump of current partial symbol definitions.\n\
diff --git a/gdb/python/lib/gdb/__init__.py b/gdb/python/lib/gdb/__init__.py
index 4ea5d06..cedd897 100644
--- a/gdb/python/lib/gdb/__init__.py
+++ b/gdb/python/lib/gdb/__init__.py
@@ -19,17 +19,22 @@ import sys
import threading
import traceback
from contextlib import contextmanager
+from importlib import reload
-# Python 3 moved "reload"
-if sys.version_info >= (3, 4):
- from importlib import reload
-else:
- from imp import reload
-
-import _gdb
-
+# The star import imports _gdb names. When the names are used locally, they
+# trigger F405 warnings unless added to the explicit import list.
# Note that two indicators are needed here to silence flake8.
from _gdb import * # noqa: F401,F403
+from _gdb import (
+ STDERR,
+ STDOUT,
+ Command,
+ execute,
+ flush,
+ parameter,
+ selected_inferior,
+ write,
+)
# isort: split
@@ -60,14 +65,14 @@ class _GdbFile(object):
self.write(line)
def flush(self):
- _gdb.flush(stream=self.stream)
+ flush(stream=self.stream)
def write(self, s):
- _gdb.write(s, stream=self.stream)
+ write(s, stream=self.stream)
-sys.stdout = _GdbFile(_gdb.STDOUT)
-sys.stderr = _GdbFile(_gdb.STDERR)
+sys.stdout = _GdbFile(STDOUT)
+sys.stderr = _GdbFile(STDERR)
# Default prompt hook does nothing.
prompt_hook = None
@@ -189,7 +194,7 @@ def GdbSetPythonDirectory(dir):
def current_progspace():
"Return the current Progspace."
- return _gdb.selected_inferior().progspace
+ return selected_inferior().progspace
def objfiles():
@@ -226,14 +231,14 @@ def set_parameter(name, value):
value = "on"
else:
value = "off"
- _gdb.execute("set " + name + " " + str(value), to_string=True)
+ execute("set " + name + " " + str(value), to_string=True)
@contextmanager
def with_parameter(name, value):
"""Temporarily set the GDB parameter NAME to VALUE.
Note that this is a context manager."""
- old_value = _gdb.parameter(name)
+ old_value = parameter(name)
set_parameter(name, value)
try:
# Nothing that useful to return.
@@ -392,3 +397,121 @@ def _handle_missing_objfile(pspace, buildid, filename):
return _handle_missing_files(
pspace, "objfile", lambda h: h(pspace, buildid, filename)
)
+
+
+class ParameterPrefix:
+ # A wrapper around gdb.Command for creating set/show prefixes.
+ #
+ # When creating a gdb.Parameter sub-classes, it is sometimes necessary
+ # to first create a gdb.Command object in order to create the needed
+ # command prefix. However, for parameters, we actually need two
+ # prefixes, a 'set' prefix, and a 'show' prefix. With this helper
+ # class, a single instance of this class will create both prefixes at
+ # once.
+ #
+ # It is important that this class-level documentation not be a __doc__
+ # string. Users are expected to sub-class this ParameterPrefix class
+ # and add their own documentation. If they don't, then GDB will
+ # generate a suitable doc string. But, if this (parent) class has a
+ # __doc__ string of its own, then sub-classes will inherit that __doc__
+ # string, and GDB will not understand that it needs to generate one.
+
+ class _PrefixCommand(Command):
+ """A gdb.Command used to implement both the set and show prefixes.
+
+ This documentation string is not used as the prefix command
+ documentation as it is overridden in the __init__ method below."""
+
+ # This private method is connected to the 'invoke' attribute within
+ # this _PrefixCommand object if the containing ParameterPrefix
+ # object has an invoke_set or invoke_show method.
+ #
+ # This method records within self.__delegate which _PrefixCommand
+ # object is currently active, and then calls the correct invoke
+ # method on the delegat object (the ParameterPrefix sub-class
+ # object).
+ #
+ # Recording the currently active _PrefixCommand object is important;
+ # if from the invoke method the user calls dont_repeat, then this is
+ # forwarded to the currently active _PrefixCommand object.
+ def __invoke(self, args, from_tty):
+
+ # A helper class for use as part of a Python 'with' block.
+ # Records which gdb.Command object is currently running its
+ # invoke method.
+ class MarkActiveCallback:
+ # The CMD is a _PrefixCommand object, and the DELEGATE is
+ # the ParameterPrefix class, or sub-class object. At this
+ # point we simple record both of these within the
+ # MarkActiveCallback object.
+ def __init__(self, cmd, delegate):
+ self.__cmd = cmd
+ self.__delegate = delegate
+
+ # Record the currently active _PrefixCommand object within
+ # the outer ParameterPrefix sub-class object.
+ def __enter__(self):
+ self.__delegate.active_prefix = self.__cmd
+
+ # Once the invoke method has completed, then clear the
+ # _PrefixCommand object that was stored into the outer
+ # ParameterPrefix sub-class object.
+ def __exit__(self, exception_type, exception_value, traceback):
+ self.__delegate.active_prefix = None
+
+ # The self.__cb attribute is set when the _PrefixCommand object
+ # is created, and is either invoke_set or invoke_show within the
+ # ParameterPrefix sub-class object.
+ assert callable(self.__cb)
+
+ # Record the currently active _PrefixCommand object within the
+ # ParameterPrefix sub-class object, then call the relevant
+ # invoke method within the ParameterPrefix sub-class object.
+ with MarkActiveCallback(self, self.__delegate):
+ self.__cb(args, from_tty)
+
+ @staticmethod
+ def __find_callback(delegate, mode):
+ """The MODE is either 'set' or 'show'. Look for an invoke_MODE method
+ on DELEGATE, if a suitable method is found, then return it, otherwise,
+ return None.
+ """
+ cb = getattr(delegate, "invoke_" + mode, None)
+ if callable(cb):
+ return cb
+ return None
+
+ def __init__(self, mode, name, cmd_class, delegate, doc=None):
+ """Setup this gdb.Command. Mode is a string, either 'set' or 'show'.
+ NAME is the name for this prefix command, that is, the
+ words that appear after both 'set' and 'show' in the
+ command name. CMD_CLASS is the usual enum. And DELEGATE
+ is the gdb.ParameterPrefix object this prefix is part of.
+ """
+ assert mode == "set" or mode == "show"
+ if doc is None:
+ self.__doc__ = delegate.__doc__
+ else:
+ self.__doc__ = doc
+ self.__cb = self.__find_callback(delegate, mode)
+ self.__delegate = delegate
+ if self.__cb is not None:
+ self.invoke = self.__invoke
+ super().__init__(mode + " " + name, cmd_class, prefix=True)
+
+ def __init__(self, name, cmd_class, doc=None):
+ """Create a _PrefixCommand for both the set and show prefix commands.
+ NAME is the command name without either the leading 'set ' or
+ 'show ' strings, and CMD_CLASS is the usual enum value.
+ """
+ self.active_prefix = None
+ self._set_prefix_cmd = self._PrefixCommand("set", name, cmd_class, self, doc)
+ self._show_prefix_cmd = self._PrefixCommand("show", name, cmd_class, self, doc)
+
+ # When called from within an invoke method the self.active_prefix
+ # attribute should be set to a gdb.Command sub-class (a _PrefixCommand
+ # object, see above). Forward the dont_repeat call to this object to
+ # register the actual command as none repeating.
+ def dont_repeat(self):
+ if self.active_prefix is not None:
+ self.active_prefix.dont_repeat()
diff --git a/gdb/python/lib/gdb/dap/breakpoint.py b/gdb/python/lib/gdb/dap/breakpoint.py
index 59da120..4d4ca18 100644
--- a/gdb/python/lib/gdb/dap/breakpoint.py
+++ b/gdb/python/lib/gdb/dap/breakpoint.py
@@ -326,7 +326,7 @@ def _rewrite_fn_breakpoint(
}
-@request("setFunctionBreakpoints")
+@request("setFunctionBreakpoints", expect_stopped=False)
@capability("supportsFunctionBreakpoints")
def set_fn_breakpoint(*, breakpoints: Sequence, **args):
specs = [_rewrite_fn_breakpoint(**bp) for bp in breakpoints]
@@ -359,7 +359,7 @@ def _rewrite_insn_breakpoint(
}
-@request("setInstructionBreakpoints")
+@request("setInstructionBreakpoints", expect_stopped=False)
@capability("supportsInstructionBreakpoints")
def set_insn_breakpoints(
*, breakpoints: Sequence, offset: Optional[int] = None, **args
@@ -410,7 +410,7 @@ def _rewrite_exception_breakpoint(
}
-@request("setExceptionBreakpoints")
+@request("setExceptionBreakpoints", expect_stopped=False)
@capability("supportsExceptionFilterOptions")
@capability(
"exceptionBreakpointFilters",
diff --git a/gdb/python/lib/gdb/dap/completions.py b/gdb/python/lib/gdb/dap/completions.py
index 85acc43..e5003ff 100644
--- a/gdb/python/lib/gdb/dap/completions.py
+++ b/gdb/python/lib/gdb/dap/completions.py
@@ -39,8 +39,11 @@ def completions(
line = 1
else:
line = import_line(line)
- text = text.splitlines()[line - 1]
- text = text[: column - 1]
+ if text:
+ text = text.splitlines()[line - 1]
+ text = text[: column - 1]
+ else:
+ text = ""
mi_result = exec_mi_and_log("-complete", text)
result = []
completion = None
diff --git a/gdb/python/lib/gdb/dap/evaluate.py b/gdb/python/lib/gdb/dap/evaluate.py
index 55538e6..fcbcc99 100644
--- a/gdb/python/lib/gdb/dap/evaluate.py
+++ b/gdb/python/lib/gdb/dap/evaluate.py
@@ -69,7 +69,7 @@ def _repl(command, frame_id):
}
-@request("evaluate")
+@request("evaluate", defer_events=False)
@capability("supportsEvaluateForHovers")
@capability("supportsValueFormattingOptions")
def eval_request(
@@ -110,7 +110,7 @@ def variables(
@capability("supportsSetExpression")
-@request("setExpression")
+@request("setExpression", defer_events=False)
def set_expression(
*, expression: str, value: str, frameId: Optional[int] = None, format=None, **args
):
@@ -126,7 +126,7 @@ def set_expression(
@capability("supportsSetVariable")
-@request("setVariable")
+@request("setVariable", defer_events=False)
def set_variable(
*, variablesReference: int, name: str, value: str, format=None, **args
):
diff --git a/gdb/python/lib/gdb/dap/events.py b/gdb/python/lib/gdb/dap/events.py
index 4dc9d65..e8f2655 100644
--- a/gdb/python/lib/gdb/dap/events.py
+++ b/gdb/python/lib/gdb/dap/events.py
@@ -17,12 +17,12 @@ import gdb
from .modules import is_module, make_module
from .scopes import set_finish_value
-from .server import send_event, send_event_maybe_later
+from .server import send_event
from .startup import exec_and_log, in_gdb_thread, log
# True when the inferior is thought to be running, False otherwise.
# This may be accessed from any thread, which can be racy. However,
-# this unimportant because this global is only used for the
+# this is unimportant because this global is only used for the
# 'notStopped' response, which itself is inherently racy.
inferior_running = False
@@ -240,7 +240,7 @@ def _on_stop(event):
else:
obj["reason"] = stop_reason_map[event.details["reason"]]
_expected_pause = False
- send_event_maybe_later("stopped", obj)
+ send_event("stopped", obj)
# This keeps a bit of state between the start of an inferior call and
diff --git a/gdb/python/lib/gdb/dap/next.py b/gdb/python/lib/gdb/dap/next.py
index ddf4e05..898fff1 100644
--- a/gdb/python/lib/gdb/dap/next.py
+++ b/gdb/python/lib/gdb/dap/next.py
@@ -16,7 +16,7 @@
import gdb
from .events import exec_and_expect_stop
-from .server import capability, request, send_gdb, send_gdb_with_response
+from .server import capability, request
from .startup import in_gdb_thread
from .state import set_thread
@@ -73,19 +73,14 @@ def step_in(
exec_and_expect_stop(cmd)
-@request("stepOut", defer_stop_events=True)
+@request("stepOut")
def step_out(*, threadId: int, singleThread: bool = False, **args):
_handle_thread_step(threadId, singleThread, True)
exec_and_expect_stop("finish &", propagate_exception=True)
-# This is a server-side request because it is funny: it wants to
-# 'continue' but also return a result, which precludes using
-# response=False. Using 'continue &' would mostly work ok, but this
-# yields races when a stop occurs before the response is sent back to
-# the client.
-@request("continue", on_dap_thread=True)
+@request("continue")
def continue_request(*, threadId: int, singleThread: bool = False, **args):
- locked = send_gdb_with_response(lambda: _handle_thread_step(threadId, singleThread))
- send_gdb(lambda: exec_and_expect_stop("continue"))
+ locked = _handle_thread_step(threadId, singleThread)
+ exec_and_expect_stop("continue &")
return {"allThreadsContinued": not locked}
diff --git a/gdb/python/lib/gdb/dap/server.py b/gdb/python/lib/gdb/dap/server.py
index c4fa781..7dab582 100644
--- a/gdb/python/lib/gdb/dap/server.py
+++ b/gdb/python/lib/gdb/dap/server.py
@@ -74,6 +74,13 @@ class DeferredRequest:
self._result = result
@in_dap_thread
+ def defer_events(self):
+ """Return True if events should be deferred during execution.
+
+ This may be overridden by subclasses."""
+ return True
+
+ @in_dap_thread
def invoke(self):
"""Implement the deferred request.
@@ -95,7 +102,10 @@ class DeferredRequest:
"""
with _server.canceller.current_request(self._req):
+ if self.defer_events():
+ _server.set_defer_events()
_server.invoke_request(self._req, self._result, self.invoke)
+ _server.emit_pending_events()
# A subclass of Exception that is used solely for reporting that a
@@ -230,7 +240,7 @@ class Server:
self._out_stream = out_stream
self._child_stream = child_stream
self._delayed_fns_lock = threading.Lock()
- self.defer_stop_events = False
+ self._defer_events = False
self._delayed_fns = []
# This queue accepts JSON objects that are then sent to the
# DAP client. Writing is done in a separate thread to avoid
@@ -316,7 +326,7 @@ class Server:
def _read_inferior_output(self):
while True:
line = self._child_stream.readline()
- self.send_event(
+ self.send_event_maybe_later(
"output",
{
"category": "stdout",
@@ -356,6 +366,17 @@ class Server:
self._read_queue.put(None)
@in_dap_thread
+ def emit_pending_events(self):
+ """Emit any pending events."""
+ fns = None
+ with self._delayed_fns_lock:
+ fns = self._delayed_fns
+ self._delayed_fns = []
+ self._defer_events = False
+ for fn in fns:
+ fn()
+
+ @in_dap_thread
def main_loop(self):
"""The main loop of the DAP server."""
# Before looping, start the thread that writes JSON to the
@@ -371,13 +392,7 @@ class Server:
req = cmd["seq"]
with self.canceller.current_request(req):
self._handle_command(cmd)
- fns = None
- with self._delayed_fns_lock:
- fns = self._delayed_fns
- self._delayed_fns = []
- self.defer_stop_events = False
- for fn in fns:
- fn()
+ self.emit_pending_events()
# Got the terminate request. This is handled by the
# JSON-writing thread, so that we can ensure that all
# responses are flushed to the client before exiting.
@@ -386,13 +401,13 @@ class Server:
send_gdb("quit")
@in_dap_thread
- def send_event_later(self, event, body=None):
- """Send a DAP event back to the client, but only after the
- current request has completed."""
+ def set_defer_events(self):
+ """Defer any events until the current request has completed."""
with self._delayed_fns_lock:
- self._delayed_fns.append(lambda: self.send_event(event, body))
+ self._defer_events = True
- @in_gdb_thread
+ # Note that this does not need to be run in any particular thread,
+ # because it uses locks for thread-safety.
def send_event_maybe_later(self, event, body=None):
"""Send a DAP event back to the client, but if a request is in-flight
within the dap thread and that request is configured to delay the event,
@@ -401,10 +416,10 @@ class Server:
with self.canceller.lock:
if self.canceller.in_flight_dap_thread:
with self._delayed_fns_lock:
- if self.defer_stop_events:
- self._delayed_fns.append(lambda: self.send_event(event, body))
+ if self._defer_events:
+ self._delayed_fns.append(lambda: self._send_event(event, body))
return
- self.send_event(event, body)
+ self._send_event(event, body)
@in_dap_thread
def call_function_later(self, fn):
@@ -415,7 +430,7 @@ class Server:
# Note that this does not need to be run in any particular thread,
# because it just creates an object and writes it to a thread-safe
# queue.
- def send_event(self, event, body=None):
+ def _send_event(self, event, body=None):
"""Send an event to the DAP client.
EVENT is the name of the event, a string.
BODY is the body of the event, an arbitrary object."""
@@ -439,14 +454,6 @@ def send_event(event, body=None):
"""Send an event to the DAP client.
EVENT is the name of the event, a string.
BODY is the body of the event, an arbitrary object."""
- _server.send_event(event, body)
-
-
-def send_event_maybe_later(event, body=None):
- """Send a DAP event back to the client, but if a request is in-flight
- within the dap thread and that request is configured to delay the event,
- wait until the response has been sent until the event is sent back to
- the client."""
_server.send_event_maybe_later(event, body)
@@ -476,7 +483,7 @@ def request(
response: bool = True,
on_dap_thread: bool = False,
expect_stopped: bool = True,
- defer_stop_events: bool = False
+ defer_events: bool = True
):
"""A decorator for DAP requests.
@@ -498,9 +505,9 @@ def request(
inferior is running. When EXPECT_STOPPED is False, the request
will proceed regardless of the inferior's state.
- If DEFER_STOP_EVENTS is True, then make sure any stop events sent
- during the request processing are not sent to the client until the
- response has been sent.
+ If DEFER_EVENTS is True, then make sure any events sent during the
+ request processing are not sent to the client until the response
+ has been sent.
"""
# Validate the parameters.
@@ -523,26 +530,33 @@ def request(
# Verify that the function is run on the correct thread.
if on_dap_thread:
- cmd = in_dap_thread(func)
+ check_cmd = in_dap_thread(func)
else:
func = in_gdb_thread(func)
if response:
- if defer_stop_events:
- if _server is not None:
- with _server.delayed_events_lock:
- _server.defer_stop_events = True
def sync_call(**args):
return send_gdb_with_response(lambda: func(**args))
- cmd = sync_call
+ check_cmd = sync_call
else:
def non_sync_call(**args):
return send_gdb(lambda: func(**args))
- cmd = non_sync_call
+ check_cmd = non_sync_call
+
+ if defer_events:
+
+ def deferring(**args):
+ _server.set_defer_events()
+ return check_cmd(**args)
+
+ cmd = deferring
+
+ else:
+ cmd = check_cmd
# If needed, check that the inferior is not running. This
# wrapping is done last, so the check is done first, before
@@ -582,7 +596,7 @@ def client_bool_capability(name, default=False):
@request("initialize", on_dap_thread=True)
def initialize(**args):
_server.config = args
- _server.send_event_later("initialized")
+ _server.send_event_maybe_later("initialized")
global _lines_start_at_1
_lines_start_at_1 = client_bool_capability("linesStartAt1", True)
global _columns_start_at_1
diff --git a/gdb/python/lib/gdb/dap/sources.py b/gdb/python/lib/gdb/dap/sources.py
index 625c01f..efcd799 100644
--- a/gdb/python/lib/gdb/dap/sources.py
+++ b/gdb/python/lib/gdb/dap/sources.py
@@ -64,9 +64,9 @@ def decode_source(source):
"""Decode a Source object.
Finds and returns the filename of a given Source object."""
- if "path" in source:
- return source["path"]
- if "sourceReference" not in source:
+ if "sourceReference" not in source or source["sourceReference"] <= 0:
+ if "path" in source:
+ return source["path"]
raise DAPException("either 'path' or 'sourceReference' must appear in Source")
ref = source["sourceReference"]
if ref not in _id_map:
diff --git a/gdb/python/lib/gdb/dap/threads.py b/gdb/python/lib/gdb/dap/threads.py
index c271961..89046a8 100644
--- a/gdb/python/lib/gdb/dap/threads.py
+++ b/gdb/python/lib/gdb/dap/threads.py
@@ -16,27 +16,32 @@
import gdb
from .server import request
+from .startup import in_gdb_thread
+@in_gdb_thread
def _thread_name(thr):
if thr.name is not None:
return thr.name
if thr.details is not None:
return thr.details
- return None
+ # Always return a name, as the protocol doesn't allow for nameless
+ # threads. Use the local thread number here... it doesn't matter
+ # without multi-inferior but in that case it might make more
+ # sense.
+ return f"Thread #{thr.num}"
-@request("threads")
+@request("threads", expect_stopped=False)
def threads(**args):
result = []
for thr in gdb.selected_inferior().threads():
- one_result = {
- "id": thr.global_num,
- }
- name = _thread_name(thr)
- if name is not None:
- one_result["name"] = name
- result.append(one_result)
+ result.append(
+ {
+ "id": thr.global_num,
+ "name": _thread_name(thr),
+ }
+ )
return {
"threads": result,
}
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index 58998f5..9ce8671 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -1537,9 +1537,7 @@ PyTypeObject breakpoint_object_type =
0, /* tp_alloc */
};
-void _initialize_py_breakpoint ();
-void
-_initialize_py_breakpoint ()
+INIT_GDB_FILE (py_breakpoint)
{
add_setshow_boolean_cmd
("py-breakpoint", class_maintenance, &pybp_debug,
diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c
index 5d98d03..dc5e270 100644
--- a/gdb/python/py-cmd.c
+++ b/gdb/python/py-cmd.c
@@ -105,19 +105,17 @@ cmdpy_function (const char *args, int from_tty, cmd_list_element *command)
gdbpy_enter enter_py;
- if (! obj)
+ if (obj == nullptr)
error (_("Invalid invocation of Python command object."));
- if (! PyObject_HasAttr ((PyObject *) obj, invoke_cst))
- {
- if (obj->command->is_prefix ())
- {
- /* A prefix command does not need an invoke method. */
- return;
- }
- error (_("Python command object missing 'invoke' method."));
- }
- if (! args)
+ /* If we get here for a prefix command then the prefix command had an
+ 'invoke' method when it was created. If the 'invoke' method is now
+ missing, then the user has done something weird (like deleting the
+ invoke method, yuck!). */
+ if (!PyObject_HasAttr ((PyObject *) obj, invoke_cst))
+ error (_("Python command object missing 'invoke' method."));
+
+ if (args == nullptr)
args = "";
gdbpy_ref<> argobj (PyUnicode_Decode (args, strlen (args), host_charset (),
NULL));
@@ -336,24 +334,30 @@ cmdpy_completer (struct cmd_list_element *command,
name of the new command. All earlier words must be existing prefix
commands.
- *BASE_LIST is set to the final prefix command's list of
- *sub-commands.
+ *BASE_LIST is set to the final prefix command's list of sub-commands.
START_LIST is the list in which the search starts.
+ When PREFIX_CMD is not NULL then *PREFIX_CMD is set to the prefix
+ command itself, or NULL, if there is no prefix command.
+
This function returns the name of the new command. On error sets the Python
error and returns NULL. */
gdb::unique_xmalloc_ptr<char>
gdbpy_parse_command_name (const char *name,
struct cmd_list_element ***base_list,
- struct cmd_list_element **start_list)
+ struct cmd_list_element **start_list,
+ struct cmd_list_element **prefix_cmd)
{
struct cmd_list_element *elt;
int len = strlen (name);
int i, lastchar;
const char *prefix_text2;
+ if (prefix_cmd != nullptr)
+ *prefix_cmd = nullptr;
+
/* Skip trailing whitespace. */
for (i = len - 1; i >= 0 && (name[i] == ' ' || name[i] == '\t'); --i)
;
@@ -368,9 +372,8 @@ gdbpy_parse_command_name (const char *name,
for (; i > 0 && valid_cmd_char_p (name[i - 1]); --i)
;
- gdb::unique_xmalloc_ptr<char> result ((char *) xmalloc (lastchar - i + 2));
- memcpy (result.get (), &name[i], lastchar - i + 1);
- result.get ()[lastchar - i + 1] = '\0';
+ gdb::unique_xmalloc_ptr<char> result
+ = make_unique_xstrndup (&name[i], lastchar - i + 1);
/* Skip whitespace again. */
for (--i; i >= 0 && (name[i] == ' ' || name[i] == '\t'); --i)
@@ -385,7 +388,7 @@ gdbpy_parse_command_name (const char *name,
prefix_text2 = prefix_text.c_str ();
elt = lookup_cmd_1 (&prefix_text2, *start_list, NULL, NULL, 1);
- if (elt == NULL || elt == CMD_LIST_AMBIGUOUS)
+ if (elt == nullptr || elt == CMD_LIST_AMBIGUOUS || *prefix_text2 != '\0')
{
PyErr_Format (PyExc_RuntimeError, _("Could not find command prefix %s."),
prefix_text.c_str ());
@@ -395,6 +398,8 @@ gdbpy_parse_command_name (const char *name,
if (elt->is_prefix ())
{
*base_list = elt->subcommands;
+ if (prefix_cmd != nullptr)
+ *prefix_cmd = elt;
return result;
}
@@ -469,8 +474,9 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
return -1;
}
+ cmd_list_element *prefix_cmd = nullptr;
gdb::unique_xmalloc_ptr<char> cmd_name
- = gdbpy_parse_command_name (name, &cmd_list, &cmdlist);
+ = gdbpy_parse_command_name (name, &cmd_list, &cmdlist, &prefix_cmd);
if (cmd_name == nullptr)
return -1;
@@ -507,26 +513,64 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
if (is_prefix)
{
- int allow_unknown;
-
- /* If we have our own "invoke" method, then allow unknown
- sub-commands. */
- allow_unknown = PyObject_HasAttr (self, invoke_cst);
- cmd = add_prefix_cmd (cmd_name.get (),
- (enum command_class) cmdtype,
- NULL, docstring.release (), &obj->sub_list,
- allow_unknown, cmd_list);
+ bool has_invoke = PyObject_HasAttr (self, invoke_cst) == 1;
+ if (has_invoke)
+ {
+ /* If there's an 'invoke' method, then create the prefix
+ command, but call cmdpy_function to dispatch to the invoke
+ method when the user runs the prefix with no sub-command. */
+ cmd = add_prefix_cmd (cmd_name.get (),
+ (enum command_class) cmdtype,
+ nullptr,
+ docstring.release (), &obj->sub_list,
+ 1 /* allow_unknown */, cmd_list);
+ cmd->func = cmdpy_function;
+ }
+ else
+ {
+ /* If there is no 'invoke' method, then create the prefix
+ using the standard prefix callbacks. This means that for
+ 'set prefix' the user will get the help text listing all
+ of the sub-commands, and for 'show prefix', the user will
+ see all of the sub-command values. */
+ if (prefix_cmd != nullptr)
+ {
+ while (prefix_cmd->prefix != nullptr)
+ prefix_cmd = prefix_cmd->prefix;
+ }
+
+ bool is_show = (prefix_cmd != nullptr
+ && prefix_cmd->subcommands == &showlist);
+
+ if (is_show)
+ cmd = add_show_prefix_cmd (cmd_name.get (),
+ (enum command_class) cmdtype,
+ docstring.release (),
+ &obj->sub_list,
+ 0 /* allow_unknown */, cmd_list);
+ else
+ cmd = add_basic_prefix_cmd (cmd_name.get (),
+ (enum command_class) cmdtype,
+ docstring.release (),
+ &obj->sub_list,
+ 0 /* allow_unknown */, cmd_list);
+ }
}
else
- cmd = add_cmd (cmd_name.get (), (enum command_class) cmdtype,
- docstring.release (), cmd_list);
+ {
+ /* For non-prefix commands, arrange to call cmdpy_function, which
+ invokes the Python 'invoke' method, or raises an exception if
+ the 'invoke' method is missing. */
+ cmd = add_cmd (cmd_name.get (), (enum command_class) cmdtype,
+ docstring.release (), cmd_list);
+ cmd->func = cmdpy_function;
+ }
/* If successful, the above takes ownership of the name, since we set
name_allocated, so release it. */
cmd_name.release ();
- /* There appears to be no API to set this. */
- cmd->func = cmdpy_function;
+ /* There appears to be no API to set these member variables. */
cmd->destroyer = cmdpy_destroyer;
cmd->doc_allocated = 1;
cmd->name_allocated = 1;
diff --git a/gdb/python/py-connection.c b/gdb/python/py-connection.c
index 93757ac..a6d9ad0 100644
--- a/gdb/python/py-connection.c
+++ b/gdb/python/py-connection.c
@@ -428,9 +428,7 @@ connpy_send_packet (PyObject *self, PyObject *args, PyObject *kw)
/* Global initialization for this file. */
-void _initialize_py_connection ();
-void
-_initialize_py_connection ()
+INIT_GDB_FILE (py_connection)
{
gdb::observers::connection_removed.attach (connpy_connection_removed,
"py-connection");
diff --git a/gdb/python/py-dap.c b/gdb/python/py-dap.c
index 7196d6c..9a9875a 100644
--- a/gdb/python/py-dap.c
+++ b/gdb/python/py-dap.c
@@ -110,9 +110,7 @@ dap_interp::pre_command_loop ()
call_dap_fn ("pre_command_loop");
}
-void _initialize_py_interp ();
-void
-_initialize_py_interp ()
+INIT_GDB_FILE (py_interp)
{
/* The dap code uses module typing, available starting python 3.5. */
#if PY_VERSION_HEX >= 0x03050000
diff --git a/gdb/python/py-gdb-readline.c b/gdb/python/py-gdb-readline.c
index ea3a385..70ceebb 100644
--- a/gdb/python/py-gdb-readline.c
+++ b/gdb/python/py-gdb-readline.c
@@ -29,11 +29,7 @@
static char *
gdbpy_readline_wrapper (FILE *sys_stdin, FILE *sys_stdout,
-#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 4
const char *prompt)
-#else
- char *prompt)
-#endif
{
int n;
const char *p = NULL;
diff --git a/gdb/python/py-micmd.c b/gdb/python/py-micmd.c
index e4f07c9..72f427f 100644
--- a/gdb/python/py-micmd.c
+++ b/gdb/python/py-micmd.c
@@ -578,9 +578,7 @@ PyTypeObject micmdpy_object_type = {
0, /* tp_alloc */
};
-void _initialize_py_micmd ();
-void
-_initialize_py_micmd ()
+INIT_GDB_FILE (py_micmd)
{
add_setshow_boolean_cmd
("py-micmd", class_maintenance, &pymicmd_debug,
diff --git a/gdb/python/py-param.c b/gdb/python/py-param.c
index 763680e..06237b6 100644
--- a/gdb/python/py-param.c
+++ b/gdb/python/py-param.c
@@ -495,7 +495,11 @@ get_doc_string (PyObject *object, enum doc_string_type doc_type,
}
}
- if (result == nullptr)
+ /* For the set/show docs, if these strings are empty then we set then to
+ a non-empty string. This ensures that the command has some sane
+ documentation for its 'help' text. */
+ if (result == nullptr
+ || (doc_type != doc_string_description && *result == '\0'))
{
if (doc_type == doc_string_description)
result.reset (xstrdup (_("This command is not documented.")));
@@ -904,6 +908,18 @@ parmpy_init (PyObject *self, PyObject *args, PyObject *kwds)
show_doc = get_doc_string (self, doc_string_show, name);
doc = get_doc_string (self, doc_string_description, cmd_name.get ());
+ /* The set/show docs should always be a non-empty string. */
+ gdb_assert (set_doc != nullptr && *set_doc != '\0');
+ gdb_assert (show_doc != nullptr && *show_doc != '\0');
+
+ /* For the DOC string only, if it is the empty string, then we convert it
+ to NULL. This means GDB will not even display a blank line for this
+ part of the help text, instead the set/show line is all the user will
+ get. */
+ gdb_assert (doc != nullptr);
+ if (*doc == '\0')
+ doc = nullptr;
+
Py_INCREF (self);
try
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index f37afde..c546aa7 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -158,7 +158,7 @@ convert_field (struct type *type, int field)
}
else
{
- if (type->field (field).loc_kind () == FIELD_LOC_KIND_DWARF_BLOCK)
+ if (type->field (field).loc_is_dwarf_block ())
arg = gdbpy_ref<>::new_reference (Py_None);
else
arg = gdb_py_object_from_longest (type->field (field).loc_bitpos ());
diff --git a/gdb/python/py-unwind.c b/gdb/python/py-unwind.c
index d43d7e9..dc078ec 100644
--- a/gdb/python/py-unwind.c
+++ b/gdb/python/py-unwind.c
@@ -1029,9 +1029,7 @@ gdbpy_initialize_unwind (void)
return 0;
}
-void _initialize_py_unwind ();
-void
-_initialize_py_unwind ()
+INIT_GDB_FILE (py_unwind)
{
add_setshow_boolean_cmd
("py-unwind", class_maintenance, &pyuw_debug,
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 5262d76..7f4237e 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -88,6 +88,8 @@
#include <frameobject.h>
#include "py-ref.h"
+static_assert (PY_VERSION_HEX >= 0x03040000);
+
#define Py_TPFLAGS_CHECKTYPES 0
/* If Python.h does not define WITH_THREAD, then the various
@@ -135,17 +137,6 @@ typedef unsigned long gdb_py_ulongest;
#endif /* HAVE_LONG_LONG */
-#if PY_VERSION_HEX < 0x03020000
-typedef long Py_hash_t;
-#endif
-
-/* PyMem_RawMalloc appeared in Python 3.4. For earlier versions, we can just
- fall back to PyMem_Malloc. */
-
-#if PY_VERSION_HEX < 0x03040000
-#define PyMem_RawMalloc PyMem_Malloc
-#endif
-
/* A template variable holding the format character (as for
Py_BuildValue) for a given type. */
template<typename T>
@@ -519,7 +510,8 @@ PyObject *gdbpy_string_to_argv (PyObject *self, PyObject *args);
PyObject *gdbpy_parameter_value (const setting &var);
gdb::unique_xmalloc_ptr<char> gdbpy_parse_command_name
(const char *name, struct cmd_list_element ***base_list,
- struct cmd_list_element **start_list);
+ struct cmd_list_element **start_list,
+ struct cmd_list_element **prefix_cmd = nullptr);
PyObject *gdbpy_register_tui_window (PyObject *self, PyObject *args,
PyObject *kw);
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 24cb511..cb0d642 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -1630,6 +1630,40 @@ gdbpy_flush (PyObject *self, PyObject *args, PyObject *kw)
Py_RETURN_NONE;
}
+/* Implement gdb.warning(). Takes a single text string argument and emit a
+ warning using GDB's 'warning' function. The input text string must not
+ be empty. */
+
+static PyObject *
+gdbpy_warning (PyObject *self, PyObject *args, PyObject *kw)
+{
+ const char *text;
+ static const char *keywords[] = { "text", nullptr };
+
+ if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s", keywords, &text))
+ return nullptr;
+
+ if (strlen (text) == 0)
+ {
+ PyErr_SetString (PyExc_ValueError,
+ _("Empty text string passed to gdb.warning"));
+ return nullptr;
+ }
+
+ try
+ {
+ warning ("%s", text);
+ }
+ catch (const gdb_exception &ex)
+ {
+ /* The warning() call probably cannot throw an exception. But just
+ in case it ever does. */
+ return gdbpy_handle_gdb_exception (nullptr, ex);
+ }
+
+ Py_RETURN_NONE;
+}
+
/* Return non-zero if print-stack is not "none". */
int
@@ -2446,7 +2480,7 @@ py_initialize ()
/foo/lib/pythonX.Y/...
This must be done before calling Py_Initialize. */
gdb::unique_xmalloc_ptr<char> progname
- (concat (ldirname (python_libdir.c_str ()).c_str (), SLASH_STRING, "bin",
+ (concat (gdb_ldirname (python_libdir.c_str ()).c_str (), SLASH_STRING, "bin",
SLASH_STRING, "python", (char *) NULL));
{
@@ -2683,9 +2717,7 @@ test_python ()
/* See python.h. */
cmd_list_element *python_cmd_element = nullptr;
-void _initialize_python ();
-void
-_initialize_python ()
+INIT_GDB_FILE (python)
{
cmd_list_element *python_interactive_cmd
= add_com ("python-interactive", class_obscure,
@@ -3124,6 +3156,12 @@ Return the current print options." },
METH_VARARGS | METH_KEYWORDS,
"notify_mi (name, data) -> None\n\
Output async record to MI channels if any." },
+
+ { "warning", (PyCFunction) gdbpy_warning,
+ METH_VARARGS | METH_KEYWORDS,
+ "warning (text) -> None\n\
+Print a warning." },
+
{NULL, NULL, 0, NULL}
};
diff --git a/gdb/ravenscar-thread.c b/gdb/ravenscar-thread.c
index 45205a0..4d79b3d 100644
--- a/gdb/ravenscar-thread.c
+++ b/gdb/ravenscar-thread.c
@@ -921,9 +921,7 @@ Support for Ravenscar task/thread switching is disabled\n"));
/* Module startup initialization function, automagically called by
init.c. */
-void _initialize_ravenscar ();
-void
-_initialize_ravenscar ()
+INIT_GDB_FILE (ravenscar)
{
/* Notice when the inferior is created in order to push the
ravenscar ops if needed. */
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 2d71b72..d789992 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -132,10 +132,7 @@ public:
bool can_execute_reverse () override;
bool stopped_by_sw_breakpoint () override;
- bool supports_stopped_by_sw_breakpoint () override;
-
bool stopped_by_hw_breakpoint () override;
- bool supports_stopped_by_hw_breakpoint () override;
enum exec_direction_kind execution_direction () override;
void prepare_to_generate_core () override;
@@ -2581,7 +2578,7 @@ record_btrace_maybe_mark_async_event
const std::vector<thread_info *> &no_history)
{
bool more_moving = !moving.empty ();
- bool more_no_history = !no_history.empty ();;
+ bool more_no_history = !no_history.empty ();
if (!more_moving && !more_no_history)
return;
@@ -2773,18 +2770,6 @@ record_btrace_target::stopped_by_sw_breakpoint ()
return this->beneath ()->stopped_by_sw_breakpoint ();
}
-/* The supports_stopped_by_sw_breakpoint method of target
- record-btrace. */
-
-bool
-record_btrace_target::supports_stopped_by_sw_breakpoint ()
-{
- if (record_is_replaying (minus_one_ptid))
- return true;
-
- return this->beneath ()->supports_stopped_by_sw_breakpoint ();
-}
-
/* The stopped_by_sw_breakpoint method of target record-btrace. */
bool
@@ -2800,18 +2785,6 @@ record_btrace_target::stopped_by_hw_breakpoint ()
return this->beneath ()->stopped_by_hw_breakpoint ();
}
-/* The supports_stopped_by_hw_breakpoint method of target
- record-btrace. */
-
-bool
-record_btrace_target::supports_stopped_by_hw_breakpoint ()
-{
- if (record_is_replaying (minus_one_ptid))
- return true;
-
- return this->beneath ()->supports_stopped_by_hw_breakpoint ();
-}
-
/* The update_thread_list method of target record-btrace. */
void
@@ -3213,9 +3186,7 @@ set_record_pt_event_tracing_value (const char *args, int from_tty,
/* Initialize btrace commands. */
-void _initialize_record_btrace ();
-void
-_initialize_record_btrace ()
+INIT_GDB_FILE (record_btrace)
{
cmd_list_element *record_btrace_cmd
= add_prefix_cmd ("btrace", class_obscure, cmd_record_btrace_start,
diff --git a/gdb/record-full.c b/gdb/record-full.c
index b52fb06..7e3da27 100644
--- a/gdb/record-full.c
+++ b/gdb/record-full.c
@@ -2877,9 +2877,7 @@ maintenance_print_record_instruction (const char *args, int from_tty)
}
}
-void _initialize_record_full ();
-void
-_initialize_record_full ()
+INIT_GDB_FILE (record_full)
{
struct cmd_list_element *c;
diff --git a/gdb/record.c b/gdb/record.c
index 440c5e9..248cfaa 100644
--- a/gdb/record.c
+++ b/gdb/record.c
@@ -769,9 +769,7 @@ set_record_call_history_size (const char *args, int from_tty,
&record_call_history_size);
}
-void _initialize_record ();
-void
-_initialize_record ()
+INIT_GDB_FILE (record)
{
struct cmd_list_element *c;
diff --git a/gdb/regcache-dump.c b/gdb/regcache-dump.c
index 39dd8c5..c6ef552 100644
--- a/gdb/regcache-dump.c
+++ b/gdb/regcache-dump.c
@@ -346,9 +346,7 @@ maintenance_print_remote_registers (const char *args, int from_tty)
"maintenance print remote-registers");
}
-void _initialize_regcache_dump ();
-void
-_initialize_regcache_dump ()
+INIT_GDB_FILE (regcache_dump)
{
add_cmd ("registers", class_maintenance, maintenance_print_registers,
_("Print the internal register configuration.\n"
diff --git a/gdb/regcache.c b/gdb/regcache.c
index e3d435f..9892c54 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -2213,9 +2213,7 @@ regcache_thread_ptid_changed ()
} /* namespace selftests */
#endif /* GDB_SELF_TEST */
-void _initialize_regcache ();
-void
-_initialize_regcache ()
+INIT_GDB_FILE (regcache)
{
struct cmd_list_element *c;
diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index c931434..596b336 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -259,9 +259,7 @@ const reggroup *const all_reggroup = &all_group;
const reggroup *const save_reggroup = &save_group;
const reggroup *const restore_reggroup = &restore_group;
-void _initialize_reggroup ();
-void
-_initialize_reggroup ()
+INIT_GDB_FILE (reggroup)
{
add_cmd ("reggroups", class_maintenance,
maintenance_print_reggroups, _("\
diff --git a/gdb/remote-notif.c b/gdb/remote-notif.c
index 053591c..da1b578 100644
--- a/gdb/remote-notif.c
+++ b/gdb/remote-notif.c
@@ -234,9 +234,7 @@ remote_notif_state::~remote_notif_state ()
delete_async_event_handler (&get_pending_events_token);
}
-void _initialize_notif ();
-void
-_initialize_notif ()
+INIT_GDB_FILE (notif)
{
add_setshow_boolean_cmd ("notification", no_class, &notif_debug,
_("\
diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c
index fc2c900..425e50d 100644
--- a/gdb/remote-sim.c
+++ b/gdb/remote-sim.c
@@ -1284,9 +1284,7 @@ gdbsim_target::memory_map ()
return result;
}
-void _initialize_remote_sim ();
-void
-_initialize_remote_sim ()
+INIT_GDB_FILE (remote_sim)
{
struct cmd_list_element *c;
diff --git a/gdb/remote.c b/gdb/remote.c
index 1c49cdf..6208a90 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -251,6 +251,7 @@ enum {
PACKET_vFile_readlink,
PACKET_vFile_fstat,
PACKET_vFile_stat,
+ PACKET_vFile_lstat,
PACKET_qXfer_auxv,
PACKET_qXfer_features,
PACKET_qXfer_exec_file,
@@ -1023,8 +1024,8 @@ public:
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_lstat (struct inferior *inf, const char *filename,
+ struct stat *sb, fileio_error *target_errno) override;
int fileio_close (int fd, fileio_error *target_errno) override;
@@ -13149,7 +13150,7 @@ remote_target::fileio_readlink (struct inferior *inf, const char *filename,
return ret;
}
-/* Helper function to handle ::fileio_fstat and ::fileio_stat result
+/* Helper function to handle ::fileio_fstat and ::fileio_lstat result
processing. When this function is called the remote syscall has been
performed and we know we didn't get an error back.
@@ -13160,10 +13161,10 @@ remote_target::fileio_readlink (struct inferior *inf, const char *filename,
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)
+fileio_process_fstat_and_lstat_reply (const char *attachment,
+ int attachment_len,
+ int expected_len,
+ struct stat *st)
{
struct fio_stat fst;
@@ -13225,15 +13226,15 @@ remote_target::fileio_fstat (int fd, struct stat *st, fileio_error *remote_errno
return 0;
}
- return fileio_process_fstat_and_stat_reply (attachment, attachment_len,
- ret, st);
+ return fileio_process_fstat_and_lstat_reply (attachment, attachment_len,
+ ret, st);
}
-/* Implementation of to_fileio_stat. */
+/* Implementation of to_fileio_lstat. */
int
-remote_target::fileio_stat (struct inferior *inf, const char *filename,
- struct stat *st, fileio_error *remote_errno)
+remote_target::fileio_lstat (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 ();
@@ -13242,14 +13243,14 @@ remote_target::fileio_stat (struct inferior *inf, const char *filename,
if (remote_hostio_set_filesystem (inf, remote_errno) != 0)
return {};
- remote_buffer_add_string (&p, &left, "vFile:stat:");
+ remote_buffer_add_string (&p, &left, "vFile:lstat:");
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,
+ int ret = remote_hostio_send_command (p - rs->buf.data (), PACKET_vFile_lstat,
remote_errno, &attachment,
&attachment_len);
@@ -13258,8 +13259,8 @@ remote_target::fileio_stat (struct inferior *inf, const char *filename,
if (ret < 0)
return ret;
- return fileio_process_fstat_and_stat_reply (attachment, attachment_len,
- ret, st);
+ return fileio_process_fstat_and_lstat_reply (attachment, attachment_len,
+ ret, st);
}
/* Implementation of to_filesystem_is_local. */
@@ -16161,9 +16162,7 @@ test_packet_check_result ()
} /* namespace selftests */
#endif /* GDB_SELF_TEST */
-void _initialize_remote ();
-void
-_initialize_remote ()
+INIT_GDB_FILE (remote)
{
add_target (remote_target_info, remote_target::open);
add_target (extended_remote_target_info, extended_remote_target::open);
@@ -16422,6 +16421,8 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
add_packet_config_cmd (PACKET_vFile_stat, "vFile:stat", "hostio-stat", 0);
+ add_packet_config_cmd (PACKET_vFile_lstat, "vFile:lstat", "hostio-lstat", 0);
+
add_packet_config_cmd (PACKET_vAttach, "vAttach", "attach", 0);
add_packet_config_cmd (PACKET_vRun, "vRun", "run", 0);
diff --git a/gdb/reverse.c b/gdb/reverse.c
index 2c9ed72..dc35bca 100644
--- a/gdb/reverse.c
+++ b/gdb/reverse.c
@@ -277,9 +277,7 @@ info_bookmarks_command (const char *args, int from_tty)
}
}
-void _initialize_reverse ();
-void
-_initialize_reverse ()
+INIT_GDB_FILE (reverse)
{
cmd_list_element *reverse_step_cmd
= add_com ("reverse-step", class_run, reverse_step, _("\
diff --git a/gdb/riscv-fbsd-nat.c b/gdb/riscv-fbsd-nat.c
index df7cc6a..2908d9f 100644
--- a/gdb/riscv-fbsd-nat.c
+++ b/gdb/riscv-fbsd-nat.c
@@ -65,9 +65,7 @@ riscv_fbsd_nat_target::store_registers (struct regcache *regcache,
PT_SETFPREGS, &riscv_fbsd_fpregset);
}
-void _initialize_riscv_fbsd_nat ();
-void
-_initialize_riscv_fbsd_nat ()
+INIT_GDB_FILE (riscv_fbsd_nat)
{
add_inf_child_target (&the_riscv_fbsd_nat_target);
}
diff --git a/gdb/riscv-fbsd-tdep.c b/gdb/riscv-fbsd-tdep.c
index fcb91ca..7bdc6e7 100644
--- a/gdb/riscv-fbsd-tdep.c
+++ b/gdb/riscv-fbsd-tdep.c
@@ -191,10 +191,9 @@ riscv_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_software_single_step (gdbarch, riscv_software_single_step);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- (riscv_isa_xlen (gdbarch) == 4
- ? svr4_ilp32_fetch_link_map_offsets
- : svr4_lp64_fetch_link_map_offsets));
+ set_solib_svr4_ops (gdbarch, (riscv_isa_xlen (gdbarch) == 4
+ ? make_svr4_ilp32_solib_ops
+ : make_svr4_lp64_solib_ops));
tramp_frame_prepend_unwinder (gdbarch, &riscv_fbsd_sigframe);
@@ -207,9 +206,7 @@ riscv_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
riscv_fbsd_get_thread_local_address);
}
-void _initialize_riscv_fbsd_tdep ();
-void
-_initialize_riscv_fbsd_tdep ()
+INIT_GDB_FILE (riscv_fbsd_tdep)
{
gdbarch_register_osabi (bfd_arch_riscv, 0, GDB_OSABI_FREEBSD,
riscv_fbsd_init_abi);
diff --git a/gdb/riscv-linux-nat.c b/gdb/riscv-linux-nat.c
index 8846329..89f1ddc 100644
--- a/gdb/riscv-linux-nat.c
+++ b/gdb/riscv-linux-nat.c
@@ -329,9 +329,7 @@ riscv_linux_nat_target::store_registers (struct regcache *regcache, int regnum)
/* Initialize RISC-V Linux native support. */
-void _initialize_riscv_linux_nat ();
-void
-_initialize_riscv_linux_nat ()
+INIT_GDB_FILE (riscv_linux_nat)
{
/* Register the target. */
linux_target = &the_riscv_linux_nat_target;
diff --git a/gdb/riscv-linux-tdep.c b/gdb/riscv-linux-tdep.c
index e1ea615..e5d77e7 100644
--- a/gdb/riscv-linux-tdep.c
+++ b/gdb/riscv-linux-tdep.c
@@ -20,6 +20,7 @@
#include "osabi.h"
#include "glibc-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "svr4-tls-tdep.h"
#include "solib-svr4.h"
#include "regset.h"
@@ -512,10 +513,9 @@ riscv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_software_single_step (gdbarch, riscv_software_single_step);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- (riscv_isa_xlen (gdbarch) == 4
- ? linux_ilp32_fetch_link_map_offsets
- : linux_lp64_fetch_link_map_offsets));
+ set_solib_svr4_ops (gdbarch, (riscv_isa_xlen (gdbarch) == 4
+ ? make_linux_ilp32_svr4_solib_ops
+ : make_linux_lp64_svr4_solib_ops));
/* GNU/Linux uses SVR4-style shared libraries. */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
@@ -544,9 +544,7 @@ riscv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* Initialize RISC-V Linux target support. */
-void _initialize_riscv_linux_tdep ();
-void
-_initialize_riscv_linux_tdep ()
+INIT_GDB_FILE (riscv_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_riscv, 0, GDB_OSABI_LINUX,
riscv_linux_init_abi);
diff --git a/gdb/riscv-none-tdep.c b/gdb/riscv-none-tdep.c
index 7303f54..ad32057 100644
--- a/gdb/riscv-none-tdep.c
+++ b/gdb/riscv-none-tdep.c
@@ -163,9 +163,7 @@ riscv_none_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* Initialize RISC-V bare-metal target support. */
-void _initialize_riscv_none_tdep ();
-void
-_initialize_riscv_none_tdep ()
+INIT_GDB_FILE (riscv_none_tdep)
{
gdbarch_register_osabi (bfd_arch_riscv, 0, GDB_OSABI_NONE,
riscv_none_init_abi);
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index 8998a29..6d439b0 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -4778,9 +4778,7 @@ riscv_supply_regset (const struct regset *regset,
}
}
-void _initialize_riscv_tdep ();
-void
-_initialize_riscv_tdep ()
+INIT_GDB_FILE (riscv_tdep)
{
riscv_init_reggroups ();
@@ -5158,7 +5156,7 @@ private:
{
return (is_csrrw_insn (ival) || is_csrrs_insn (ival) || is_csrrc_insn (ival)
|| is_csrrwi_insn (ival) || is_csrrsi_insn (ival)
- || is_csrrc_insn (ival));
+ || is_csrrci_insn (ival));
}
/* Returns true if instruction is classified. This function can set
diff --git a/gdb/rl78-tdep.c b/gdb/rl78-tdep.c
index f325f41..5c49d1f 100644
--- a/gdb/rl78-tdep.c
+++ b/gdb/rl78-tdep.c
@@ -1488,9 +1488,7 @@ rl78_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
/* Register the above initialization routine. */
-void _initialize_rl78_tdep ();
-void
-_initialize_rl78_tdep ()
+INIT_GDB_FILE (rl78_tdep)
{
gdbarch_register (bfd_arch_rl78, rl78_gdbarch_init);
}
diff --git a/gdb/rs6000-aix-nat.c b/gdb/rs6000-aix-nat.c
index 225d1b8..213f197 100644
--- a/gdb/rs6000-aix-nat.c
+++ b/gdb/rs6000-aix-nat.c
@@ -1062,9 +1062,7 @@ rs6000_nat_target::xfer_shared_libraries
}
}
-void _initialize_rs6000_nat ();
-void
-_initialize_rs6000_nat ()
+INIT_GDB_FILE (rs6000_nat)
{
add_inf_child_target (&the_rs6000_nat_target);
}
diff --git a/gdb/rs6000-aix-tdep.c b/gdb/rs6000-aix-tdep.c
index ab9feb3..853a66e 100644
--- a/gdb/rs6000-aix-tdep.c
+++ b/gdb/rs6000-aix-tdep.c
@@ -1411,13 +1411,11 @@ rs6000_aix_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_wchar_signed (gdbarch, 0);
set_gdbarch_auto_wide_charset (gdbarch, rs6000_aix_auto_wide_charset);
- set_gdbarch_so_ops (gdbarch, &solib_aix_so_ops);
+ set_gdbarch_make_solib_ops (gdbarch, make_aix_solib_ops);
frame_unwind_append_unwinder (gdbarch, &aix_sighandle_frame_unwind);
}
-void _initialize_rs6000_aix_tdep ();
-void
-_initialize_rs6000_aix_tdep ()
+INIT_GDB_FILE (rs6000_aix_tdep)
{
gdbarch_register_osabi_sniffer (bfd_arch_rs6000,
bfd_target_xcoff_flavour,
diff --git a/gdb/rs6000-lynx178-tdep.c b/gdb/rs6000-lynx178-tdep.c
index 38af2ac..d0d9a53 100644
--- a/gdb/rs6000-lynx178-tdep.c
+++ b/gdb/rs6000-lynx178-tdep.c
@@ -407,9 +407,7 @@ rs6000_lynx178_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
}
-void _initialize_rs6000_lynx178_tdep ();
-void
-_initialize_rs6000_lynx178_tdep ()
+INIT_GDB_FILE (rs6000_lynx178_tdep)
{
gdbarch_register_osabi_sniffer (bfd_arch_rs6000,
bfd_target_xcoff_flavour,
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 23ccd92..1c75bb7 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -8722,9 +8722,7 @@ ppc_insn_prefix_dform (unsigned int insn1, unsigned int insn2)
/* Initialization code. */
-void _initialize_rs6000_tdep ();
-void
-_initialize_rs6000_tdep ()
+INIT_GDB_FILE (rs6000_tdep)
{
gdbarch_register (bfd_arch_rs6000, rs6000_gdbarch_init, rs6000_dump_tdep);
gdbarch_register (bfd_arch_powerpc, rs6000_gdbarch_init, rs6000_dump_tdep);
diff --git a/gdb/run-on-main-thread.c b/gdb/run-on-main-thread.c
index edaab08..30b0928 100644
--- a/gdb/run-on-main-thread.c
+++ b/gdb/run-on-main-thread.c
@@ -130,9 +130,7 @@ is_main_thread ()
#endif
}
-void _initialize_run_on_main_thread ();
-void
-_initialize_run_on_main_thread ()
+INIT_GDB_FILE (run_on_main_thread)
{
#if CXX_STD_THREAD
/* The variable main_thread_id should be initialized when entering main, or
diff --git a/gdb/rust-exp.h b/gdb/rust-exp.h
index 73654f6..3185242 100644
--- a/gdb/rust-exp.h
+++ b/gdb/rust-exp.h
@@ -33,14 +33,6 @@ extern struct value *eval_op_rust_array (struct type *expect_type,
enum exp_opcode opcode,
struct value *ncopies,
struct value *elt);
-extern struct value *rust_subscript (struct type *expect_type,
- struct expression *exp,
- enum noside noside, bool for_addr,
- struct value *lhs, struct value *rhs);
-extern struct value *rust_range (struct type *expect_type,
- struct expression *exp,
- enum noside noside, enum range_flag kind,
- struct value *low, struct value *high);
namespace expr
{
@@ -75,22 +67,26 @@ public:
struct expression *exp,
enum noside noside) override
{
- value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
- value *arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
- return rust_subscript (expect_type, exp, noside, false, arg1, arg2);
+ return subscript (exp, noside, false);
}
value *slice (struct type *expect_type,
struct expression *exp,
enum noside noside)
{
- value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
- value *arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
- return rust_subscript (expect_type, exp, noside, true, arg1, arg2);
+ return subscript (exp, noside, true);
}
enum exp_opcode opcode () const override
{ return BINOP_SUBSCRIPT; }
+
+private:
+
+ /* Helper function that does the work of evaluation. FOR_ADDR is
+ true if we're evaluating a slice. */
+ value *subscript (struct expression *exp, enum noside noside,
+ bool for_addr);
+
};
class rust_unop_addr_operation
@@ -126,17 +122,7 @@ public:
value *evaluate (struct type *expect_type,
struct expression *exp,
- enum noside noside) override
- {
- auto kind = std::get<0> (m_storage);
- value *low = nullptr;
- if (std::get<1> (m_storage) != nullptr)
- low = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
- value *high = nullptr;
- if (std::get<2> (m_storage) != nullptr)
- high = std::get<2> (m_storage)->evaluate (nullptr, exp, noside);
- return rust_range (expect_type, exp, noside, kind, low, high);
- }
+ enum noside noside) override;
enum exp_opcode opcode () const override
{ return OP_RANGE; }
diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c
index 1bb14db..3957413 100644
--- a/gdb/rust-lang.c
+++ b/gdb/rust-lang.c
@@ -1142,13 +1142,22 @@ rust_slice_type (const char *name, struct type *elt_type,
-/* A helper for rust_evaluate_subexp that handles OP_RANGE. */
+namespace expr
+{
struct value *
-rust_range (struct type *expect_type, struct expression *exp,
- enum noside noside, enum range_flag kind,
- struct value *low, struct value *high)
+rust_range_operation::evaluate (struct type *expect_type,
+ struct expression *exp,
+ enum noside noside)
{
+ auto kind = std::get<0> (m_storage);
+ value *low = nullptr;
+ if (std::get<1> (m_storage) != nullptr)
+ low = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
+ value *high = nullptr;
+ if (std::get<2> (m_storage) != nullptr)
+ high = std::get<2> (m_storage)->evaluate (nullptr, exp, noside);
+
struct value *addrval, *result;
CORE_ADDR addr;
struct type *range_type;
@@ -1225,6 +1234,8 @@ rust_range (struct type *expect_type, struct expression *exp,
return result;
}
+} /* namespace expr */
+
/* A helper function to compute the range and kind given a range
value. TYPE is the type of the range value. RANGE is the range
value. LOW, HIGH, and KIND are out parameters. The LOW and HIGH
@@ -1266,13 +1277,16 @@ rust_compute_range (struct type *type, struct value *range,
}
}
-/* A helper for rust_evaluate_subexp that handles BINOP_SUBSCRIPT. */
+namespace expr
+{
struct value *
-rust_subscript (struct type *expect_type, struct expression *exp,
- enum noside noside, bool for_addr,
- struct value *lhs, struct value *rhs)
+rust_subscript_operation::subscript (struct expression *exp,
+ enum noside noside, bool for_addr)
{
+ value *lhs = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
+ value *rhs = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
+
struct value *result;
struct type *rhstype;
LONGEST low, high_bound;
@@ -1413,9 +1427,6 @@ rust_subscript (struct type *expect_type, struct expression *exp,
return result;
}
-namespace expr
-{
-
struct value *
rust_unop_ind_operation::evaluate (struct type *expect_type,
struct expression *exp,
diff --git a/gdb/rust-parse.c b/gdb/rust-parse.c
index ef64005..b428b97 100644
--- a/gdb/rust-parse.c
+++ b/gdb/rust-parse.c
@@ -2421,9 +2421,7 @@ rust_lex_tests (void)
-void _initialize_rust_exp ();
-void
-_initialize_rust_exp ()
+INIT_GDB_FILE (rust_exp)
{
int code = regcomp (&number_regex, number_regex_text, REG_EXTENDED);
/* If the regular expression was incorrect, it was a programming
diff --git a/gdb/rx-tdep.c b/gdb/rx-tdep.c
index f767666..7b110ce 100644
--- a/gdb/rx-tdep.c
+++ b/gdb/rx-tdep.c
@@ -1063,9 +1063,7 @@ rx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
/* Register the above initialization routine. */
-void _initialize_rx_tdep ();
-void
-_initialize_rx_tdep ()
+INIT_GDB_FILE (rx_tdep)
{
gdbarch_register (bfd_arch_rx, rx_gdbarch_init);
initialize_tdesc_rx ();
diff --git a/gdb/s12z-tdep.c b/gdb/s12z-tdep.c
index 70f8598..28d5635 100644
--- a/gdb/s12z-tdep.c
+++ b/gdb/s12z-tdep.c
@@ -662,9 +662,7 @@ s12z_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
return gdbarch;
}
-void _initialize_s12z_tdep ();
-void
-_initialize_s12z_tdep ()
+INIT_GDB_FILE (s12z_tdep)
{
gdbarch_register (bfd_arch_s12z, s12z_gdbarch_init, NULL);
}
diff --git a/gdb/s390-linux-nat.c b/gdb/s390-linux-nat.c
index d5964e2..5b723b1 100644
--- a/gdb/s390-linux-nat.c
+++ b/gdb/s390-linux-nat.c
@@ -1051,9 +1051,7 @@ s390_linux_nat_target::read_description ()
tdesc_s390_linux32);
}
-void _initialize_s390_nat ();
-void
-_initialize_s390_nat ()
+INIT_GDB_FILE (s390_nat)
{
/* Register the target. */
linux_target = &the_s390_linux_nat_target;
diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index bd1f42c..66e571d 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -29,6 +29,7 @@
#include "gdbcore.h"
#include "linux-record.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "svr4-tls-tdep.h"
#include "objfiles.h"
#include "osabi.h"
@@ -1214,8 +1215,7 @@ s390_linux_init_abi_31 (struct gdbarch_info info, struct gdbarch *gdbarch)
s390_linux_init_abi_any (info, gdbarch);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_S390);
}
@@ -1230,14 +1230,11 @@ s390_linux_init_abi_64 (struct gdbarch_info info, struct gdbarch *gdbarch)
s390_linux_init_abi_any (info, gdbarch);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_lp64_svr4_solib_ops);
set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_S390X);
}
-void _initialize_s390_linux_tdep ();
-void
-_initialize_s390_linux_tdep ()
+INIT_GDB_FILE (s390_linux_tdep)
{
/* Hook us into the OSABI mechanism. */
gdbarch_register_osabi (bfd_arch_s390, bfd_mach_s390_31, GDB_OSABI_LINUX,
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
index a3b7658..8a2b405 100644
--- a/gdb/s390-tdep.c
+++ b/gdb/s390-tdep.c
@@ -7515,9 +7515,7 @@ disassemble_s390x ()
#endif /* GDB_SELF_TEST */
-void _initialize_s390_tdep ();
-void
-_initialize_s390_tdep ()
+INIT_GDB_FILE (s390_tdep)
{
/* Hook us into the gdbarch mechanism. */
gdbarch_register (bfd_arch_s390, s390_gdbarch_init);
diff --git a/gdb/ser-go32.c b/gdb/ser-go32.c
index c6b34ab..6e60569 100644
--- a/gdb/ser-go32.c
+++ b/gdb/ser-go32.c
@@ -914,9 +914,7 @@ info_serial_command (const char *arg, int from_tty)
#endif
}
-void _initialize_ser_dos ();
-void
-_initialize_ser_dos ()
+INIT_GDB_FILE (ser_dos)
{
serial_add_interface (&dos_ops);
diff --git a/gdb/ser-mingw.c b/gdb/ser-mingw.c
index db733c3..086919a 100644
--- a/gdb/ser-mingw.c
+++ b/gdb/ser-mingw.c
@@ -1338,9 +1338,7 @@ static const struct serial_ops tcp_ops =
net_windows_done_wait_handle
};
-void _initialize_ser_windows ();
-void
-_initialize_ser_windows ()
+INIT_GDB_FILE (ser_windows)
{
WSADATA wsa_data;
diff --git a/gdb/ser-pipe.c b/gdb/ser-pipe.c
index 16f7419..bdf3602 100644
--- a/gdb/ser-pipe.c
+++ b/gdb/ser-pipe.c
@@ -236,9 +236,7 @@ static const struct serial_ops pipe_ops =
ser_unix_write_prim
};
-void _initialize_ser_pipe ();
-void
-_initialize_ser_pipe ()
+INIT_GDB_FILE (ser_pipe)
{
serial_add_interface (&pipe_ops);
}
diff --git a/gdb/ser-tcp.c b/gdb/ser-tcp.c
index 122b913..589b23d 100644
--- a/gdb/ser-tcp.c
+++ b/gdb/ser-tcp.c
@@ -465,9 +465,7 @@ static const struct serial_ops tcp_ops =
#endif /* USE_WIN32API */
-void _initialize_ser_tcp ();
-void
-_initialize_ser_tcp ()
+INIT_GDB_FILE (ser_tcp)
{
#ifdef USE_WIN32API
/* Do nothing; the TCP serial operations will be initialized in
diff --git a/gdb/ser-uds.c b/gdb/ser-uds.c
index 64e1599..2a45a90 100644
--- a/gdb/ser-uds.c
+++ b/gdb/ser-uds.c
@@ -110,9 +110,7 @@ static const struct serial_ops uds_ops =
uds_write_prim
};
-void _initialize_ser_socket ();
-void
-_initialize_ser_socket ()
+INIT_GDB_FILE (ser_socket)
{
serial_add_interface (&uds_ops);
}
diff --git a/gdb/ser-unix.c b/gdb/ser-unix.c
index cb803a5..553220e 100644
--- a/gdb/ser-unix.c
+++ b/gdb/ser-unix.c
@@ -30,9 +30,33 @@
#include "gdbsupport/gdb_select.h"
#include "cli/cli-cmds.h"
#include "gdbsupport/filestuff.h"
-#include <termios.h>
+
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+
+#if HAVE_IOKIT_SERIAL_IOSS_H
+# include <IOKit/serial/ioss.h>
+#endif
+
+#if HAVE_ASM_TERMIOS_H
+/* Workaround to resolve conflicting declarations of termios
+ in <asm/termbits.h> and <termios.h>. */
+# define termios asmtermios
+# include <asm/termbits.h>
+# undef termios
+#endif
+
+#ifdef HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
#include "gdbsupport/scoped_ignore_sigttou.h"
+#if defined(HAVE_SYS_IOCTL_H) && (defined(BOTHER) || defined(IOSSIOSPEED))
+# define HAVE_CUSTOM_BAUDRATE_SUPPORT 1
+#endif
+
struct hardwire_ttystate
{
struct termios termios;
@@ -289,14 +313,32 @@ baudtab[] =
4800, B4800
}
,
+#ifdef B7200
+ {
+ 7200, B7200
+ }
+ ,
+#endif
{
9600, B9600
}
,
+#ifdef B14400
+ {
+ 14400, B14400
+ }
+ ,
+#endif
{
19200, B19200
}
,
+#ifdef B28800
+ {
+ 28800, B28800
+ }
+ ,
+#endif
{
38400, B38400
}
@@ -307,6 +349,12 @@ baudtab[] =
}
,
#endif
+#ifdef B76800
+ {
+ 76800, B76800
+ }
+ ,
+#endif
#ifdef B115200
{
115200, B115200
@@ -412,6 +460,7 @@ rate_to_code (int rate)
/* check if it is in between valid values. */
if (rate < baudtab[i].rate)
{
+#if !HAVE_CUSTOM_BAUDRATE_SUPPORT
if (i)
{
error (_("Invalid baud rate %d. "
@@ -423,29 +472,126 @@ rate_to_code (int rate)
error (_("Invalid baud rate %d. Minimum value is %d."),
rate, baudtab[0].rate);
}
+#else
+ return -1;
+#endif
}
}
}
-
+
+#if !HAVE_CUSTOM_BAUDRATE_SUPPORT
/* The requested speed was too large. */
error (_("Invalid baud rate %d. Maximum value is %d."),
rate, baudtab[i - 1].rate);
+#else
+ return -1;
+#endif
}
+/* Set baud rate using B_code from termios.h. */
+
static void
-hardwire_setbaudrate (struct serial *scb, int rate)
+set_baudcode_baudrate (struct serial *scb, int baud_code)
{
struct hardwire_ttystate state;
- int baud_code = rate_to_code (rate);
-
+
if (get_tty_state (scb, &state))
- perror_with_name ("could not get tty state");
+ perror_with_name (_("could not get tty state"));
cfsetospeed (&state.termios, baud_code);
cfsetispeed (&state.termios, baud_code);
if (set_tty_state (scb, &state))
- perror_with_name ("could not set tty state");
+ perror_with_name (_("could not set tty state"));
+}
+
+#if HAVE_CUSTOM_BAUDRATE_SUPPORT && defined(BOTHER)
+
+/* Set a custom baud rate using the termios BOTHER. */
+
+static void
+set_custom_baudrate_linux (int fd, int rate)
+{
+#ifdef TCGETS2
+ struct termios2 tio;
+ const unsigned long req_get = TCGETS2;
+ const unsigned long req_set = TCSETS2;
+#else
+ struct termios tio;
+ const unsigned long req_get = TCGETS;
+ const unsigned long req_set = TCSETS;
+#endif
+
+ if (ioctl (fd, req_get, &tio) < 0)
+ perror_with_name (_("Can not get current baud rate"));
+
+ /* Clear the current output baud rate and fill a new value. */
+ tio.c_cflag &= ~CBAUD;
+ tio.c_cflag |= BOTHER;
+ tio.c_ospeed = rate;
+
+ /* Clear the current input baud rate and fill a new value. */
+ tio.c_cflag &= ~(CBAUD << IBSHIFT);
+ tio.c_cflag |= BOTHER << IBSHIFT;
+ tio.c_ispeed = rate;
+
+ if (ioctl (fd, req_set, &tio) < 0)
+ perror_with_name (_("Can not set custom baud rate"));
+}
+
+#elif HAVE_CUSTOM_BAUDRATE_SUPPORT && defined(IOSSIOSPEED)
+
+/* Set a custom baud rate using the IOSSIOSPEED ioctl call. */
+
+static void
+set_custom_baudrate_darwin (int fd, int rate)
+{
+
+ if (ioctl (fd, IOSSIOSPEED, &rate) < 0)
+ perror_with_name (_("Can not set custom baud rate"));
+}
+
+#endif /* HAVE_CUSTOM_BAUDRATE_SUPPORT
+ && (defined(BOTHER) || defined(IOSSIOSPEED)) */
+
+#if HAVE_CUSTOM_BAUDRATE_SUPPORT
+
+/* Set a baud rate that differs from the OS B_codes.
+ This is possible if one of the following macros is available:
+ - BOTHER (Linux).
+ - IOSSIOSPEED (Darwin). */
+
+static void
+set_custom_baudrate (int fd, int rate)
+{
+#if defined(BOTHER)
+ set_custom_baudrate_linux (fd, rate);
+#elif defined(IOSSIOSPEED)
+ set_custom_baudrate_darwin (fd, rate);
+#endif
+}
+
+#endif /* HAVE_CUSTOM_BAUDRATE_SUPPORT */
+
+/* Set the baud rate for the serial communication. */
+
+static void
+hardwire_setbaudrate (struct serial *scb, int rate)
+{
+ int baud_code = rate_to_code (rate);
+
+ if (baud_code < 0)
+ {
+#if HAVE_CUSTOM_BAUDRATE_SUPPORT
+ set_custom_baudrate (scb->fd, rate);
+#else
+ /* An error should already have been thrown by rate_to_code().
+ Add an additional error in case execution somehow reaches this line. */
+ gdb_assert_not_reached ("Serial baud rate was not found in B_codes");
+#endif
+ }
+ else
+ set_baudcode_baudrate (scb, baud_code);
}
static int
@@ -551,9 +697,7 @@ static const struct serial_ops hardwire_ops =
ser_unix_write_prim
};
-void _initialize_ser_hardwire ();
-void
-_initialize_ser_hardwire ()
+INIT_GDB_FILE (ser_hardwire)
{
serial_add_interface (&hardwire_ops);
diff --git a/gdb/serial.c b/gdb/serial.c
index bab8480..d66c637 100644
--- a/gdb/serial.c
+++ b/gdb/serial.c
@@ -642,9 +642,7 @@ set_parity (const char *ignore_args, int from_tty, struct cmd_list_element *c)
serial_parity = GDBPARITY_NONE;
}
-void _initialize_serial ();
-void
-_initialize_serial ()
+INIT_GDB_FILE (serial)
{
#if 0
add_com ("connect", class_obscure, connect_command, _("\
diff --git a/gdb/sh-linux-tdep.c b/gdb/sh-linux-tdep.c
index f0b35d3..2578192 100644
--- a/gdb/sh-linux-tdep.c
+++ b/gdb/sh-linux-tdep.c
@@ -28,6 +28,7 @@
#include "glibc-tdep.h"
#include "sh-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "gdbarch.h"
#define REGSx16(base) \
@@ -187,8 +188,7 @@ sh_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* GNU/Linux uses SVR4-style shared libraries. */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
set_gdbarch_fetch_tls_load_module_address (gdbarch,
@@ -207,9 +207,7 @@ sh_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tramp_frame_prepend_unwinder (gdbarch, &sh_linux_rt_sigreturn_tramp_frame);
}
-void _initialize_sh_linux_tdep ();
-void
-_initialize_sh_linux_tdep ()
+INIT_GDB_FILE (sh_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_LINUX, sh_linux_init_abi);
}
diff --git a/gdb/sh-netbsd-nat.c b/gdb/sh-netbsd-nat.c
index 25aafe1..d36dba5 100644
--- a/gdb/sh-netbsd-nat.c
+++ b/gdb/sh-netbsd-nat.c
@@ -98,9 +98,7 @@ sh_nbsd_nat_target::store_registers (struct regcache *regcache, int regno)
}
}
-void _initialize_shnbsd_nat ();
-void
-_initialize_shnbsd_nat ()
+INIT_GDB_FILE (shnbsd_nat)
{
add_inf_child_target (&the_sh_nbsd_nat_target);
}
diff --git a/gdb/sh-netbsd-tdep.c b/gdb/sh-netbsd-tdep.c
index f99566f..4b0181b 100644
--- a/gdb/sh-netbsd-tdep.c
+++ b/gdb/sh-netbsd-tdep.c
@@ -68,13 +68,10 @@ shnbsd_init_abi (struct gdbarch_info info,
tdep->core_gregmap = (struct sh_corefile_regmap *)regmap;
tdep->sizeof_gregset = 84;
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
}
-void _initialize_shnbsd_tdep ();
-void
-_initialize_shnbsd_tdep ()
+INIT_GDB_FILE (shnbsd_tdep)
{
gdbarch_register_osabi (bfd_arch_sh, 0, GDB_OSABI_NETBSD,
shnbsd_init_abi);
diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
index 59a67bf..6bd4fd3 100644
--- a/gdb/sh-tdep.c
+++ b/gdb/sh-tdep.c
@@ -2394,9 +2394,7 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
return gdbarch;
}
-void _initialize_sh_tdep ();
-void
-_initialize_sh_tdep ()
+INIT_GDB_FILE (sh_tdep)
{
gdbarch_register (bfd_arch_sh, sh_gdbarch_init, NULL);
diff --git a/gdb/skip.c b/gdb/skip.c
index a077241..a9ee223 100644
--- a/gdb/skip.c
+++ b/gdb/skip.c
@@ -657,9 +657,7 @@ complete_skip_number (cmd_list_element *cmd,
}
}
-void _initialize_step_skip ();
-void
-_initialize_step_skip ()
+INIT_GDB_FILE (step_skip)
{
static struct cmd_list_element *skiplist = NULL;
struct cmd_list_element *c;
diff --git a/gdb/sol-thread.c b/gdb/sol-thread.c
index ae1e5c0..55e1d3e 100644
--- a/gdb/sol-thread.c
+++ b/gdb/sol-thread.c
@@ -1111,19 +1111,21 @@ info_solthreads (const char *args, int from_tty)
ptid_t
sol_thread_target::get_ada_task_ptid (long lwp, ULONGEST thread)
{
- struct thread_info *thread_info
- = iterate_over_threads ([&] (struct thread_info *thread)
+ auto thread_db_find_thread_from_tid
+ = [&] (struct thread_info *iter)
{
- return thread->ptid.tid () == thread;
- });
+ return iter->ptid.tid () == thread;
+ };
+
+ struct thread_info *thread_info
+ = iterate_over_threads (thread_db_find_thread_from_tid);
if (thread_info == NULL)
{
/* The list of threads is probably not up to date. Find any
thread that is missing from the list, and try again. */
update_thread_list ();
- thread_info = iterate_over_threads (thread_db_find_thread_from_tid,
- &thread);
+ thread_info = iterate_over_threads (thread_db_find_thread_from_tid);
}
gdb_assert (thread_info != NULL);
@@ -1131,9 +1133,7 @@ sol_thread_target::get_ada_task_ptid (long lwp, ULONGEST thread)
return (thread_info->ptid);
}
-void _initialize_sol_thread ();
-void
-_initialize_sol_thread ()
+INIT_GDB_FILE (sol_thread)
{
void *dlhandle;
diff --git a/gdb/solib-aix.c b/gdb/solib-aix.c
index 0ad25f1..b246df8 100644
--- a/gdb/solib-aix.c
+++ b/gdb/solib-aix.c
@@ -17,7 +17,6 @@
#include "solib-aix.h"
#include "solib.h"
-#include "solist.h"
#include "inferior.h"
#include "gdb_bfd.h"
#include "objfiles.h"
@@ -25,6 +24,24 @@
#include "xcoffread.h"
#include "observable.h"
+/* solib_ops for AIX systems. */
+
+struct aix_solib_ops : public solib_ops
+{
+ void relocate_section_addresses (solib &so, target_section *) const override;
+ void create_inferior_hook (int from_tty) const override;
+ owning_intrusive_list<solib> current_sos () const override;
+ gdb_bfd_ref_ptr bfd_open (const char *pathname) const override;
+};
+
+/* See solib-aix.h. */
+
+solib_ops_up
+make_aix_solib_ops ()
+{
+ return std::make_unique<aix_solib_ops> ();
+}
+
/* Our private data in struct solib. */
struct lm_info_aix final : public lm_info
@@ -307,10 +324,9 @@ solib_aix_bss_data_overlap (bfd *abfd)
return 0;
}
-/* Implement the "relocate_section_addresses" solib_ops method. */
-
-static void
-solib_aix_relocate_section_addresses (solib &so, target_section *sec)
+void
+aix_solib_ops::relocate_section_addresses (solib &so,
+ target_section *sec) const
{
struct bfd_section *bfd_sect = sec->the_bfd_section;
bfd *abfd = bfd_sect->owner;
@@ -411,10 +427,8 @@ solib_aix_get_section_offsets (struct objfile *objfile,
return offsets;
}
-/* Implement the "solib_create_inferior_hook" solib_ops method. */
-
-static void
-solib_aix_solib_create_inferior_hook (int from_tty)
+void
+aix_solib_ops::create_inferior_hook (int from_tty) const
{
const char *warning_msg = "unable to relocate main executable";
@@ -442,10 +456,8 @@ solib_aix_solib_create_inferior_hook (int from_tty)
}
}
-/* Implement the "current_sos" solib_ops method. */
-
-static owning_intrusive_list<solib>
-solib_aix_current_sos ()
+owning_intrusive_list<solib>
+aix_solib_ops::current_sos () const
{
std::optional<std::vector<lm_info_aix>> &library_list
= solib_aix_get_library_list (current_inferior (), NULL);
@@ -481,35 +493,17 @@ solib_aix_current_sos ()
}
/* Add it to the list. */
- auto &new_solib = sos.emplace_back ();
- new_solib.so_original_name = so_name;
- new_solib.so_name = so_name;
+ auto &new_solib = sos.emplace_back (*this);
+ new_solib.original_name = so_name;
+ new_solib.name = so_name;
new_solib.lm_info = std::make_unique<lm_info_aix> (info);
}
return sos;
}
-/* Implement the "open_symbol_file_object" solib_ops method. */
-
-static int
-solib_aix_open_symbol_file_object (int from_tty)
-{
- return 0;
-}
-
-/* Implement the "in_dynsym_resolve_code" solib_ops method. */
-
-static int
-solib_aix_in_dynsym_resolve_code (CORE_ADDR pc)
-{
- return 0;
-}
-
-/* Implement the "bfd_open" solib_ops method. */
-
-static gdb_bfd_ref_ptr
-solib_aix_bfd_open (const char *pathname)
+gdb_bfd_ref_ptr
+aix_solib_ops::bfd_open (const char *pathname) const
{
/* The pathname is actually a synthetic filename with the following
form: "/path/to/sharedlib(member.o)" (double-quotes excluded).
@@ -523,7 +517,7 @@ solib_aix_bfd_open (const char *pathname)
int found_file;
if (pathname[path_len - 1] != ')')
- return solib_bfd_open (pathname);
+ return solib_ops::bfd_open (pathname);
/* Search for the associated parens. */
sep = strrchr (pathname, '(');
@@ -533,7 +527,7 @@ solib_aix_bfd_open (const char *pathname)
to open pathname without decoding, possibly leading to
a failure), rather than triggering an assert failure). */
warning (_("missing '(' in shared object pathname: %s"), pathname);
- return solib_bfd_open (pathname);
+ return solib_ops::bfd_open (pathname);
}
filename_len = sep - pathname;
@@ -676,27 +670,7 @@ solib_aix_normal_stop_observer (struct bpstat *unused_1, int unused_2)
data->library_list.reset ();
}
-/* The solib_ops for AIX targets. */
-const solib_ops solib_aix_so_ops =
-{
- solib_aix_relocate_section_addresses,
- nullptr,
- nullptr,
- solib_aix_solib_create_inferior_hook,
- solib_aix_current_sos,
- 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 ();
-void
-_initialize_solib_aix ()
+INIT_GDB_FILE (solib_aix)
{
gdb::observers::normal_stop.attach (solib_aix_normal_stop_observer,
"solib-aix");
diff --git a/gdb/solib-aix.h b/gdb/solib-aix.h
index 7a1bc7b..628b7c8 100644
--- a/gdb/solib-aix.h
+++ b/gdb/solib-aix.h
@@ -18,9 +18,12 @@
#ifndef GDB_SOLIB_AIX_H
#define GDB_SOLIB_AIX_H
-struct solib_ops;
-extern const solib_ops solib_aix_so_ops;
+#include "solib.h"
extern CORE_ADDR solib_aix_get_toc_value (CORE_ADDR pc);
+/* Return a new solib_ops for AIX systems. */
+
+solib_ops_up make_aix_solib_ops ();
+
#endif /* GDB_SOLIB_AIX_H */
diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c
index 368f401..aac8ab2 100644
--- a/gdb/solib-darwin.c
+++ b/gdb/solib-darwin.c
@@ -27,12 +27,31 @@
#include "regcache.h"
#include "gdb_bfd.h"
-#include "solist.h"
+#include "solib.h"
#include "solib-darwin.h"
#include "mach-o.h"
#include "mach-o/external.h"
+/* solib_ops for Darwin systems. */
+
+struct darwin_solib_ops : public solib_ops
+{
+ void relocate_section_addresses (solib &so, target_section *) const override;
+ void clear_solib (program_space *pspace) const override;
+ void create_inferior_hook (int from_tty) const override;
+ owning_intrusive_list<solib> current_sos () const override;
+ gdb_bfd_ref_ptr bfd_open (const char *pathname) const override;
+};
+
+/* See solib-darwin.h. */
+
+solib_ops_up
+make_darwin_solib_ops ()
+{
+ return std::make_unique<darwin_solib_ops> ();
+}
+
struct gdb_dyld_image_info
{
/* Base address (which corresponds to the Mach-O header). */
@@ -133,7 +152,7 @@ darwin_load_image_infos (struct darwin_info *info)
(buf + 8 + ptr_type->length (), ptr_type);
}
-/* Link map info to include in an allocated so_list entry. */
+/* Link map info to include in an allocated solib entry. */
struct lm_info_darwin final : public lm_info
{
@@ -188,20 +207,8 @@ find_program_interpreter (void)
return buf;
}
-/* Not used. I don't see how the main symbol file can be found: the
- interpreter name is needed and it is known from the executable file.
- Note that darwin-nat.c implements pid_to_exec_file. */
-
-static int
-open_symbol_file_object (int from_tty)
-{
- return 0;
-}
-
-/* Build a list of currently loaded shared objects. See solib-svr4.c. */
-
-static owning_intrusive_list<solib>
-darwin_current_sos ()
+owning_intrusive_list<solib>
+darwin_solib_ops::current_sos () const
{
type *ptr_type
= builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
@@ -260,12 +267,12 @@ darwin_current_sos ()
break;
/* Create and fill the new struct solib element. */
- auto &newobj = sos.emplace_back ();
+ auto &newobj = sos.emplace_back (*this);
auto li = std::make_unique<lm_info_darwin> ();
- newobj.so_name = file_path.get ();
- newobj.so_original_name = newobj.so_name;
+ newobj.name = file_path.get ();
+ newobj.original_name = newobj.name;
li->lm_addr = load_addr;
newobj.lm_info = std::move (li);
@@ -363,15 +370,6 @@ darwin_read_exec_load_addr_at_init (struct darwin_info *info)
return darwin_validate_exec_header (load_addr);
}
-/* Return 1 if PC lies in the dynamic symbol resolution code of the
- run time loader. */
-
-static int
-darwin_in_dynsym_resolve_code (CORE_ADDR pc)
-{
- return 0;
-}
-
/* A wrapper for bfd_mach_o_fat_extract that handles reference
counting properly. This will either return NULL, or return a new
reference to a BFD. */
@@ -476,10 +474,8 @@ darwin_solib_read_all_image_info_addr (struct darwin_info *info)
info->all_image_addr = extract_unsigned_integer (buf, len, BFD_ENDIAN_BIG);
}
-/* Shared library startup support. See documentation in solib-svr4.c. */
-
-static void
-darwin_solib_create_inferior_hook (int from_tty)
+void
+darwin_solib_ops::create_inferior_hook (int from_tty) const
{
/* Everything below only makes sense if we have a running inferior. */
if (!target_has_execution ())
@@ -579,8 +575,8 @@ darwin_solib_create_inferior_hook (int from_tty)
create_solib_event_breakpoint (current_inferior ()->arch (), notifier);
}
-static void
-darwin_clear_solib (program_space *pspace)
+void
+darwin_solib_ops::clear_solib (program_space *pspace) const
{
darwin_info *info = get_darwin_info (pspace);
@@ -591,8 +587,9 @@ darwin_clear_solib (program_space *pspace)
/* The section table is built from bfd sections using bfd VMAs.
Relocate these VMAs according to solib info. */
-static void
-darwin_relocate_section_addresses (solib &so, target_section *sec)
+void
+darwin_solib_ops::relocate_section_addresses (solib &so,
+ target_section *sec) const
{
auto *li = gdb::checked_static_cast<lm_info_darwin *> (so.lm_info.get ());
@@ -611,9 +608,9 @@ darwin_relocate_section_addresses (solib &so, target_section *sec)
if (sec->addr < so.addr_low)
so.addr_low = sec->addr;
}
-
-static gdb_bfd_ref_ptr
-darwin_bfd_open (const char *pathname)
+
+gdb_bfd_ref_ptr
+darwin_solib_ops::bfd_open (const char *pathname) const
{
int found_file;
@@ -641,20 +638,3 @@ darwin_bfd_open (const char *pathname)
return res;
}
-
-const solib_ops darwin_so_ops =
-{
- darwin_relocate_section_addresses,
- nullptr,
- darwin_clear_solib,
- darwin_solib_create_inferior_hook,
- darwin_current_sos,
- 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-darwin.h b/gdb/solib-darwin.h
index b96e744..f5bcdd1 100644
--- a/gdb/solib-darwin.h
+++ b/gdb/solib-darwin.h
@@ -20,8 +20,10 @@
#ifndef GDB_SOLIB_DARWIN_H
#define GDB_SOLIB_DARWIN_H
-struct solib_ops;
+#include "solib.h"
-extern const solib_ops darwin_so_ops;
+/* Return a new solib_ops for Darwin systems. */
+
+extern solib_ops_up make_darwin_solib_ops ();
#endif /* GDB_SOLIB_DARWIN_H */
diff --git a/gdb/solib-dsbt.c b/gdb/solib-dsbt.c
index 3832a7a..f18d9a2 100644
--- a/gdb/solib-dsbt.c
+++ b/gdb/solib-dsbt.c
@@ -21,7 +21,6 @@
#include "inferior.h"
#include "gdbcore.h"
#include "solib.h"
-#include "solist.h"
#include "objfiles.h"
#include "symtab.h"
#include "command.h"
@@ -121,7 +120,26 @@ struct dbst_ext_link_map
ext_ptr l_next, l_prev; /* struct link_map *l_next, *l_prev; */
};
-/* Link map info to include in an allocated so_list entry */
+/* solib_ops for DSBT systems. */
+
+struct dsbt_solib_ops : public solib_ops
+{
+ void relocate_section_addresses (solib &so, target_section *) const override;
+ void clear_solib (program_space *pspace) const override;
+ void create_inferior_hook (int from_tty) const override;
+ owning_intrusive_list<solib> current_sos () const override;
+ bool in_dynsym_resolve_code (CORE_ADDR pc) const override;
+};
+
+/* See solib-dsbt.h. */
+
+solib_ops_up
+make_dsbt_solib_ops ()
+{
+ return std::make_unique<dsbt_solib_ops> ();
+}
+
+/* Link map info to include in an allocated solib entry */
struct lm_info_dsbt final : public lm_info
{
@@ -393,15 +411,6 @@ fetch_loadmap (CORE_ADDR ldmaddr)
static void dsbt_relocate_main_executable (void);
static int enable_break (void);
-/* See solist.h. */
-
-static int
-open_symbol_file_object (int from_tty)
-{
- /* Unimplemented. */
- return 0;
-}
-
/* Given a loadmap and an address, return the displacement needed
to relocate the address. */
@@ -512,8 +521,8 @@ lm_base (void)
themselves. The declaration of `struct solib' says which fields
we provide values for. */
-static owning_intrusive_list<solib>
-dsbt_current_sos (void)
+owning_intrusive_list<solib>
+dsbt_solib_ops::current_sos () const
{
bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
CORE_ADDR lm_addr;
@@ -594,7 +603,7 @@ dsbt_current_sos (void)
break;
}
- auto &sop = sos.emplace_back ();
+ auto &sop = sos.emplace_back (*this);
auto li = std::make_unique<lm_info_dsbt> ();
li->map = loadmap;
/* Fetch the name. */
@@ -612,8 +621,8 @@ dsbt_current_sos (void)
gdb_printf (gdb_stdlog, "current_sos: name = %s\n",
name_buf.get ());
- sop.so_name = name_buf.get ();
- sop.so_original_name = sop.so_name;
+ sop.name = name_buf.get ();
+ sop.original_name = sop.name;
}
sop.lm_info = std::move (li);
@@ -630,11 +639,11 @@ dsbt_current_sos (void)
return sos;
}
-/* Return 1 if PC lies in the dynamic symbol resolution code of the
+/* Return true if PC lies in the dynamic symbol resolution code of the
run time loader. */
-static int
-dsbt_in_dynsym_resolve_code (CORE_ADDR pc)
+bool
+dsbt_solib_ops::in_dynsym_resolve_code (CORE_ADDR pc) const
{
dsbt_info *info = get_dsbt_info (current_program_space);
@@ -850,8 +859,8 @@ dsbt_relocate_main_executable (void)
For the DSBT shared library, the main executable needs to be relocated.
The shared library breakpoints also need to be enabled. */
-static void
-dsbt_solib_create_inferior_hook (int from_tty)
+void
+dsbt_solib_ops::create_inferior_hook (int from_tty) const
{
/* Relocate main executable. */
dsbt_relocate_main_executable ();
@@ -864,8 +873,8 @@ dsbt_solib_create_inferior_hook (int from_tty)
}
}
-static void
-dsbt_clear_solib (program_space *pspace)
+void
+dsbt_solib_ops::clear_solib (program_space *pspace) const
{
dsbt_info *info = get_dsbt_info (pspace);
@@ -876,8 +885,9 @@ dsbt_clear_solib (program_space *pspace)
info->main_executable_lm_info = NULL;
}
-static void
-dsbt_relocate_section_addresses (solib &so, target_section *sec)
+void
+dsbt_solib_ops::relocate_section_addresses (solib &so,
+ target_section *sec) const
{
int seg;
auto *li = gdb::checked_static_cast<lm_info_dsbt *> (so.lm_info.get ());
@@ -903,26 +913,7 @@ show_dsbt_debug (struct ui_file *file, int from_tty,
gdb_printf (file, _("solib-dsbt debugging is %s.\n"), value);
}
-const solib_ops dsbt_so_ops =
-{
- dsbt_relocate_section_addresses,
- nullptr,
- dsbt_clear_solib,
- dsbt_solib_create_inferior_hook,
- dsbt_current_sos,
- open_symbol_file_object,
- dsbt_in_dynsym_resolve_code,
- solib_bfd_open,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- default_find_solib_addr,
-};
-
-void _initialize_dsbt_solib ();
-void
-_initialize_dsbt_solib ()
+INIT_GDB_FILE (dsbt_solib)
{
/* Debug this file's internals. */
add_setshow_zuinteger_cmd ("solib-dsbt", class_maintenance,
diff --git a/gdb/solib-dsbt.h b/gdb/solib-dsbt.h
index d5c52c6..d44613c 100644
--- a/gdb/solib-dsbt.h
+++ b/gdb/solib-dsbt.h
@@ -20,8 +20,10 @@
#ifndef GDB_SOLIB_DSBT_H
#define GDB_SOLIB_DSBT_H
-struct solib_ops;
+#include "solib.h"
-extern const solib_ops dsbt_so_ops;
+/* Return a new solib_ops for DSBT systems. */
+
+solib_ops_up make_dsbt_solib_ops ();
#endif /* GDB_SOLIB_DSBT_H */
diff --git a/gdb/solib-frv.c b/gdb/solib-frv.c
index bf13d36..6165d0b 100644
--- a/gdb/solib-frv.c
+++ b/gdb/solib-frv.c
@@ -20,13 +20,32 @@
#include "extract-store-integer.h"
#include "gdbcore.h"
#include "solib.h"
-#include "solist.h"
#include "frv-tdep.h"
#include "objfiles.h"
#include "symtab.h"
#include "elf/frv.h"
#include "gdb_bfd.h"
#include "inferior.h"
+#include "solib-frv.h"
+
+/* solib_ops for FR-V systems. */
+
+struct frv_solib_ops : public solib_ops
+{
+ void relocate_section_addresses (solib &so, target_section *) const override;
+ void clear_solib (program_space *pspace) const override;
+ void create_inferior_hook (int from_tty) const override;
+ owning_intrusive_list<solib> current_sos () const override;
+ bool in_dynsym_resolve_code (CORE_ADDR pc) const override;
+};
+
+/* See solib-frv.h. */
+
+solib_ops_up
+make_frv_solib_ops ()
+{
+ return std::make_unique<frv_solib_ops> ();
+}
/* FR-V pointers are four bytes wide. */
enum { FRV_PTR_SIZE = 4 };
@@ -194,7 +213,7 @@ struct ext_link_map
ext_ptr l_next, l_prev; /* struct link_map *l_next, *l_prev; */
};
-/* Link map info to include in an allocated so_list entry. */
+/* Link map info to include in an allocated solib entry. */
struct lm_info_frv final : public lm_info
{
@@ -237,15 +256,6 @@ static void frv_relocate_main_executable (void);
static CORE_ADDR main_got (void);
static int enable_break2 (void);
-/* Implement the "open_symbol_file_object" solib_ops method. */
-
-static int
-open_symbol_file_object (int from_tty)
-{
- /* Unimplemented. */
- return 0;
-}
-
/* Cached value for lm_base(), below. */
static CORE_ADDR lm_base_cache = 0;
@@ -303,11 +313,8 @@ lm_base (void)
return lm_base_cache;
}
-
-/* Implement the "current_sos" solib_ops method. */
-
-static owning_intrusive_list<solib>
-frv_current_sos ()
+owning_intrusive_list<solib>
+frv_solib_ops::current_sos () const
{
bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
CORE_ADDR lm_addr, mgot;
@@ -377,7 +384,7 @@ frv_current_sos ()
break;
}
- auto &sop = sos.emplace_back ();
+ auto &sop = sos.emplace_back (*this);
auto li = std::make_unique<lm_info_frv> ();
li->map = loadmap;
li->got_value = got_addr;
@@ -397,8 +404,8 @@ frv_current_sos ()
warning (_("Can't read pathname for link map entry."));
else
{
- sop.so_name = name_buf.get ();
- sop.so_original_name = sop.so_name;
+ sop.name = name_buf.get ();
+ sop.original_name = sop.name;
}
}
else
@@ -424,8 +431,8 @@ static CORE_ADDR interp_text_sect_high;
static CORE_ADDR interp_plt_sect_low;
static CORE_ADDR interp_plt_sect_high;
-static int
-frv_in_dynsym_resolve_code (CORE_ADDR pc)
+bool
+frv_solib_ops::in_dynsym_resolve_code (CORE_ADDR pc) const
{
return ((pc >= interp_text_sect_low && pc < interp_text_sect_high)
|| (pc >= interp_plt_sect_low && pc < interp_plt_sect_high)
@@ -786,8 +793,8 @@ frv_relocate_main_executable (void)
to be relocated. The shared library breakpoints also need to be
enabled. */
-static void
-frv_solib_create_inferior_hook (int from_tty)
+void
+frv_solib_ops::create_inferior_hook (int from_tty) const
{
/* Relocate main executable. */
frv_relocate_main_executable ();
@@ -800,8 +807,8 @@ frv_solib_create_inferior_hook (int from_tty)
}
}
-static void
-frv_clear_solib (program_space *pspace)
+void
+frv_solib_ops::clear_solib (program_space *pspace) const
{
lm_base_cache = 0;
enable_break2_done = 0;
@@ -811,8 +818,9 @@ frv_clear_solib (program_space *pspace)
main_executable_lm_info = NULL;
}
-static void
-frv_relocate_section_addresses (solib &so, target_section *sec)
+void
+frv_solib_ops::relocate_section_addresses (solib &so,
+ target_section *sec) const
{
int seg;
auto *li = gdb::checked_static_cast<lm_info_frv *> (so.lm_info.get ());
@@ -1073,20 +1081,3 @@ frv_fetch_objfile_link_map (struct objfile *objfile)
/* Not found! */
return 0;
}
-
-const solib_ops frv_so_ops =
-{
- frv_relocate_section_addresses,
- nullptr,
- frv_clear_solib,
- frv_solib_create_inferior_hook,
- frv_current_sos,
- 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-frv.h b/gdb/solib-frv.h
new file mode 100644
index 0000000..710a424
--- /dev/null
+++ b/gdb/solib-frv.h
@@ -0,0 +1,28 @@
+/* Handle FR-V (FDPIC) shared libraries for GDB, the GNU Debugger.
+ Copyright (C) 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef GDB_SOLIB_FRV_H
+#define GDB_SOLIB_FRV_H
+
+#include "solib.h"
+
+/* Return a new solib_ops for FR-V systems. */
+
+solib_ops_up make_frv_solib_ops ();
+
+#endif /* GDB_SOLIB_FRV_H */
diff --git a/gdb/solib-rocm.c b/gdb/solib-rocm.c
index 27b404c..2d26c3c 100644
--- a/gdb/solib-rocm.c
+++ b/gdb/solib-rocm.c
@@ -26,10 +26,10 @@
#include "event-top.h"
#include "gdbsupport/fileio.h"
#include "inferior.h"
+#include "linux-tdep.h"
#include "observable.h"
#include "solib.h"
#include "solib-svr4.h"
-#include "solist.h"
#include "symfile.h"
#include <unordered_map>
@@ -154,7 +154,69 @@ struct solib_info
/* Per-inferior data key. */
static const registry<inferior>::key<solib_info> rocm_solib_data;
-static solib_ops rocm_solib_ops;
+/* solib_ops for ROCm systems. */
+
+struct rocm_solib_ops : public solib_ops
+{
+ /* HOST_OPS is the host solib_ops that rocm_solib_ops hijacks / wraps,
+ in order to provide support for ROCm code objects. */
+ explicit rocm_solib_ops (solib_ops_up host_ops)
+ : m_host_ops (std::move (host_ops))
+ {
+ }
+
+ /* The methods implemented by rocm_solib_ops. */
+ owning_intrusive_list<solib> current_sos () const override;
+ void create_inferior_hook (int from_tty) const override;
+ gdb_bfd_ref_ptr bfd_open (const char *pathname) const override;
+ void relocate_section_addresses (solib &so, target_section *) const override;
+ void handle_event () const override;
+
+ /* Implement the following methods just to forward the calls to the host
+ solib_ops. We currently need to implement all the methods that
+ svr4_solib_ops implements. */
+ void clear_so (const solib &so) const override
+ { return m_host_ops->clear_so (so); }
+
+ void clear_solib (program_space *pspace) const override
+ { return m_host_ops->clear_solib (pspace); }
+
+ bool open_symbol_file_object (int from_tty) const override
+ { return m_host_ops->open_symbol_file_object (from_tty); }
+
+ bool in_dynsym_resolve_code (CORE_ADDR pc) const override
+ { return m_host_ops->in_dynsym_resolve_code (pc); }
+
+ bool same (const solib &gdb, const solib &inferior) const override
+ { return m_host_ops->same (gdb, inferior); }
+
+ bool keep_data_in_core (CORE_ADDR vaddr, unsigned long size) const override
+ { return m_host_ops->keep_data_in_core (vaddr, size); }
+
+ void update_breakpoints () const override
+ { return m_host_ops->update_breakpoints (); }
+
+ std::optional<CORE_ADDR> find_solib_addr (solib &so) const override
+ { return m_host_ops->find_solib_addr (so); }
+
+ bool supports_namespaces () const override
+ { return true; }
+
+ int find_solib_ns (const solib &so) const override
+ { return m_host_ops->find_solib_ns (so); }
+
+ int num_active_namespaces () const override
+ { return m_host_ops->num_active_namespaces (); }
+
+ std::vector<const solib *> get_solibs_in_ns (int nsid) const override
+ { return m_host_ops->get_solibs_in_ns (nsid); }
+
+private:
+ owning_intrusive_list<solib>
+ solibs_from_rocm_sos (const std::vector<rocm_so> &sos) const;
+
+ solib_ops_up m_host_ops;
+};
/* Fetch the solib_info data for INF. */
@@ -171,13 +233,13 @@ get_solib_info (inferior *inf)
/* Relocate section addresses. */
-static void
-rocm_solib_relocate_section_addresses (solib &so,
- struct target_section *sec)
+void
+rocm_solib_ops::relocate_section_addresses (solib &so,
+ struct target_section *sec) const
{
if (!is_amdgpu_arch (gdbarch_from_bfd (so.abfd.get ())))
{
- svr4_so_ops.relocate_section_addresses (so, sec);
+ m_host_ops->relocate_section_addresses (so, sec);
return;
}
@@ -188,34 +250,34 @@ rocm_solib_relocate_section_addresses (solib &so,
static void rocm_update_solib_list ();
-static void
-rocm_solib_handle_event ()
+void
+rocm_solib_ops::handle_event () const
{
- /* Since we sit on top of svr4_so_ops, we might get called following an event
- concerning host libraries. We must therefore forward the call. If the
- event was for a ROCm code object, it will be a no-op. On the other hand,
+ /* Since we sit on top of a host solib_ops, we might get called following an
+ event concerning host libraries. We must therefore forward the call. If
+ the event was for a ROCm code object, it will be a no-op. On the other hand
if the event was for host libraries, rocm_update_solib_list will be
essentially be a no-op (it will reload the same code object list as was
previously loaded). */
- svr4_so_ops.handle_event ();
+ m_host_ops->handle_event ();
rocm_update_solib_list ();
}
-/* Create so_list objects from rocm_so objects in SOS. */
+/* Create solib objects from rocm_so objects in SOS. */
-static owning_intrusive_list<solib>
-so_list_from_rocm_sos (const std::vector<rocm_so> &sos)
+owning_intrusive_list<solib>
+rocm_solib_ops::solibs_from_rocm_sos (const std::vector<rocm_so> &sos) const
{
owning_intrusive_list<solib> dst;
for (const rocm_so &so : sos)
{
- auto &newobj = dst.emplace_back ();
+ auto &newobj = dst.emplace_back (*this);
newobj.lm_info = std::make_unique<lm_info_svr4> (*so.lm_info);
- newobj.so_name = so.name;
- newobj.so_original_name = so.unique_name;
+ newobj.name = so.name;
+ newobj.original_name = so.unique_name;
}
return dst;
@@ -224,11 +286,11 @@ so_list_from_rocm_sos (const std::vector<rocm_so> &sos)
/* Build a list of `struct solib' objects describing the shared
objects currently loaded in the inferior. */
-static owning_intrusive_list<solib>
-rocm_solib_current_sos ()
+owning_intrusive_list<solib>
+rocm_solib_ops::current_sos () const
{
/* First, retrieve the host-side shared library list. */
- owning_intrusive_list<solib> sos = svr4_so_ops.current_sos ();
+ owning_intrusive_list<solib> sos = m_host_ops->current_sos ();
/* Then, the device-side shared library list. */
std::vector<rocm_so> &dev_sos = get_solib_info (current_inferior ())->solib_list;
@@ -236,13 +298,13 @@ rocm_solib_current_sos ()
if (dev_sos.empty ())
return sos;
- owning_intrusive_list<solib> dev_so_list = so_list_from_rocm_sos (dev_sos);
+ owning_intrusive_list<solib> dev_solibs = solibs_from_rocm_sos (dev_sos);
if (sos.empty ())
- return dev_so_list;
+ return dev_solibs;
/* Append our libraries to the end of the list. */
- sos.splice (std::move (dev_so_list));
+ sos.splice (std::move (dev_solibs));
return sos;
}
@@ -580,12 +642,12 @@ rocm_bfd_iovec_open (bfd *abfd, inferior *inferior)
}
}
-static gdb_bfd_ref_ptr
-rocm_solib_bfd_open (const char *pathname)
+gdb_bfd_ref_ptr
+rocm_solib_ops::bfd_open (const char *pathname) const
{
/* Handle regular files with SVR4 open. */
if (strstr (pathname, "://") == nullptr)
- return svr4_so_ops.bfd_open (pathname);
+ return m_host_ops->bfd_open (pathname);
auto open = [] (bfd *nbfd) -> gdb_bfd_iovec_base *
{
@@ -669,12 +731,12 @@ rocm_solib_bfd_open (const char *pathname)
return abfd;
}
-static void
-rocm_solib_create_inferior_hook (int from_tty)
+void
+rocm_solib_ops::create_inferior_hook (int from_tty) const
{
get_solib_info (current_inferior ())->solib_list.clear ();
- svr4_so_ops.solib_create_inferior_hook (from_tty);
+ m_host_ops->create_inferior_hook (from_tty);
}
static void
@@ -704,6 +766,9 @@ rocm_update_solib_list ()
return;
}
+ gdb::unique_xmalloc_ptr<amd_dbgapi_code_object_id_t> code_object_list_holder
+ (code_object_list);
+
for (size_t i = 0; i < count; ++i)
{
CORE_ADDR l_addr;
@@ -734,24 +799,6 @@ rocm_update_solib_list ()
sos.emplace_back (uri_bytes, std::move (unique_name), std::move (li));
}
-
- xfree (code_object_list);
-
- if (rocm_solib_ops.current_sos == NULL)
- {
- /* Override what we need to. */
- rocm_solib_ops = svr4_so_ops;
- rocm_solib_ops.current_sos = rocm_solib_current_sos;
- rocm_solib_ops.solib_create_inferior_hook
- = rocm_solib_create_inferior_hook;
- rocm_solib_ops.bfd_open = rocm_solib_bfd_open;
- rocm_solib_ops.relocate_section_addresses
- = rocm_solib_relocate_section_addresses;
- rocm_solib_ops.handle_event = rocm_solib_handle_event;
-
- /* Engage the ROCm so_ops. */
- set_gdbarch_so_ops (current_inferior ()->arch (), &rocm_solib_ops);
- }
}
static void
@@ -759,6 +806,10 @@ rocm_solib_target_inferior_created (inferior *inf)
{
get_solib_info (inf)->solib_list.clear ();
+ auto prev_ops = inf->pspace->release_solib_ops ();
+ auto rocm_ops = std::make_unique<rocm_solib_ops> (std::move (prev_ops));
+ inf->pspace->set_solib_ops (std::move (rocm_ops));
+
rocm_update_solib_list ();
/* Force GDB to reload the solibs. */
@@ -766,11 +817,22 @@ rocm_solib_target_inferior_created (inferior *inf)
solib_add (nullptr, 0, auto_solib_add);
}
-/* -Wmissing-prototypes */
-extern initialize_file_ftype _initialize_rocm_solib;
+static void
+rocm_solib_target_inferior_execd (inferior *exec_inf, inferior *follow_inf)
+{
+ /* Engage the ROCm so_ops, but only if dbgapi is attached to the inferior
+ (avoiding remote inferiors and core file debugging). */
+ if (get_amd_dbgapi_process_id (follow_inf) == AMD_DBGAPI_PROCESS_NONE)
+ return;
+
+ auto prev_ops = follow_inf->pspace->release_solib_ops ();
+ auto rocm_ops = std::make_unique<rocm_solib_ops> (std::move (prev_ops));
+ follow_inf->pspace->set_solib_ops (std::move (rocm_ops));
-void
-_initialize_rocm_solib ()
+ get_solib_info (exec_inf)->solib_list.clear ();
+}
+
+INIT_GDB_FILE (rocm_solib)
{
/* The dependency on the amd-dbgapi exists because solib-rocm's
inferior_created observer needs amd-dbgapi to have attached the process,
@@ -779,4 +841,8 @@ _initialize_rocm_solib ()
(rocm_solib_target_inferior_created,
"solib-rocm",
{ &get_amd_dbgapi_target_inferior_created_observer_token () });
+
+ gdb::observers::inferior_execd.attach
+ (rocm_solib_target_inferior_execd, "solib-rocm",
+ { &get_amd_dbgapi_target_inferior_execd_observer_token () });
}
diff --git a/gdb/solib-svr4-linux.c b/gdb/solib-svr4-linux.c
new file mode 100644
index 0000000..fd86cf0
--- /dev/null
+++ b/gdb/solib-svr4-linux.c
@@ -0,0 +1,98 @@
+/* Target-dependent code for GNU/Linux using SVR4-style libraries.
+
+ Copyright (C) 2025 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "solib-svr4-linux.h"
+
+/* See solib-svr4-linux.h. */
+
+solib_ops_up
+make_linux_ilp32_svr4_solib_ops ()
+{
+ return std::make_unique<linux_ilp32_svr4_solib_ops> ();
+}
+
+/* See solib-svr4-linux.h. */
+
+link_map_offsets *
+linux_ilp32_svr4_solib_ops::fetch_link_map_offsets () const
+{
+ static link_map_offsets lmo;
+ static link_map_offsets *lmp = nullptr;
+
+ if (lmp == nullptr)
+ {
+ lmp = &lmo;
+
+ lmo.r_version_offset = 0;
+ lmo.r_version_size = 4;
+ lmo.r_map_offset = 4;
+ lmo.r_brk_offset = 8;
+ lmo.r_ldsomap_offset = -1;
+ lmo.r_next_offset = 20;
+
+ /* Everything we need is in the first 20 bytes. */
+ lmo.link_map_size = 20;
+ lmo.l_addr_offset = 0;
+ lmo.l_name_offset = 4;
+ lmo.l_ld_offset = 8;
+ lmo.l_next_offset = 12;
+ lmo.l_prev_offset = 16;
+ }
+
+ return lmp;
+}
+
+/* See solib-svr4-linux.h. */
+
+solib_ops_up
+make_linux_lp64_svr4_solib_ops ()
+{
+ return std::make_unique<linux_lp64_svr4_solib_ops> ();
+}
+
+/* See linux-tdep.h. */
+
+link_map_offsets *
+linux_lp64_svr4_solib_ops::fetch_link_map_offsets () const
+{
+ static link_map_offsets lmo;
+ static link_map_offsets *lmp = nullptr;
+
+ if (lmp == nullptr)
+ {
+ lmp = &lmo;
+
+ lmo.r_version_offset = 0;
+ lmo.r_version_size = 4;
+ lmo.r_map_offset = 8;
+ lmo.r_brk_offset = 16;
+ lmo.r_ldsomap_offset = -1;
+ lmo.r_next_offset = 40;
+
+ /* Everything we need is in the first 40 bytes. */
+ lmo.link_map_size = 40;
+ lmo.l_addr_offset = 0;
+ lmo.l_name_offset = 8;
+ lmo.l_ld_offset = 16;
+ lmo.l_next_offset = 24;
+ lmo.l_prev_offset = 32;
+ }
+
+ return lmp;
+}
diff --git a/gdb/solib-svr4-linux.h b/gdb/solib-svr4-linux.h
new file mode 100644
index 0000000..623013c
--- /dev/null
+++ b/gdb/solib-svr4-linux.h
@@ -0,0 +1,47 @@
+/* Target-dependent code for GNU/Linux using SVR4-style libraries.
+
+ Copyright (C) 2025 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef GDB_SOLIB_SVR4_LINUX_H
+#define GDB_SOLIB_SVR4_LINUX_H
+
+#include "solib-svr4.h"
+
+/* solib_ops for ILP32 Linux systems. */
+
+struct linux_ilp32_svr4_solib_ops : public svr4_solib_ops
+{
+ link_map_offsets *fetch_link_map_offsets () const override;
+};
+
+/* solib_ops for LP64 Linux systems. */
+
+struct linux_lp64_svr4_solib_ops : public svr4_solib_ops
+{
+ link_map_offsets *fetch_link_map_offsets () const override;
+};
+
+/* Return a new solib_ops for ILP32 Linux systems. */
+
+extern solib_ops_up make_linux_ilp32_svr4_solib_ops ();
+
+/* Return a new solib_ops for LP64 Linux systems. */
+
+extern solib_ops_up make_linux_lp64_svr4_solib_ops ();
+
+#endif /* GDB_SOLIB_SVR4_LINUX_H */
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 9f56d86..9b4cabf 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -35,7 +35,6 @@
#include "regcache.h"
#include "observable.h"
-#include "solist.h"
#include "solib.h"
#include "solib-svr4.h"
@@ -48,8 +47,6 @@
#include <map>
-static struct link_map_offsets *svr4_fetch_link_map_offsets (void);
-static int svr4_have_link_map_offsets (void);
static void svr4_relocate_main_executable (void);
static void probes_table_remove_objfile_probes (struct objfile *objfile);
static void svr4_iterate_over_objfiles_in_search_order
@@ -91,27 +88,6 @@ static const char * const main_name_list[] =
NULL
};
-/* What to do when a probe stop occurs. */
-
-enum probe_action
-{
- /* Something went seriously wrong. Stop using probes and
- revert to using the older interface. */
- PROBES_INTERFACE_FAILED,
-
- /* No action is required. The shared object list is still
- valid. */
- DO_NOTHING,
-
- /* The shared object list should be reloaded entirely. */
- FULL_RELOAD,
-
- /* Attempt to incrementally update the shared object list. If
- the update fails or is not possible, fall back to reloading
- the list in full. */
- UPDATE_OR_RELOAD,
-};
-
/* A probe's name and its associated action. */
struct probe_info
@@ -186,22 +162,22 @@ svr4_same (const char *gdb_name, const char *inferior_name,
return gdb_lm_info.l_addr_inferior == inferior_lm_info.l_addr_inferior;
}
-static int
-svr4_same (const solib &gdb, const solib &inferior)
+bool
+svr4_solib_ops::same (const solib &gdb, const solib &inferior) const
{
auto *lmg
= gdb::checked_static_cast<const lm_info_svr4 *> (gdb.lm_info.get ());
auto *lmi
= gdb::checked_static_cast<const lm_info_svr4 *> (inferior.lm_info.get ());
- return svr4_same (gdb.so_original_name.c_str (),
- inferior.so_original_name.c_str (), *lmg, *lmi);
+ return svr4_same (gdb.original_name.c_str (),
+ inferior.original_name.c_str (), *lmg, *lmi);
}
-static lm_info_svr4_up
-lm_info_read (CORE_ADDR lm_addr)
+lm_info_svr4_up
+svr4_solib_ops::read_lm_info (CORE_ADDR lm_addr) const
{
- struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+ link_map_offsets *lmo = this->fetch_link_map_offsets ();
lm_info_svr4_up lm_info;
gdb::byte_vector lm (lmo->link_map_size);
@@ -231,16 +207,16 @@ lm_info_read (CORE_ADDR lm_addr)
return lm_info;
}
-static int
-has_lm_dynamic_from_link_map (void)
+int
+svr4_solib_ops::has_lm_dynamic_from_link_map () const
{
- struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+ link_map_offsets *lmo = this->fetch_link_map_offsets ();
return lmo->l_ld_offset >= 0;
}
-static CORE_ADDR
-lm_addr_check (const solib &so, bfd *abfd)
+CORE_ADDR
+svr4_solib_ops::lm_addr_check (const solib &so, bfd *abfd) const
{
auto *li = gdb::checked_static_cast<lm_info_svr4 *> (so.lm_info.get ());
@@ -251,7 +227,7 @@ lm_addr_check (const solib &so, bfd *abfd)
l_addr = li->l_addr_inferior;
- if (! abfd || ! has_lm_dynamic_from_link_map ())
+ if (!abfd || !this->has_lm_dynamic_from_link_map ())
goto set_addr;
l_dynaddr = li->l_ld;
@@ -317,7 +293,7 @@ lm_addr_check (const solib &so, bfd *abfd)
gdb_printf (_("Using PIC (Position Independent Code) "
"prelink displacement %s for \"%s\".\n"),
paddress (current_inferior ()->arch (), l_addr),
- so.so_name.c_str ());
+ so.name.c_str ());
}
else
{
@@ -333,7 +309,7 @@ lm_addr_check (const solib &so, bfd *abfd)
warning (_(".dynamic section for \"%s\" "
"is not at the expected address "
"(wrong library or version mismatch?)"),
- so.so_name.c_str ());
+ so.name.c_str ());
}
}
@@ -369,7 +345,7 @@ struct svr4_info
CORE_ADDR debug_loader_offset = 0;
/* Name of the dynamic linker, valid if debug_loader_offset_p. */
- char *debug_loader_name = nullptr;
+ std::string debug_loader_name;
/* Load map address for the main executable in default namespace. */
CORE_ADDR main_lm_addr = 0;
@@ -477,8 +453,8 @@ svr4_is_default_namespace (const svr4_info *info, CORE_ADDR debug_base)
/* Free the probes table. */
-static void
-free_probes_table (struct svr4_info *info)
+void
+svr4_solib_ops::free_probes_table (svr4_info *info) const
{
info->probes_table.reset (nullptr);
}
@@ -754,9 +730,6 @@ elf_locate_base (void)
{
CORE_ADDR dyn_ptr, dyn_ptr_addr;
- if (!svr4_have_link_map_offsets ())
- return 0;
-
/* Look for DT_MIPS_RLD_MAP first. MIPS executables use this
instead of DT_DEBUG, although they sometimes contain an unused
DT_DEBUG. */
@@ -825,10 +798,10 @@ elf_locate_base (void)
checking r_version for a known version number, or r_state for
RT_CONSISTENT. */
-static CORE_ADDR
-solib_svr4_r_map (CORE_ADDR debug_base)
+CORE_ADDR
+svr4_solib_ops::read_r_map (CORE_ADDR debug_base) const
{
- struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+ link_map_offsets *lmo = this->fetch_link_map_offsets ();
type *ptr_type
= builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
CORE_ADDR addr = 0;
@@ -848,10 +821,10 @@ solib_svr4_r_map (CORE_ADDR debug_base)
/* Find r_brk from the inferior's debug base. */
-static CORE_ADDR
-solib_svr4_r_brk (struct svr4_info *info)
+CORE_ADDR
+svr4_solib_ops::find_r_brk (svr4_info *info) const
{
- struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+ link_map_offsets *lmo = this->fetch_link_map_offsets ();
type *ptr_type
= builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
@@ -862,10 +835,10 @@ solib_svr4_r_brk (struct svr4_info *info)
/* Find the link map for the dynamic linker (if it is not in the
normal list of loaded shared objects). */
-static CORE_ADDR
-solib_svr4_r_ldsomap (struct svr4_info *info)
+CORE_ADDR
+svr4_solib_ops::find_r_ldsomap (svr4_info *info) const
{
- struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+ link_map_offsets *lmo = this->fetch_link_map_offsets ();
type *ptr_type
= builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
enum bfd_endian byte_order = type_byte_order (ptr_type);
@@ -893,10 +866,10 @@ solib_svr4_r_ldsomap (struct svr4_info *info)
/* Find the next namespace from the r_next field. */
-static CORE_ADDR
-solib_svr4_r_next (CORE_ADDR debug_base)
+CORE_ADDR
+svr4_solib_ops::read_r_next (CORE_ADDR debug_base) const
{
- link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+ link_map_offsets *lmo = this->fetch_link_map_offsets ();
type *ptr_type
= builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
bfd_endian byte_order = type_byte_order (ptr_type);
@@ -928,8 +901,8 @@ solib_svr4_r_next (CORE_ADDR debug_base)
memory areas containing the l_name string are saved in the core
file. */
-static int
-svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
+bool
+svr4_solib_ops::keep_data_in_core (CORE_ADDR vaddr, unsigned long size) const
{
struct svr4_info *info;
CORE_ADDR ldsomap;
@@ -939,25 +912,25 @@ svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
info->debug_base = elf_locate_base ();
if (info->debug_base == 0)
- return 0;
+ return false;
- ldsomap = solib_svr4_r_ldsomap (info);
+ ldsomap = this->find_r_ldsomap (info);
if (!ldsomap)
- return 0;
+ return false;
- std::unique_ptr<lm_info_svr4> li = lm_info_read (ldsomap);
+ std::unique_ptr<lm_info_svr4> li = this->read_lm_info (ldsomap);
name_lm = li != NULL ? li->l_name : 0;
return (name_lm >= vaddr && name_lm < vaddr + size);
}
-/* See solist.h. */
+/* See solib.h. */
-static int
-open_symbol_file_object (int from_tty)
+bool
+svr4_solib_ops::open_symbol_file_object (int from_tty) const
{
CORE_ADDR lm, l_name;
- struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+ link_map_offsets *lmo = this->fetch_link_map_offsets ();
type *ptr_type
= builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
int l_name_size = ptr_type->length ();
@@ -970,17 +943,17 @@ open_symbol_file_object (int from_tty)
if (current_program_space->symfile_object_file)
if (!query (_("Attempt to reload symbols from process? ")))
- return 0;
+ return false;
/* Always locate the debug struct, in case it has moved. */
info->debug_base = elf_locate_base ();
if (info->debug_base == 0)
- return 0; /* failed somehow... */
+ return false; /* failed somehow... */
/* First link map member should be the executable. */
- lm = solib_svr4_r_map (info->debug_base);
+ lm = this->read_r_map (info->debug_base);
if (lm == 0)
- return 0; /* failed somehow... */
+ return false; /* failed somehow... */
/* Read address of name from target memory to GDB. */
read_memory (lm + lmo->l_name_offset, l_name_buf.data (), l_name_size);
@@ -989,7 +962,7 @@ open_symbol_file_object (int from_tty)
l_name = extract_typed_address (l_name_buf.data (), ptr_type);
if (l_name == 0)
- return 0; /* No filename. */
+ return false; /* No filename. */
/* Now fetch the filename from target memory. */
gdb::unique_xmalloc_ptr<char> filename
@@ -998,13 +971,13 @@ open_symbol_file_object (int from_tty)
if (filename == nullptr)
{
warning (_("failed to read exec filename from attached file"));
- return 0;
+ return false;
}
/* Have a pathname: read the symbol file. */
symbol_file_add_main (filename.get (), add_flags);
- return 1;
+ return true;
}
/* Data exchange structure for the XML parser as returned by
@@ -1037,8 +1010,8 @@ svr4_free_objfile_observer (struct objfile *objfile)
/* Implement solib_ops.clear_so. */
-static void
-svr4_clear_so (const solib &so)
+void
+svr4_solib_ops::clear_so (const solib &so) const
{
auto *li = gdb::checked_static_cast<lm_info_svr4 *> (so.lm_info.get ());
@@ -1046,19 +1019,19 @@ svr4_clear_so (const solib &so)
li->l_addr_p = 0;
}
-/* Create the so_list objects equivalent to the svr4_sos in SOS. */
+/* Create the solib objects equivalent to the svr4_sos in SOS. */
-static owning_intrusive_list<solib>
-so_list_from_svr4_sos (const std::vector<svr4_so> &sos)
+owning_intrusive_list<solib>
+svr4_solib_ops::solibs_from_svr4_sos (const std::vector<svr4_so> &sos) const
{
owning_intrusive_list<solib> dst;
for (const svr4_so &so : sos)
{
- auto &newobj = dst.emplace_back ();
+ auto &newobj = dst.emplace_back (*this);
- newobj.so_name = so.name;
- newobj.so_original_name = so.name;
+ newobj.name = so.name;
+ newobj.original_name = so.name;
newobj.lm_info = std::make_unique<lm_info_svr4> (*so.lm_info);
}
@@ -1176,11 +1149,10 @@ static const struct gdb_xml_element svr4_library_list_elements[] =
{ NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};
-/* Parse qXfer:libraries:read packet into *SO_LIST_RETURN. Return 1 if
+/* Parse qXfer:libraries:read packet into *LIST.
- Return 0 if packet not supported, *SO_LIST_RETURN is not modified in such
- case. Return 1 if *SO_LIST_RETURN contains the library list, it may be
- empty, caller is responsible for freeing all its entries. */
+ Return 0 if packet not supported, *LIST is not modified in such case.
+ Return 1 if *LIST contains the library list. */
static int
svr4_parse_libraries (const char *document, struct svr4_library_list *list)
@@ -1202,11 +1174,11 @@ svr4_parse_libraries (const char *document, struct svr4_library_list *list)
return 0;
}
-/* Attempt to get so_list from target via qXfer:libraries-svr4:read packet.
+/* Attempt to get the shared object list from target via
+ qXfer:libraries-svr4:read packet.
- Return 0 if packet not supported, *SO_LIST_RETURN is not modified in such
- case. Return 1 if *SO_LIST_RETURN contains the library list, it may be
- empty, caller is responsible for freeing all its entries.
+ Return 0 if packet not supported, *LIST is not modified in such case.
+ Return 1 if *LIST contains the library list.
Note that ANNEX must be NULL if the remote does not explicitly allow
qXfer:libraries-svr4:read packets with non-empty annexes. Support for
@@ -1243,8 +1215,8 @@ svr4_current_sos_via_xfer_libraries (struct svr4_library_list *list,
/* If no shared library information is available from the dynamic
linker, build a fallback list from other sources. */
-static owning_intrusive_list<solib>
-svr4_default_sos (svr4_info *info)
+owning_intrusive_list<solib>
+svr4_solib_ops::default_sos (svr4_info *info) const
{
if (!info->debug_loader_offset_p)
return {};
@@ -1256,11 +1228,11 @@ svr4_default_sos (svr4_info *info)
li->l_addr_p = 1;
owning_intrusive_list<solib> sos;
- auto &newobj = sos.emplace_back ();
+ auto &newobj = sos.emplace_back (*this);
newobj.lm_info = std::move (li);
- newobj.so_name = info->debug_loader_name;
- newobj.so_original_name = newobj.so_name;
+ newobj.name = info->debug_loader_name;
+ newobj.original_name = newobj.name;
return sos;
}
@@ -1272,16 +1244,16 @@ svr4_default_sos (svr4_info *info)
is returned the entries stored to LINK_PTR_PTR are still valid although they may
represent only part of the inferior library list. */
-static int
-svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
- std::vector<svr4_so> &sos, int ignore_first)
+int
+svr4_solib_ops::read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
+ std::vector<svr4_so> &sos, int ignore_first) const
{
CORE_ADDR first_l_name = 0;
CORE_ADDR next_lm;
for (; lm != 0; prev_lm = lm, lm = next_lm)
{
- lm_info_svr4_up li = lm_info_read (lm);
+ lm_info_svr4_up li = this->read_lm_info (lm);
if (li == NULL)
return 0;
@@ -1337,8 +1309,8 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
stored by the probes interface. Handle special cases relating
to the first elements of the list in default namespace. */
-static void
-svr4_current_sos_direct (struct svr4_info *info)
+void
+svr4_solib_ops::current_sos_direct (svr4_info *info) const
{
CORE_ADDR lm;
bool ignore_first;
@@ -1404,15 +1376,15 @@ svr4_current_sos_direct (struct svr4_info *info)
/* Collect the sos in each namespace. */
CORE_ADDR debug_base = info->debug_base;
for (; debug_base != 0;
- ignore_first = false, debug_base = solib_svr4_r_next (debug_base))
+ ignore_first = false, debug_base = this->read_r_next (debug_base))
{
/* Walk the inferior's link map list, and build our so_list list. */
- lm = solib_svr4_r_map (debug_base);
+ lm = this->read_r_map (debug_base);
if (lm != 0)
{
svr4_maybe_add_namespace (info, debug_base);
- svr4_read_so_list (info, lm, 0, info->solib_lists[debug_base],
- ignore_first);
+ this->read_so_list (info, lm, 0, info->solib_lists[debug_base],
+ ignore_first);
}
}
@@ -1425,15 +1397,15 @@ svr4_current_sos_direct (struct svr4_info *info)
r_debug object. If we added it to the default namespace (as it was),
we would probably run into inconsistencies with the load map's
prev/next links (I wonder if we did). */
- debug_base = solib_svr4_r_ldsomap (info);
+ debug_base = this->find_r_ldsomap (info);
if (debug_base != 0)
{
/* Add the dynamic linker's namespace unless we already did. */
if (info->solib_lists.find (debug_base) == info->solib_lists.end ())
{
svr4_maybe_add_namespace (info, debug_base);
- svr4_read_so_list (info, debug_base, 0, info->solib_lists[debug_base],
- 0);
+ this->read_so_list (info, debug_base, 0,
+ info->solib_lists[debug_base], 0);
}
}
@@ -1442,15 +1414,15 @@ svr4_current_sos_direct (struct svr4_info *info)
/* Collect sos read and stored by the probes interface. */
-static owning_intrusive_list<solib>
-svr4_collect_probes_sos (svr4_info *info)
+owning_intrusive_list<solib>
+svr4_solib_ops::collect_probes_sos (svr4_info *info) const
{
owning_intrusive_list<solib> res;
for (const auto &tuple : info->solib_lists)
{
const std::vector<svr4_so> &sos = tuple.second;
- res.splice (so_list_from_svr4_sos (sos));
+ res.splice (this->solibs_from_svr4_sos (sos));
}
return res;
@@ -1459,26 +1431,26 @@ svr4_collect_probes_sos (svr4_info *info)
/* Implement the main part of the "current_sos" solib_ops
method. */
-static owning_intrusive_list<solib>
-svr4_current_sos_1 (svr4_info *info)
+owning_intrusive_list<solib>
+svr4_solib_ops::current_sos_1 (svr4_info *info) const
{
owning_intrusive_list<solib> sos;
/* If we're using the probes interface, we can use the cache as it will
be maintained by probe update/reload actions. */
if (info->probes_table != nullptr)
- sos = svr4_collect_probes_sos (info);
+ sos = this->collect_probes_sos (info);
/* If we're not using the probes interface or if we didn't cache
anything, read the sos to fill the cache, then collect them from the
cache. */
if (sos.empty ())
{
- svr4_current_sos_direct (info);
+ this->current_sos_direct (info);
- sos = svr4_collect_probes_sos (info);
+ sos = this->collect_probes_sos (info);
if (sos.empty ())
- sos = svr4_default_sos (info);
+ sos = this->default_sos (info);
}
return sos;
@@ -1486,11 +1458,11 @@ svr4_current_sos_1 (svr4_info *info)
/* Implement the "current_sos" solib_ops method. */
-static owning_intrusive_list<solib>
-svr4_current_sos ()
+owning_intrusive_list<solib>
+svr4_solib_ops::current_sos () const
{
svr4_info *info = get_svr4_info (current_program_space);
- owning_intrusive_list<solib> sos = svr4_current_sos_1 (info);
+ owning_intrusive_list<solib> sos = this->current_sos_1 (info);
struct mem_range vsyscall_range;
/* Filter out the vDSO module, if present. Its symbol file would
@@ -1728,12 +1700,20 @@ glibc_link_map_to_tls_module_id (CORE_ADDR lm_addr)
static void
tls_maybe_fill_slot (solib &so)
{
+ auto *li = dynamic_cast<lm_info_svr4 *> (so.lm_info.get ());
+ if (li == nullptr)
+ return;
+
struct svr4_info *info = get_svr4_info (current_program_space);
if (!info->glibc_tls_slots_inited)
{
/* Cause svr4_current_sos() to be run if it hasn't been already. */
if (info->main_lm_addr == 0)
- svr4_current_sos_direct (info);
+ {
+ auto &ops
+ = gdb::checked_static_cast<const svr4_solib_ops &> (so.ops ());
+ ops.current_sos_direct (info);
+ }
/* Quit early when main_lm_addr is still 0. */
if (info->main_lm_addr == 0)
@@ -1753,7 +1733,6 @@ tls_maybe_fill_slot (solib &so)
auto it = std::find (info->glibc_tls_slots.begin (),
info->glibc_tls_slots.end (),
0);
- auto *li = gdb::checked_static_cast<lm_info_svr4 *> (so.lm_info.get ());
if (it == info->glibc_tls_slots.end ())
info->glibc_tls_slots.push_back (li->lm_addr);
else
@@ -1771,8 +1750,11 @@ tls_maybe_erase_slot (program_space *pspace, const solib &so,
if (still_in_use)
return;
+ auto *li = dynamic_cast<lm_info_svr4 *> (so.lm_info.get ());
+ if (li == nullptr)
+ return;
+
struct svr4_info *info = get_svr4_info (pspace);
- auto *li = gdb::checked_static_cast<lm_info_svr4 *> (so.lm_info.get ());
auto it = std::find (info->glibc_tls_slots.begin (),
info->glibc_tls_slots.end (),
li->lm_addr);
@@ -1798,11 +1780,11 @@ match_main (const char *soname)
return (0);
}
-/* Return 1 if PC lies in the dynamic symbol resolution code of the
+/* Return true if PC lies in the dynamic symbol resolution code of the
SVR4 run time loader. */
-int
-svr4_in_dynsym_resolve_code (CORE_ADDR pc)
+bool
+svr4_solib_ops::in_dynsym_resolve_code (CORE_ADDR pc) const
{
struct svr4_info *info = get_svr4_info (current_program_space);
@@ -2001,12 +1983,10 @@ solib_event_probe_action (struct probe_and_action *pa)
shared objects from the inferior. Handle special cases relating
to the first elements of the list. Returns nonzero on success. */
-static int
-solist_update_full (struct svr4_info *info)
+void
+svr4_solib_ops::update_full (svr4_info *info) const
{
- svr4_current_sos_direct (info);
-
- return 1;
+ this->current_sos_direct (info);
}
/* Update the shared object list starting from the link-map entry
@@ -2014,9 +1994,9 @@ solist_update_full (struct svr4_info *info)
nonzero if the list was successfully updated, or zero to indicate
failure. */
-static int
-solist_update_incremental (svr4_info *info, CORE_ADDR debug_base,
- CORE_ADDR lm)
+int
+svr4_solib_ops::update_incremental (svr4_info *info, CORE_ADDR debug_base,
+ CORE_ADDR lm) const
{
/* Fall back to a full update if we are using a remote target
that does not support incremental transfers. */
@@ -2094,7 +2074,7 @@ solist_update_incremental (svr4_info *info, CORE_ADDR debug_base,
above check and deferral to solist_update_full ensures
that this call to svr4_read_so_list will never see the
first element. */
- if (!svr4_read_so_list (info, lm, prev_lm, solist, 0))
+ if (!this->read_so_list (info, lm, prev_lm, solist, 0))
return 0;
}
@@ -2105,8 +2085,8 @@ solist_update_incremental (svr4_info *info, CORE_ADDR debug_base,
original interface. We don't reset the breakpoints as the
ones set up for the probes-based interface are adequate. */
-static void
-disable_probes_interface (svr4_info *info)
+void
+svr4_solib_ops::disable_probes_interface (svr4_info *info) const
{
warning (_("Probes-based dynamic linker interface failed.\n"
"Reverting to original interface."));
@@ -2121,8 +2101,8 @@ disable_probes_interface (svr4_info *info)
probes-based linker interface. Do nothing if using the
standard interface. */
-static void
-svr4_handle_solib_event (void)
+void
+svr4_solib_ops::handle_event () const
{
struct svr4_info *info = get_svr4_info (current_program_space);
struct probe_and_action *pa;
@@ -2147,9 +2127,9 @@ svr4_handle_solib_event (void)
/* If anything goes wrong we revert to the original linker
interface. */
- auto cleanup = make_scope_exit ([info] ()
+ auto cleanup = make_scope_exit ([this, info] ()
{
- disable_probes_interface (info);
+ this->disable_probes_interface (info);
});
action = solib_event_probe_action (pa);
@@ -2251,15 +2231,12 @@ svr4_handle_solib_event (void)
if (action == UPDATE_OR_RELOAD)
{
- if (!solist_update_incremental (info, debug_base, lm))
+ if (!this->update_incremental (info, debug_base, lm))
action = FULL_RELOAD;
}
if (action == FULL_RELOAD)
- {
- if (!solist_update_full (info))
- return;
- }
+ this->update_full (info);
cleanup.release ();
}
@@ -2306,8 +2283,8 @@ svr4_update_solib_event_breakpoint (struct breakpoint *b)
/* Enable or disable optional solib event breakpoints as appropriate.
Called whenever stop_on_solib_events is changed. */
-static void
-svr4_update_solib_event_breakpoints (void)
+void
+svr4_solib_ops::update_breakpoints () const
{
for (breakpoint &bp : all_breakpoints_safe ())
svr4_update_solib_event_breakpoint (&bp);
@@ -2318,10 +2295,10 @@ svr4_update_solib_event_breakpoints (void)
solib event breakpoint will be created and registered for each
probe. */
-static void
-svr4_create_probe_breakpoints (svr4_info *info, struct gdbarch *gdbarch,
- const std::vector<probe *> *probes,
- struct objfile *objfile)
+void
+svr4_solib_ops::create_probe_breakpoints (svr4_info *info, gdbarch *gdbarch,
+ const std::vector<probe *> *probes,
+ objfile *objfile) const
{
for (int i = 0; i < NUM_PROBES; i++)
{
@@ -2339,17 +2316,17 @@ svr4_create_probe_breakpoints (svr4_info *info, struct gdbarch *gdbarch,
}
}
- svr4_update_solib_event_breakpoints ();
+ this->update_breakpoints ();
}
/* Find all the glibc named probes. Only if all of the probes are found, then
create them and return true. Otherwise return false. If WITH_PREFIX is set
then add "rtld" to the front of the probe names. */
-static bool
-svr4_find_and_create_probe_breakpoints (svr4_info *info,
- struct gdbarch *gdbarch,
- struct obj_section *os,
- bool with_prefix)
+bool
+svr4_solib_ops::find_and_create_probe_breakpoints (svr4_info *info,
+ gdbarch *gdbarch,
+ obj_section *os,
+ bool with_prefix) const
{
SOLIB_SCOPED_DEBUG_START_END ("objfile=%s, with_prefix=%d",
os->objfile->original_name, with_prefix);
@@ -2427,7 +2404,7 @@ svr4_find_and_create_probe_breakpoints (svr4_info *info,
/* All probes found. Now create them. */
solib_debug_printf ("using probes interface");
- svr4_create_probe_breakpoints (info, gdbarch, probes, os->objfile);
+ this->create_probe_breakpoints (info, gdbarch, probes, os->objfile);
return true;
}
@@ -2443,15 +2420,16 @@ svr4_find_and_create_probe_breakpoints (svr4_info *info,
probes aren't found, a single breakpoint is set on the original
marker function. */
-static void
-svr4_create_solib_event_breakpoints (svr4_info *info, struct gdbarch *gdbarch,
- CORE_ADDR address)
+void
+svr4_solib_ops::create_event_breakpoints (svr4_info *info, gdbarch *gdbarch,
+ CORE_ADDR address) const
{
struct obj_section *os = find_pc_section (address);
if (os == nullptr
- || (!svr4_find_and_create_probe_breakpoints (info, gdbarch, os, false)
- && !svr4_find_and_create_probe_breakpoints (info, gdbarch, os, true)))
+ || (!this->find_and_create_probe_breakpoints (info, gdbarch, os, false)
+ && !this->find_and_create_probe_breakpoints (info, gdbarch, os,
+ true)))
{
solib_debug_printf ("falling back to r_brk breakpoint: addr=%s",
paddress (gdbarch, address));
@@ -2491,8 +2469,8 @@ svr4_create_solib_event_breakpoints (svr4_info *info, struct gdbarch *gdbarch,
depending upon whether or not the library is being mapped or unmapped,
and then set to RT_CONSISTENT after the library is mapped/unmapped. */
-static int
-enable_break (struct svr4_info *info, int from_tty)
+int
+svr4_solib_ops::enable_break (svr4_info *info, int from_tty) const
{
const char * const *bkpt_namep;
asection *interp_sect;
@@ -2508,8 +2486,8 @@ enable_break (struct svr4_info *info, int from_tty)
solib_add (NULL, from_tty, auto_solib_add);
sym_addr = 0;
- if (info->debug_base && solib_svr4_r_map (info->debug_base) != 0)
- sym_addr = solib_svr4_r_brk (info);
+ if (info->debug_base && this->read_r_map (info->debug_base) != 0)
+ sym_addr = this->find_r_brk (info);
if (sym_addr != 0)
{
@@ -2568,8 +2546,8 @@ enable_break (struct svr4_info *info, int from_tty)
= info->interp_plt_sect_low + bfd_section_size (interp_sect);
}
- svr4_create_solib_event_breakpoints
- (info, current_inferior ()->arch (), sym_addr);
+ this->create_event_breakpoints (info, current_inferior ()->arch (),
+ sym_addr);
return 1;
}
}
@@ -2617,11 +2595,11 @@ enable_break (struct svr4_info *info, int from_tty)
address from the shared library table. */
for (const solib &so : current_program_space->solibs ())
{
- if (svr4_same_1 (interp_name, so.so_original_name.c_str ()))
+ if (svr4_same_1 (interp_name, so.original_name.c_str ()))
{
load_addr_found = 1;
loader_found_in_list = 1;
- load_addr = lm_addr_check (so, tmp_bfd.get ());
+ load_addr = this->lm_addr_check (so, tmp_bfd.get ());
break;
}
}
@@ -2677,7 +2655,7 @@ enable_break (struct svr4_info *info, int from_tty)
if (!loader_found_in_list)
{
- info->debug_loader_name = xstrdup (interp_name);
+ info->debug_loader_name = interp_name;
info->debug_loader_offset_p = 1;
info->debug_loader_offset = load_addr;
solib_add (NULL, from_tty, auto_solib_add);
@@ -2728,9 +2706,8 @@ enable_break (struct svr4_info *info, int from_tty)
if (sym_addr != 0)
{
- svr4_create_solib_event_breakpoints (info,
- current_inferior ()->arch (),
- load_addr + sym_addr);
+ this->create_event_breakpoints (info, current_inferior ()->arch (),
+ load_addr + sym_addr);
return 1;
}
@@ -2757,9 +2734,8 @@ enable_break (struct svr4_info *info, int from_tty)
sym_addr = gdbarch_convert_from_func_ptr_addr
(current_inferior ()->arch (), sym_addr,
current_inferior ()->top_target ());
- svr4_create_solib_event_breakpoints (info,
- current_inferior ()->arch (),
- sym_addr);
+ this->create_event_breakpoints (info, current_inferior ()->arch (),
+ sym_addr);
return 1;
}
}
@@ -2777,8 +2753,9 @@ enable_break (struct svr4_info *info, int from_tty)
sym_addr = gdbarch_convert_from_func_ptr_addr
(current_inferior ()->arch (), sym_addr,
current_inferior ()->top_target ());
- svr4_create_solib_event_breakpoints
- (info, current_inferior ()->arch (), sym_addr);
+ this->create_event_breakpoints (info,
+ current_inferior ()->arch (),
+ sym_addr);
return 1;
}
}
@@ -3302,15 +3279,15 @@ svr4_relocate_main_executable (void)
addresses, and saving sufficient information about them to allow
their symbols to be read at a later time. */
-static void
-svr4_solib_create_inferior_hook (int from_tty)
+void
+svr4_solib_ops::create_inferior_hook (int from_tty) const
{
struct svr4_info *info;
info = get_svr4_info (current_program_space);
/* Clear the probes-based interface's state. */
- free_probes_table (info);
+ this->free_probes_table (info);
info->solib_lists.clear ();
info->namespace_id.clear ();
info->active_namespaces.clear ();
@@ -3323,22 +3300,18 @@ svr4_solib_create_inferior_hook (int from_tty)
if (!target_has_execution ())
return;
- if (!svr4_have_link_map_offsets ())
- return;
-
- if (!enable_break (info, from_tty))
+ if (!this->enable_break (info, from_tty))
return;
}
-static void
-svr4_clear_solib (program_space *pspace)
+void
+svr4_solib_ops::clear_solib (program_space *pspace) const
{
svr4_info *info = get_svr4_info (pspace);
info->debug_base = 0;
info->debug_loader_offset_p = 0;
info->debug_loader_offset = 0;
- xfree (info->debug_loader_name);
- info->debug_loader_name = NULL;
+ info->debug_loader_name.clear ();
}
/* Clear any bits of ADDR that wouldn't fit in a target-format
@@ -3395,15 +3368,15 @@ find_loadable_elf_internal_phdr (bfd *abfd, bfd_section *asect)
return nullptr;
}
-/* Implement solib_ops::relocate_section_addresses() for svr4 targets. */
-
-static void
-svr4_relocate_section_addresses (solib &so, target_section *sec)
+void
+svr4_solib_ops::relocate_section_addresses (solib &so,
+ target_section *sec) const
{
bfd *abfd = sec->the_bfd_section->owner;
- sec->addr = svr4_truncate_ptr (sec->addr + lm_addr_check (so, abfd));
- sec->endaddr = svr4_truncate_ptr (sec->endaddr + lm_addr_check (so, abfd));
+ sec->addr = svr4_truncate_ptr (sec->addr + this->lm_addr_check (so, abfd));
+ sec->endaddr
+ = svr4_truncate_ptr (sec->endaddr + this->lm_addr_check (so, abfd));
struct bfd_section *asect = sec->the_bfd_section;
gdb_assert (asect != nullptr);
@@ -3473,68 +3446,24 @@ svr4_relocate_section_addresses (solib &so, target_section *sec)
}
}
}
-
-
-/* Architecture-specific operations. */
-
-struct solib_svr4_ops
-{
- /* Return a description of the layout of `struct link_map'. */
- struct link_map_offsets *(*fetch_link_map_offsets)(void) = nullptr;
-};
-
-/* Per-architecture data key. */
-static const registry<gdbarch>::key<struct solib_svr4_ops> solib_svr4_data;
-
-/* Return a default for the architecture-specific operations. */
-
-static struct solib_svr4_ops *
-get_ops (struct gdbarch *gdbarch)
-{
- struct solib_svr4_ops *ops = solib_svr4_data.get (gdbarch);
- if (ops == nullptr)
- ops = solib_svr4_data.emplace (gdbarch);
- return ops;
-}
-/* Set the architecture-specific `struct link_map_offsets' fetcher for
- GDBARCH to FLMO. Also, install SVR4 solib_ops into GDBARCH. */
+/* See solib-svr4.h. */
void
-set_solib_svr4_fetch_link_map_offsets (struct gdbarch *gdbarch,
- struct link_map_offsets *(*flmo) (void))
+set_solib_svr4_ops (gdbarch *gdbarch, gdbarch_make_solib_ops_ftype make_solib_ops)
{
- struct solib_svr4_ops *ops = get_ops (gdbarch);
-
- ops->fetch_link_map_offsets = flmo;
-
- set_gdbarch_so_ops (gdbarch, &svr4_so_ops);
+ set_gdbarch_make_solib_ops (gdbarch, make_solib_ops);
set_gdbarch_iterate_over_objfiles_in_search_order
(gdbarch, svr4_iterate_over_objfiles_in_search_order);
}
-/* Fetch a link_map_offsets structure using the architecture-specific
- `struct link_map_offsets' fetcher. */
-
-static struct link_map_offsets *
-svr4_fetch_link_map_offsets (void)
-{
- struct solib_svr4_ops *ops = get_ops (current_inferior ()->arch ());
-
- gdb_assert (ops->fetch_link_map_offsets);
- return ops->fetch_link_map_offsets ();
-}
-
-/* Return 1 if a link map offset fetcher has been defined, 0 otherwise. */
+/* See solib-svr4.h. */
-static int
-svr4_have_link_map_offsets (void)
+solib_ops_up
+make_svr4_ilp32_solib_ops ()
{
- struct solib_svr4_ops *ops = get_ops (current_inferior ()->arch ());
-
- return (ops->fetch_link_map_offsets != NULL);
+ return std::make_unique<ilp32_svr4_solib_ops> ();
}
-
/* Most OS'es that have SVR4-style ELF dynamic libraries define a
`struct r_debug' and a `struct link_map' that are binary compatible
@@ -3543,8 +3472,8 @@ svr4_have_link_map_offsets (void)
/* Fetch (and possibly build) an appropriate `struct link_map_offsets'
for an ILP32 SVR4 system. */
-struct link_map_offsets *
-svr4_ilp32_fetch_link_map_offsets (void)
+link_map_offsets *
+ilp32_svr4_solib_ops::fetch_link_map_offsets () const
{
static struct link_map_offsets lmo;
static struct link_map_offsets *lmp = NULL;
@@ -3572,11 +3501,26 @@ svr4_ilp32_fetch_link_map_offsets (void)
return lmp;
}
+/* solib_ops for LP64 SVR4 systems. */
+
+struct lp64_svr4_solib_ops : public svr4_solib_ops
+{
+ link_map_offsets *fetch_link_map_offsets () const override;
+};
+
+/* See solib-svr4.h. */
+
+solib_ops_up
+make_svr4_lp64_solib_ops ()
+{
+ return std::make_unique<lp64_svr4_solib_ops> ();
+}
+
/* Fetch (and possibly build) an appropriate `struct link_map_offsets'
for an LP64 SVR4 system. */
-struct link_map_offsets *
-svr4_lp64_fetch_link_map_offsets (void)
+link_map_offsets *
+lp64_svr4_solib_ops::fetch_link_map_offsets () const
{
static struct link_map_offsets lmo;
static struct link_map_offsets *lmp = NULL;
@@ -3650,7 +3594,7 @@ find_debug_base_for_solib (const solib *solib)
const std::vector<svr4_so> &sos = tuple.second;
for (const svr4_so &so : sos)
- if (svr4_same (solib->so_original_name.c_str (), so.name.c_str (),
+ if (svr4_same (solib->original_name.c_str (), so.name.c_str (),
*lm_info, *so.lm_info))
return debug_base;
}
@@ -3723,19 +3667,15 @@ svr4_iterate_over_objfiles_in_search_order
}
}
-/* See solib_ops::find_solib_addr in solist.h. */
-
-static std::optional<CORE_ADDR>
-svr4_find_solib_addr (solib &so)
+std::optional<CORE_ADDR>
+svr4_solib_ops::find_solib_addr (solib &so) const
{
auto *li = gdb::checked_static_cast<lm_info_svr4 *> (so.lm_info.get ());
return li->l_addr_inferior;
}
-/* See solib_ops::find_solib_ns in solist.h. */
-
-static int
-svr4_find_solib_ns (const solib &so)
+int
+svr4_solib_ops::find_solib_ns (const solib &so) const
{
CORE_ADDR debug_base = find_debug_base_for_solib (&so);
svr4_info *info = get_svr4_info (current_program_space);
@@ -3750,17 +3690,15 @@ svr4_find_solib_ns (const solib &so)
error (_("No namespace found"));
}
-/* see solib_ops::num_active_namespaces in solist.h. */
-static int
-svr4_num_active_namespaces ()
+int
+svr4_solib_ops::num_active_namespaces () const
{
svr4_info *info = get_svr4_info (current_program_space);
return info->active_namespaces.size ();
}
-/* See solib_ops::get_solibs_in_ns in solist.h. */
-static std::vector<const solib *>
-svr4_get_solibs_in_ns (int nsid)
+std::vector<const solib *>
+svr4_solib_ops::get_solibs_in_ns (int nsid) const
{
std::vector<const solib*> ns_solibs;
svr4_info *info = get_svr4_info (current_program_space);
@@ -3792,43 +3730,21 @@ svr4_get_solibs_in_ns (int nsid)
/* This is inspired by the svr4_same, by finding the svr4_so object
in the map, and then double checking if the lm_info is considered
the same. */
- if (namespace_solibs.count (so.so_original_name) > 0
- && namespace_solibs[so.so_original_name]->l_addr_inferior
+ if (namespace_solibs.count (so.original_name) > 0
+ && namespace_solibs[so.original_name]->l_addr_inferior
== lm_inferior->l_addr_inferior)
{
ns_solibs.push_back (&so);
/* Remove the SO from the map, so that we don't end up
printing the dynamic linker multiple times. */
- namespace_solibs.erase (so.so_original_name);
+ namespace_solibs.erase (so.original_name);
}
}
return ns_solibs;
}
-const struct solib_ops svr4_so_ops =
-{
- svr4_relocate_section_addresses,
- svr4_clear_so,
- svr4_clear_solib,
- svr4_solib_create_inferior_hook,
- svr4_current_sos,
- open_symbol_file_object,
- svr4_in_dynsym_resolve_code,
- solib_bfd_open,
- svr4_same,
- svr4_keep_data_in_core,
- svr4_update_solib_event_breakpoints,
- svr4_handle_solib_event,
- svr4_find_solib_addr,
- svr4_find_solib_ns,
- svr4_num_active_namespaces,
- svr4_get_solibs_in_ns,
-};
-
-void _initialize_svr4_solib ();
-void
-_initialize_svr4_solib ()
+INIT_GDB_FILE (svr4_solib)
{
gdb::observers::free_objfile.attach (svr4_free_objfile_observer,
"solib-svr4");
diff --git a/gdb/solib-svr4.h b/gdb/solib-svr4.h
index e59c8e4..b331fa7 100644
--- a/gdb/solib-svr4.h
+++ b/gdb/solib-svr4.h
@@ -20,14 +20,17 @@
#ifndef GDB_SOLIB_SVR4_H
#define GDB_SOLIB_SVR4_H
-#include "solist.h"
+#include "gdbarch.h"
+#include "solib.h"
struct objfile;
-struct solib_ops;
+struct link_map_offsets;
+struct probe_and_action;
+struct svr4_info;
+struct svr4_library_list;
+struct svr4_so;
-extern const solib_ops svr4_so_ops;
-
-/* Link map info to include in an allocated so_list entry. */
+/* Link map info to include in an allocated solib entry. */
struct lm_info_svr4 final : public lm_info
{
@@ -50,6 +53,101 @@ struct lm_info_svr4 final : public lm_info
using lm_info_svr4_up = std::unique_ptr<lm_info_svr4>;
+/* What to do when a probe stop occurs. */
+
+enum probe_action
+{
+ /* Something went seriously wrong. Stop using probes and
+ revert to using the older interface. */
+ PROBES_INTERFACE_FAILED,
+
+ /* No action is required. The shared object list is still
+ valid. */
+ DO_NOTHING,
+
+ /* The shared object list should be reloaded entirely. */
+ FULL_RELOAD,
+
+ /* Attempt to incrementally update the shared object list. If
+ the update fails or is not possible, fall back to reloading
+ the list in full. */
+ UPDATE_OR_RELOAD,
+};
+
+/* solib_ops for SVR4 systems. */
+
+struct svr4_solib_ops : public solib_ops
+{
+ void relocate_section_addresses (solib &so, target_section *) const override;
+ void clear_so (const solib &so) const override;
+ void clear_solib (program_space *pspace) const override;
+ void create_inferior_hook (int from_tty) const override;
+ owning_intrusive_list<solib> current_sos () const override;
+ bool open_symbol_file_object (int from_tty) const override;
+ bool in_dynsym_resolve_code (CORE_ADDR pc) const override;
+ bool same (const solib &gdb, const solib &inferior) const override;
+ bool keep_data_in_core (CORE_ADDR vaddr, unsigned long size) const override;
+ void update_breakpoints () const override;
+ void handle_event () const override;
+ std::optional<CORE_ADDR> find_solib_addr (solib &so) const override;
+ bool supports_namespaces () const override { return true; }
+ int find_solib_ns (const solib &so) const override;
+ int num_active_namespaces () const override;
+ std::vector<const solib *> get_solibs_in_ns (int nsid) const override;
+
+ /* Return the appropriate link map offsets table for the architecture. */
+ virtual link_map_offsets *fetch_link_map_offsets () const = 0;
+
+ /* This needs to be public because it's accessed from an observer. */
+ void current_sos_direct (svr4_info *info) const;
+
+private:
+ void create_probe_breakpoints (svr4_info *info, gdbarch *gdbarch,
+ const std::vector<probe *> *probes,
+ objfile *objfile) const;
+ bool find_and_create_probe_breakpoints (svr4_info *info, gdbarch *gdbarch,
+ obj_section *os,
+ bool with_prefix) const;
+ void create_event_breakpoints (svr4_info *info, gdbarch *gdbarch,
+ CORE_ADDR address) const;
+ int enable_break (svr4_info *info, int from_tty) const;
+ bool is_default_namespace (CORE_ADDR debug_base) const;
+ void free_probes_table (svr4_info *info) const;
+ CORE_ADDR find_r_brk (svr4_info *info) const;
+ CORE_ADDR find_r_ldsomap (svr4_info *info) const;
+ owning_intrusive_list<solib> default_sos (svr4_info *info) const;
+ int read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
+ std::vector<svr4_so> &sos, int ignore_first) const;
+ lm_info_svr4_up read_lm_info (CORE_ADDR lm_addr) const;
+ int has_lm_dynamic_from_link_map () const;
+ CORE_ADDR lm_addr_check (const solib &so, bfd *abfd) const;
+ CORE_ADDR read_r_next (CORE_ADDR debug_base) const;
+ CORE_ADDR read_r_map (CORE_ADDR debug_base) const;
+ int parse_libraries (const char *document, svr4_library_list *list);
+ int current_sos_via_xfer_libraries (svr4_library_list *list,
+ const char *annex) const;
+ owning_intrusive_list<solib> collect_probes_sos (svr4_info *info) const;
+ owning_intrusive_list<solib> current_sos_1 (svr4_info *info) const;
+ owning_intrusive_list<solib> solibs_from_svr4_sos
+ (const std::vector<svr4_so> &sos) const;
+ void register_event_probe (objfile *objfile, probe *prob, CORE_ADDR address,
+ enum probe_action action) const;
+ void disable_probes_interface (svr4_info *info) const;
+ probe_and_action *event_probe_at (CORE_ADDR address) const;
+ void update_full (svr4_info *info) const;
+ int update_incremental (svr4_info *info, CORE_ADDR debug_base,
+ CORE_ADDR lm) const;
+ bool update_event_breakpoint (breakpoint *b) const;
+ CORE_ADDR find_debug_base (const solib *solib) const;
+};
+
+/* solib_ops for ILP32 SVR4 systems. */
+
+struct ilp32_svr4_solib_ops : public svr4_solib_ops
+{
+ link_map_offsets *fetch_link_map_offsets () const override;
+};
+
/* Critical offsets and sizes which describe struct r_debug and
struct link_map on SVR4-like targets. All offsets and sizes are
in bytes unless otherwise specified. */
@@ -91,26 +189,22 @@ struct link_map_offsets
int l_name_offset;
};
-/* set_solib_svr4_fetch_link_map_offsets() is intended to be called by
- a <arch>_gdbarch_init() function. It is used to establish an
- architecture specific link_map_offsets fetcher for the architecture
- being defined. */
+/* Set the gdbarch methods for SVR4 systems. */
-extern void set_solib_svr4_fetch_link_map_offsets
- (struct gdbarch *gdbarch, struct link_map_offsets *(*func) (void));
+extern void set_solib_svr4_ops (gdbarch *gdbarch,
+ gdbarch_make_solib_ops_ftype make_solib_ops);
/* This function is called by thread_db.c. Return the address of the
link map for the given objfile. */
extern CORE_ADDR svr4_fetch_objfile_link_map (struct objfile *objfile);
-/* Fetch (and possibly build) an appropriate `struct link_map_offsets'
- for ILP32 and LP64 SVR4 systems. */
-extern struct link_map_offsets *svr4_ilp32_fetch_link_map_offsets (void);
-extern struct link_map_offsets *svr4_lp64_fetch_link_map_offsets (void);
+/* Return a new solib_ops for ILP32 SVR4 systems. */
+
+extern solib_ops_up make_svr4_ilp32_solib_ops ();
+
+/* Return a new solib_ops for LP64 SVR4 systems. */
-/* Return 1 if PC lies in the dynamic symbol resolution code of the
- SVR4 run time loader. */
-int svr4_in_dynsym_resolve_code (CORE_ADDR pc);
+extern solib_ops_up make_svr4_lp64_solib_ops ();
/* For the MUSL C library, given link map address LM_ADDR, return the
corresponding TLS module id, or 0 if not found. */
diff --git a/gdb/solib-target.c b/gdb/solib-target.c
index f304431..770028d 100644
--- a/gdb/solib-target.c
+++ b/gdb/solib-target.c
@@ -18,7 +18,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "objfiles.h"
-#include "solist.h"
+#include "solib.h"
#include "symtab.h"
#include "symfile.h"
#include "target.h"
@@ -30,7 +30,7 @@
struct lm_info_target final : public lm_info
{
/* The library's name. The name is normally kept in the struct
- so_list; it is only here during XML parsing. */
+ solib; it is only here during XML parsing. */
std::string name;
/* The target can either specify segment bases or section bases, not
@@ -226,8 +226,8 @@ solib_target_parse_libraries (const char *library)
}
#endif
-static owning_intrusive_list<solib>
-solib_target_current_sos (void)
+owning_intrusive_list<solib>
+target_solib_ops::current_sos () const
{
owning_intrusive_list<solib> sos;
@@ -245,25 +245,20 @@ solib_target_current_sos (void)
/* Build a struct solib for each entry on the list. */
for (lm_info_target_up &info : library_list)
{
- auto &new_solib = sos.emplace_back ();
+ auto &new_solib = sos.emplace_back (*this);
/* We don't need a copy of the name in INFO anymore. */
- new_solib.so_name = std::move (info->name);
- new_solib.so_original_name = new_solib.so_name;
+ new_solib.name = std::move (info->name);
+ new_solib.original_name = new_solib.name;
new_solib.lm_info = std::move (info);
}
return sos;
}
-static void
-solib_target_solib_create_inferior_hook (int from_tty)
-{
- /* Nothing needed. */
-}
-
-static void
-solib_target_relocate_section_addresses (solib &so, target_section *sec)
+void
+target_solib_ops::relocate_section_addresses (solib &so,
+ target_section *sec) const
{
CORE_ADDR offset;
auto *li = gdb::checked_static_cast<lm_info_target *> (so.lm_info.get ());
@@ -291,7 +286,7 @@ solib_target_relocate_section_addresses (solib &so, target_section *sec)
if (num_alloc_sections != li->section_bases.size ())
warning (_("\
Could not relocate shared library \"%s\": wrong number of ALLOC sections"),
- so.so_name.c_str ());
+ so.name.c_str ());
else
{
int bases_index = 0;
@@ -334,7 +329,7 @@ Could not relocate shared library \"%s\": wrong number of ALLOC sections"),
if (data == NULL)
warning (_("\
-Could not relocate shared library \"%s\": no segments"), so.so_name.c_str ());
+Could not relocate shared library \"%s\": no segments"), so.name.c_str ());
else
{
ULONGEST orig_delta;
@@ -345,7 +340,7 @@ Could not relocate shared library \"%s\": no segments"), so.so_name.c_str ());
li->segment_bases.size (),
li->segment_bases.data ()))
warning (_("\
-Could not relocate shared library \"%s\": bad offsets"), so.so_name.c_str ());
+Could not relocate shared library \"%s\": bad offsets"), so.name.c_str ());
/* Find the range of addresses to report for this library in
"info sharedlibrary". Report any consecutive segments
@@ -382,16 +377,8 @@ Could not relocate shared library \"%s\": bad offsets"), so.so_name.c_str ());
sec->endaddr += offset;
}
-static int
-solib_target_open_symbol_file_object (int from_tty)
-{
- /* We can't locate the main symbol file based on the target's
- knowledge; the user has to specify it. */
- return 0;
-}
-
-static int
-solib_target_in_dynsym_resolve_code (CORE_ADDR pc)
+bool
+target_solib_ops::in_dynsym_resolve_code (CORE_ADDR pc) const
{
/* We don't have a range of addresses for the dynamic linker; there
may not be one in the program's address space. So only report
@@ -399,19 +386,10 @@ solib_target_in_dynsym_resolve_code (CORE_ADDR pc)
return in_plt_section (pc);
}
-const solib_ops solib_target_so_ops =
+/* See solib-target.h. */
+
+solib_ops_up
+make_target_solib_ops ()
{
- solib_target_relocate_section_addresses,
- nullptr,
- nullptr,
- solib_target_solib_create_inferior_hook,
- solib_target_current_sos,
- solib_target_open_symbol_file_object,
- solib_target_in_dynsym_resolve_code,
- solib_bfd_open,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- default_find_solib_addr,
-};
+ return std::make_unique<target_solib_ops> ();
+}
diff --git a/gdb/solib-target.h b/gdb/solib-target.h
index f8a22fd..89ae2bc 100644
--- a/gdb/solib-target.h
+++ b/gdb/solib-target.h
@@ -20,7 +20,19 @@
#ifndef GDB_SOLIB_TARGET_H
#define GDB_SOLIB_TARGET_H
-struct solib_ops;
-extern const solib_ops solib_target_so_ops;
+#include "solib.h"
+
+/* solib_ops for systems fetching solibs from the target. */
+
+struct target_solib_ops : solib_ops
+{
+ void relocate_section_addresses (solib &so, target_section *) const override;
+ owning_intrusive_list<solib> current_sos () const override;
+ bool in_dynsym_resolve_code (CORE_ADDR pc) const override;
+};
+
+/* Return a new solib_ops for systems fetching solibs from the target. */
+
+solib_ops_up make_target_solib_ops ();
#endif /* GDB_SOLIB_TARGET_H */
diff --git a/gdb/solib.c b/gdb/solib.c
index 85ec6bb..e43b1a3 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -37,7 +37,6 @@
#include "elf/common.h"
#include "filenames.h"
#include "exec.h"
-#include "solist.h"
#include "observable.h"
#include "readline/tilde.h"
#include "solib.h"
@@ -468,6 +467,12 @@ solib_bfd_open (const char *pathname)
return abfd;
}
+gdb_bfd_ref_ptr
+solib_ops::bfd_open (const char *pathname) const
+{
+ return solib_bfd_open (pathname);
+}
+
/* 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
@@ -483,10 +488,8 @@ solib_bfd_open (const char *pathname)
static int
solib_map_sections (solib &so)
{
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
-
- gdb::unique_xmalloc_ptr<char> filename (tilde_expand (so.so_name.c_str ()));
- gdb_bfd_ref_ptr abfd (ops->bfd_open (filename.get ()));
+ gdb::unique_xmalloc_ptr<char> filename (tilde_expand (so.name.c_str ()));
+ gdb_bfd_ref_ptr abfd (so.ops ().bfd_open (filename.get ()));
/* 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
@@ -496,9 +499,9 @@ solib_map_sections (solib &so)
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<CORE_ADDR> solib_addr = ops->find_solib_addr (so);
+ std::optional<CORE_ADDR> solib_addr = so.ops ().find_solib_addr (so);
std::optional <const core_target_mapped_file_info> mapped_file_info
- = core_target_find_mapped_file (so.so_name.c_str (), solib_addr);
+ = core_target_find_mapped_file (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
@@ -520,14 +523,14 @@ solib_map_sections (solib &so)
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 ());
+ abfd = so.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 ());
+ so.name.c_str ());
if (abfd == nullptr && mismatch)
{
@@ -545,14 +548,14 @@ solib_map_sections (solib &so)
/* Leave bfd open, core_xfer_memory and "info files" need it. */
so.abfd = std::move (abfd);
- /* Copy the full path name into so_name, allowing symbol_file_add
+ /* Copy the full path name into `so.name`, allowing symbol_file_add
to find it later. This also affects the =library-loaded GDB/MI
event, and in particular the part of that notification providing
the library's host-side path. If we let the target dictate
that objfile's path, and the target is different from the host,
GDB/MI will not provide the correct host-side path. */
- so.so_name = bfd_get_filename (so.abfd.get ());
+ so.name = bfd_get_filename (so.abfd.get ());
so.sections = build_section_table (so.abfd.get ());
for (target_section &p : so.sections)
@@ -560,7 +563,7 @@ solib_map_sections (solib &so)
/* Relocate the section binding addresses as recorded in the shared
object's file by the base address to which the object was actually
mapped. */
- ops->relocate_section_addresses (so, &p);
+ so.ops ().relocate_section_addresses (so, &p);
/* If the target didn't provide information about the address
range of the shared object, assume we want the location of
@@ -582,13 +585,11 @@ solib_map_sections (solib &so)
return 1;
}
-/* See solist.h. */
+/* See solib.h. */
void
solib::clear ()
{
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
-
this->sections.clear ();
this->abfd = nullptr;
@@ -600,11 +601,10 @@ solib::clear ()
/* Restore the target-supplied file name. SO_NAME may be the path
of the symbol file. */
- this->so_name = this->so_original_name;
+ this->name = this->original_name;
/* Do the same for target-specific data. */
- if (ops->clear_so != NULL)
- ops->clear_so (*this);
+ this->ops ().clear_so (*this);
}
lm_info::~lm_info () = default;
@@ -634,7 +634,7 @@ solib_read_symbols (solib &so, symfile_add_flags flags)
so.objfile = nullptr;
for (objfile *objfile : current_program_space->objfiles ())
{
- if (filename_cmp (objfile_name (objfile), so.so_name.c_str ())
+ if (filename_cmp (objfile_name (objfile), so.name.c_str ())
== 0
&& objfile->addr_low == so.addr_low)
{
@@ -648,7 +648,7 @@ solib_read_symbols (solib &so, symfile_add_flags flags)
= build_section_addr_info_from_section_table (so.sections);
gdb_bfd_ref_ptr tmp_bfd = so.abfd;
so.objfile
- = symbol_file_add_from_bfd (tmp_bfd, so.so_name.c_str (),
+ = symbol_file_add_from_bfd (tmp_bfd, so.name.c_str (),
flags, &sap, OBJF_SHARED, nullptr);
so.objfile->addr_low = so.addr_low;
}
@@ -660,7 +660,7 @@ solib_read_symbols (solib &so, symfile_add_flags flags)
exception_fprintf (gdb_stderr, e,
_ ("Error while reading shared"
" library symbols for %s:\n"),
- so.so_name.c_str ());
+ so.name.c_str ());
}
return true;
@@ -712,7 +712,10 @@ notify_solib_unloaded (program_space *pspace, const solib &so,
void
update_solib_list (int from_tty)
{
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
+ const solib_ops *ops = current_program_space->solib_ops ();
+
+ if (ops == nullptr)
+ return;
/* We can reach here due to changing solib-search-path or the
sysroot, before having any inferior. */
@@ -724,7 +727,7 @@ update_solib_list (int from_tty)
have not opened a symbol file, we may be able to get its
symbols now! */
if (inf->attach_flag
- && current_program_space->symfile_object_file == NULL)
+ && current_program_space->symfile_object_file == nullptr)
{
try
{
@@ -765,27 +768,16 @@ update_solib_list (int from_tty)
owning_intrusive_list<solib> inferior = ops->current_sos ();
owning_intrusive_list<solib>::iterator gdb_iter
- = current_program_space->so_list.begin ();
- while (gdb_iter != current_program_space->so_list.end ())
+ = current_program_space->solibs ().begin ();
+ while (gdb_iter != current_program_space->solibs ().end ())
{
intrusive_list<solib>::iterator inferior_iter = inferior.begin ();
/* Check to see whether the shared object *gdb also appears in
the inferior's current list. */
for (; inferior_iter != inferior.end (); ++inferior_iter)
- {
- if (ops->same)
- {
- if (ops->same (*gdb_iter, *inferior_iter))
- break;
- }
- else
- {
- if (!filename_cmp (gdb_iter->so_original_name.c_str (),
- inferior_iter->so_original_name.c_str ()))
- break;
- }
- }
+ if (ops->same (*gdb_iter, *inferior_iter))
+ break;
/* If the shared object appears on the inferior's list too, then
it's still loaded, so we don't need to do anything. Delete
@@ -814,13 +806,13 @@ update_solib_list (int from_tty)
&& !still_in_use)
gdb_iter->objfile->unlink ();
- current_program_space->deleted_solibs.push_back (gdb_iter->so_name);
+ current_program_space->deleted_solibs.push_back (gdb_iter->name);
/* Some targets' section tables might be referring to
sections from so.abfd; remove them. */
current_program_space->remove_target_sections (&*gdb_iter);
- gdb_iter = current_program_space->so_list.erase (gdb_iter);
+ gdb_iter = current_program_space->solibs ().erase (gdb_iter);
}
}
@@ -844,7 +836,7 @@ update_solib_list (int from_tty)
{
not_found++;
if (not_found_filename == NULL)
- not_found_filename = new_so.so_original_name.c_str ();
+ not_found_filename = new_so.original_name.c_str ();
}
}
@@ -861,7 +853,7 @@ update_solib_list (int from_tty)
}
/* Add the new shared objects to GDB's list. */
- current_program_space->so_list.splice (std::move (inferior));
+ current_program_space->solibs ().splice (std::move (inferior));
/* If a library was not found, issue an appropriate warning
message. We have to use a single call to warning in case the
@@ -918,7 +910,7 @@ libpthread_name_p (const char *name)
static bool
libpthread_solib_p (const solib &so)
{
- return libpthread_name_p (so.so_name.c_str ());
+ return libpthread_name_p (so.name.c_str ());
}
/* Read in symbolic information for any shared objects whose names
@@ -968,7 +960,7 @@ solib_add (const char *pattern, int from_tty, int readsyms)
add_flags |= SYMFILE_VERBOSE;
for (solib &gdb : current_program_space->solibs ())
- if (!pattern || re_exec (gdb.so_name.c_str ()))
+ if (!pattern || re_exec (gdb.name.c_str ()))
{
/* Normally, we would read the symbols from that library
only if READSYMS is set. However, we're making a small
@@ -987,7 +979,7 @@ solib_add (const char *pattern, int from_tty, int readsyms)
if (pattern && (from_tty || info_verbose))
gdb_printf (_ ("Symbols already loaded for %ps\n"),
styled_string (file_name_style.style (),
- gdb.so_name.c_str ()));
+ gdb.name.c_str ()));
}
else if (solib_read_symbols (gdb, add_flags))
loaded_any_symbols = true;
@@ -1025,16 +1017,21 @@ print_solib_list_table (std::vector<const solib *> solib_list,
gdbarch *gdbarch = current_inferior ()->arch ();
/* "0x", a little whitespace, and two hex digits per byte of pointers. */
int addr_width = 4 + (gdbarch_ptr_bit (gdbarch) / 4);
- const solib_ops *ops = gdbarch_so_ops (gdbarch);
+ const solib_ops *ops = current_program_space->solib_ops ();
struct ui_out *uiout = current_uiout;
bool so_missing_debug_info = false;
+ if (ops == nullptr)
+ return;
+
/* There are 3 conditions for this command to print solib namespaces,
first PRINT_NAMESPACE has to be true, second the solib_ops has to
support multiple namespaces, and third there must be more than one
active namespace. Fold all these into the PRINT_NAMESPACE condition. */
- print_namespace = print_namespace && ops->num_active_namespaces != nullptr
- && ops->num_active_namespaces () > 1;
+ print_namespace = (print_namespace
+ && ops != nullptr
+ && ops->supports_namespaces ()
+ && ops->num_active_namespaces () > 1);
int num_cols = 4;
if (print_namespace)
@@ -1056,7 +1053,7 @@ print_solib_list_table (std::vector<const solib *> solib_list,
for (const solib *so : solib_list)
{
- if (so->so_name.empty ())
+ if (so->name.empty ())
continue;
ui_out_emit_tuple tuple_emitter (uiout, "lib");
@@ -1085,7 +1082,7 @@ print_solib_list_table (std::vector<const solib *> solib_list,
}
if (!top_level_interpreter ()->interp_ui_out ()->is_mi_like_p ()
- && so->symbols_loaded && !objfile_has_symbols (so->objfile))
+ && so->symbols_loaded && !so->objfile->has_symbols ())
{
so_missing_debug_info = true;
uiout->field_string ("syms-read", "Yes (*)");
@@ -1093,7 +1090,7 @@ print_solib_list_table (std::vector<const solib *> solib_list,
else
uiout->field_string ("syms-read", so->symbols_loaded ? "Yes" : "No");
- uiout->field_string ("name", so->so_name, file_name_style.style ());
+ uiout->field_string ("name", so->name, file_name_style.style ());
uiout->text ("\n");
}
@@ -1130,9 +1127,9 @@ info_sharedlibrary_command (const char *pattern, int from_tty)
std::vector<const solib *> print_libs;
for (const solib &so : current_program_space->solibs ())
{
- if (!so.so_name.empty ())
+ if (!so.name.empty ())
{
- if (pattern && !re_exec (so.so_name.c_str ()))
+ if (pattern && !re_exec (so.name.c_str ()))
continue;
print_libs.push_back (&so);
}
@@ -1159,12 +1156,13 @@ info_sharedlibrary_command (const char *pattern, int from_tty)
static void
info_linker_namespace_command (const char *pattern, int from_tty)
{
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
+ const solib_ops *ops = current_program_space->solib_ops ();
+
/* This command only really makes sense for inferiors that support
linker namespaces, so we can leave early. */
- if (ops->num_active_namespaces == nullptr)
- error (_("Current inferior does not support linker namespaces." \
- "Use \"info sharedlibrary\" instead"));
+ if (ops == nullptr || !ops->supports_namespaces ())
+ error (_("Current inferior does not support linker namespaces. "
+ "Use \"info sharedlibrary\" instead."));
struct ui_out *uiout = current_uiout;
std::vector<std::pair<int, std::vector<const solib *>>> all_solibs_to_print;
@@ -1265,24 +1263,28 @@ solib_contains_address_p (const solib &solib, CORE_ADDR address)
const char *
solib_name_from_address (struct program_space *pspace, CORE_ADDR address)
{
- for (const solib &so : pspace->so_list)
+ for (const solib &so : pspace->solibs ())
if (solib_contains_address_p (so, address))
- return so.so_name.c_str ();
+ return so.name.c_str ();
return nullptr;
}
+bool
+solib_ops::same (const solib &a, const solib &b) const
+{
+ return (filename_cmp (a.original_name.c_str (), b.original_name.c_str ())
+ == 0);
+}
+
/* See solib.h. */
bool
solib_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
{
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
+ const solib_ops *ops = current_program_space->solib_ops ();
- if (ops->keep_data_in_core)
- return ops->keep_data_in_core (vaddr, size) != 0;
- else
- return false;
+ return ops != nullptr && ops->keep_data_in_core (vaddr, size);
}
/* See solib.h. */
@@ -1290,9 +1292,7 @@ solib_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
void
clear_solib (program_space *pspace)
{
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
-
- for (solib &so : pspace->so_list)
+ for (solib &so : pspace->solibs ())
{
bool still_in_use
= (so.objfile != nullptr && solib_used (pspace, so));
@@ -1301,9 +1301,10 @@ clear_solib (program_space *pspace)
pspace->remove_target_sections (&so);
};
- pspace->so_list.clear ();
+ pspace->solibs ().clear ();
- if (ops->clear_solib != nullptr)
+ if (const solib_ops *ops = pspace->solib_ops ();
+ ops != nullptr)
ops->clear_solib (pspace);
}
@@ -1315,9 +1316,9 @@ clear_solib (program_space *pspace)
void
solib_create_inferior_hook (int from_tty)
{
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
-
- ops->solib_create_inferior_hook (from_tty);
+ if (const solib_ops *ops = current_program_space->solib_ops ();
+ ops != nullptr)
+ ops->create_inferior_hook (from_tty);
}
/* See solib.h. */
@@ -1325,9 +1326,9 @@ solib_create_inferior_hook (int from_tty)
bool
in_solib_dynsym_resolve_code (CORE_ADDR pc)
{
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
+ const solib_ops *ops = current_program_space->solib_ops ();
- return ops->in_dynsym_resolve_code (pc) != 0;
+ return ops != nullptr && ops->in_dynsym_resolve_code (pc);
}
/* Implements the "sharedlibrary" command. */
@@ -1369,9 +1370,9 @@ no_shared_libraries_command (const char *ignored, int from_tty)
void
update_solib_breakpoints (void)
{
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
+ const solib_ops *ops = current_program_space->solib_ops ();
- if (ops->update_breakpoints != NULL)
+ if (ops != nullptr)
ops->update_breakpoints ();
}
@@ -1380,9 +1381,8 @@ update_solib_breakpoints (void)
void
handle_solib_event (void)
{
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
-
- if (ops->handle_event != NULL)
+ if (const solib_ops *ops = current_program_space->solib_ops ();
+ ops != nullptr)
ops->handle_event ();
current_inferior ()->pspace->clear_solib_cache ();
@@ -1414,8 +1414,9 @@ reload_shared_libraries_1 (int from_tty)
add_flags |= SYMFILE_VERBOSE;
gdb::unique_xmalloc_ptr<char> filename (
- tilde_expand (so.so_original_name.c_str ()));
- gdb_bfd_ref_ptr abfd (solib_bfd_open (filename.get ()));
+ tilde_expand (so.original_name.c_str ()));
+
+ gdb_bfd_ref_ptr abfd = so.ops ().bfd_open (filename.get ());
if (abfd != NULL)
found_pathname = bfd_get_filename (abfd.get ());
@@ -1423,7 +1424,7 @@ reload_shared_libraries_1 (int from_tty)
symbol file, close that. */
if ((found_pathname == NULL && was_loaded)
|| (found_pathname != NULL
- && filename_cmp (found_pathname, so.so_name.c_str ()) != 0))
+ && filename_cmp (found_pathname, so.name.c_str ()) != 0))
{
if (so.objfile && !(so.objfile->flags & OBJF_USERLOADED)
&& !solib_used (current_program_space, so))
@@ -1436,7 +1437,7 @@ reload_shared_libraries_1 (int from_tty)
file, open it. */
if (found_pathname != NULL
&& (!was_loaded
- || filename_cmp (found_pathname, so.so_name.c_str ()) != 0))
+ || filename_cmp (found_pathname, so.name.c_str ()) != 0))
{
bool got_error = false;
@@ -1466,8 +1467,6 @@ reload_shared_libraries (const char *ignored, int from_tty,
{
reload_shared_libraries_1 (from_tty);
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
-
/* Creating inferior hooks here has two purposes. First, if we reload
shared libraries then the address of solib breakpoint we've computed
previously might be no longer valid. For example, if we forgot to set
@@ -1480,8 +1479,9 @@ reload_shared_libraries (const char *ignored, int from_tty,
if (target_has_execution ())
{
/* Reset or free private data structures not associated with
- so_list entries. */
- if (ops->clear_solib != nullptr)
+ solib entries. */
+ if (const solib_ops *ops = current_program_space->solib_ops ();
+ ops != nullptr)
ops->clear_solib (current_program_space);
/* Remove any previous solib event breakpoint. This is usually
@@ -1808,56 +1808,42 @@ remove_user_added_objfile (struct objfile *objfile)
}
}
-/* See solist.h. */
+/* Implementation of the linker_namespace convenience variable.
-std::optional<CORE_ADDR>
-default_find_solib_addr (solib &so)
-{
- return {};
-}
-
-/* Implementation of the current_linker_namespace convenience variable.
This returns the GDB internal identifier of the linker namespace,
- for the current frame, in the form '[[<number>]]'. If the inferior
- doesn't support linker namespaces, this always returns [[0]]. */
+ for the selected frame, as an integer. If the inferior doesn't support
+ linker namespaces, this always returns 0. */
static value *
-current_linker_namespace_make_value (gdbarch *gdbarch, internalvar *var,
+linker_namespace_make_value (gdbarch *gdbarch, internalvar *var,
void *ignore)
{
- const solib_ops *ops = gdbarch_so_ops (gdbarch);
- const language_defn *lang = language_def (get_frame_language
- (get_current_frame ()));
- std::string nsid = "[[0]]";
- if (ops->find_solib_ns != nullptr)
- {
- CORE_ADDR curr_pc = get_frame_pc (get_current_frame ());
- for (const solib &so : current_program_space->solibs ())
- if (solib_contains_address_p (so, curr_pc))
- {
- nsid = string_printf ("[[%d]]", ops->find_solib_ns (so));
- break;
- }
- }
+ int nsid = 0;
+ CORE_ADDR curr_pc = get_frame_pc (get_selected_frame ());
+
+ for (const solib &so : current_program_space->solibs ())
+ if (solib_contains_address_p (so, curr_pc))
+ {
+ if (so.ops ().supports_namespaces ())
+ nsid = so.ops ().find_solib_ns (so);
+ break;
+ }
/* If the PC is not in an SO, or the solib_ops doesn't support
linker namespaces, the inferior is in the default namespace. */
- return lang->value_string (gdbarch, nsid.c_str (), nsid.length ());
+ return value_from_longest (builtin_type (gdbarch)->builtin_int, nsid);
}
-/* Implementation of `$_current_linker_namespace' variable. */
+/* Implementation of `$_linker_namespace' variable. */
-static const struct internalvar_funcs current_linker_namespace_funcs =
+static const struct internalvar_funcs linker_namespace_funcs =
{
- current_linker_namespace_make_value,
+ linker_namespace_make_value,
nullptr,
};
-void _initialize_solib ();
-
-void
-_initialize_solib ()
+INIT_GDB_FILE (solib)
{
gdb::observers::free_objfile.attach (remove_user_added_objfile, "solib");
gdb::observers::inferior_execd.attach (
@@ -1869,8 +1855,8 @@ _initialize_solib ()
/* Convenience variables for debugging linker namespaces. These are
set here, even if the solib_ops doesn't support them,
for consistency. */
- create_internalvar_type_lazy ("_current_linker_namespace",
- &current_linker_namespace_funcs, nullptr);
+ create_internalvar_type_lazy ("_linker_namespace",
+ &linker_namespace_funcs, nullptr);
set_internalvar_integer (lookup_internalvar ("_active_linker_namespaces"), 1);
add_com (
diff --git a/gdb/solib.h b/gdb/solib.h
index 360b6ef..b9465e1 100644
--- a/gdb/solib.h
+++ b/gdb/solib.h
@@ -20,15 +20,14 @@
#ifndef GDB_SOLIB_H
#define GDB_SOLIB_H
-/* Forward decl's for prototypes */
-struct solib;
-struct target_ops;
-struct solib_ops;
-struct program_space;
-
#include "gdb_bfd.h"
-#include "symfile-add-flags.h"
#include "gdbsupport/function-view.h"
+#include "gdbsupport/intrusive_list.h"
+#include "gdbsupport/owning_intrusive_list.h"
+#include "symfile-add-flags.h"
+#include "target-section.h"
+
+struct program_space;
/* Value of the 'set debug solib' configuration variable. */
@@ -42,6 +41,243 @@ extern bool debug_solib;
#define SOLIB_SCOPED_DEBUG_START_END(fmt, ...) \
scoped_debug_start_end (debug_solib, "solib", fmt, ##__VA_ARGS__)
+#define SO_NAME_MAX_PATH_SIZE 512 /* FIXME: Should be dynamic */
+
+/* Base class for target-specific link map information. */
+
+struct lm_info
+{
+ lm_info () = default;
+ lm_info (const lm_info &) = default;
+ virtual ~lm_info () = 0;
+};
+
+using lm_info_up = std::unique_ptr<lm_info>;
+
+struct solib_ops;
+
+struct solib : intrusive_list_node<solib>
+{
+ /* Constructor
+
+ OPS is the solib_ops implementation providing this solib. */
+ explicit solib (const solib_ops &ops) : m_ops (&ops) {}
+
+ /* Return the solib_ops implementation providing this solib. */
+ const solib_ops &ops () const
+ { return *m_ops; }
+
+ /* Free symbol-file related contents of SO and reset for possible reloading
+ of SO. If we have opened a BFD for SO, close it. If we have placed SO's
+ sections in some target's section table, the caller is responsible for
+ removing them.
+
+ This function doesn't mess with objfiles at all. If there is an
+ objfile associated with SO that needs to be removed, the caller is
+ responsible for taking care of that. */
+ void clear () ;
+
+ /* The following fields of the structure come directly from the
+ dynamic linker's tables in the inferior, and are initialized by
+ current_sos. */
+
+ /* A pointer to target specific link map information. Often this
+ will be a copy of struct link_map from the user process, but
+ it need not be; it can be any collection of data needed to
+ traverse the dynamic linker's data structures. */
+ lm_info_up lm_info;
+
+ /* Shared object file name, exactly as it appears in the
+ inferior's link map. This may be a relative path, or something
+ which needs to be looked up in LD_LIBRARY_PATH, etc. We use it
+ to tell which entries in the inferior's dynamic linker's link
+ map we've already loaded. */
+ std::string original_name;
+
+ /* Shared object file name, expanded to something GDB can open. */
+ std::string name;
+
+ /* The following fields of the structure are built from
+ information gathered from the shared object file itself, and
+ are set when we actually add it to our symbol tables.
+
+ current_sos must initialize these fields to 0. */
+
+ gdb_bfd_ref_ptr abfd;
+
+ /* True if symbols have been read in. */
+ bool symbols_loaded = false;
+
+ /* objfile with symbols for a loaded library. Target memory is read from
+ ABFD. OBJFILE may be NULL either before symbols have been loaded, if
+ the file cannot be found or after the command "nosharedlibrary". */
+ struct objfile *objfile = nullptr;
+
+ std::vector<target_section> sections;
+
+ /* Record the range of addresses belonging to this shared library.
+ There may not be just one (e.g. if two segments are relocated
+ differently). This is used for "info sharedlibrary" and
+ the MI command "-file-list-shared-libraries". The latter has a format
+ that supports outputting multiple segments once the related code
+ supports them. */
+ CORE_ADDR addr_low = 0, addr_high = 0;
+
+private:
+ /* The solib_ops responsible for this solib. */
+ const solib_ops *m_ops;
+};
+
+/* A unique pointer to an solib. */
+using solib_up = std::unique_ptr<solib>;
+
+struct solib_ops
+{
+ virtual ~solib_ops () = default;
+
+ /* Adjust the section binding addresses by the base address at
+ which the object was actually mapped. */
+ virtual void relocate_section_addresses (solib &so, target_section *) const
+ = 0;
+
+ /* Reset private data structures associated with SO.
+ This is called when SO is about to be reloaded.
+ It is also called when SO is about to be freed.
+
+ Defaults to no-op. */
+ virtual void clear_so (const solib &so) const {}
+
+ /* Free private data structures associated to PSPACE. This method
+ should not free resources associated to individual solib entries,
+ those are cleared by the clear_so method.
+
+ Defaults to no-op. */
+ virtual void clear_solib (program_space *pspace) const {}
+
+ /* Target dependent code to run after child process fork.
+
+ Defaults to no-op. */
+ virtual void create_inferior_hook (int from_tty) const {};
+
+ /* Construct a list of the currently loaded shared objects. This
+ list does not include an entry for the main executable file.
+
+ Note that we only gather information directly available from the
+ inferior --- we don't examine any of the shared library files
+ themselves. The declaration of `struct solib' says which fields
+ we provide values for. */
+ virtual owning_intrusive_list<solib> current_sos () const = 0;
+
+ /* Find, open, and read the symbols for the main executable. If
+ FROM_TTY is non-zero, allow messages to be printed.
+
+ Return true if this was done successfully. Defaults to false. */
+ virtual bool open_symbol_file_object (int from_tty) const { return false; }
+
+ /* Determine if PC lies in the dynamic symbol resolution code of
+ the run time loader.
+
+ Defaults to false. */
+ virtual bool in_dynsym_resolve_code (CORE_ADDR pc) const
+ { return false; };
+
+ /* Find and open shared library binary file. */
+ virtual gdb_bfd_ref_ptr bfd_open (const char *pathname) const;
+
+ /* Given two solib objects, GDB from the GDB thread list and INFERIOR from the
+ list returned by current_sos, return true if they represent the same library.
+
+ Defaults to comparing the solib original names using filename_cmp. */
+ virtual bool same (const solib &gdb, const solib &inferior) const;
+
+ /* Return whether a region of memory must be kept in a core file
+ for shared libraries loaded before "gcore" is used to be
+ handled correctly when the core file is loaded. This only
+ applies when the section would otherwise not be kept in the
+ core file (in particular, for readonly sections).
+
+ Defaults to false. */
+ virtual bool keep_data_in_core (CORE_ADDR vaddr, unsigned long size) const
+ { return false; };
+
+ /* Enable or disable optional solib event breakpoints as appropriate. This
+ should be called whenever stop_on_solib_events is changed.
+
+ Defaults to no-op. */
+ virtual void update_breakpoints () const {};
+
+ /* Target-specific processing of solib events that will be performed before
+ solib_add is called.
+
+ Defaults to no-op. */
+ virtual void handle_event () const {};
+
+ /* 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).
+
+ The default implementation of returns an empty option, indicating GDB is
+ unable to find an address within the library SO. */
+ virtual std::optional<CORE_ADDR> find_solib_addr (solib &so) const
+ { return {}; };
+
+ /* Return true if the linker or libc supports linkage namespaces.
+
+ Defaults to false. */
+ virtual bool supports_namespaces () const { return false; }
+
+ /* Return which linker namespace contains SO.
+
+ The supports_namespaces method must return true for this to be
+ called.
+
+ Throw an error if the namespace can not be determined (such as when we're
+ stepping though the dynamic linker). */
+ virtual int find_solib_ns (const solib &so) const
+ { gdb_assert_not_reached ("namespaces not supported"); }
+
+ /* Returns the number of active namespaces in the inferior.
+
+ The supports_namespaces method must return true for this to be called. */
+ virtual int num_active_namespaces () const
+ { gdb_assert_not_reached ("namespaces not supported"); }
+
+ /* Returns all solibs for a given namespace. If the namespace is not
+ active, returns an empty vector.
+
+ The supports_namespaces method must return true for this to be called. */
+ virtual std::vector<const solib *> get_solibs_in_ns (int ns) const
+ { gdb_assert_not_reached ("namespaces not supported"); }
+};
+
+/* A unique pointer to an solib_ops. */
+using solib_ops_up = std::unique_ptr<solib_ops>;
+
+/* Find main executable binary file. */
+extern gdb::unique_xmalloc_ptr<char> exec_file_find (const char *in_pathname,
+ int *fd);
+
+/* Find shared library binary file. */
+extern gdb::unique_xmalloc_ptr<char> solib_find (const char *in_pathname,
+ int *fd);
+
+/* Open BFD for shared library file. */
+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);
+
/* Called when we free all symtabs of PSPACE, to free the shared library
information as well. */
@@ -89,7 +325,8 @@ extern void no_shared_libraries (program_space *pspace);
Extract the list of currently loaded shared objects from the
inferior, and compare it with the list of shared objects in the
current program space's list of shared libraries. Edit
- so_list_head to bring it in sync with the inferior's new list.
+ the current program space's solib list to bring it in sync with the
+ inferior's new list.
If we notice that the inferior has unloaded some shared objects,
free any symbolic info GDB had read about those shared objects.
diff --git a/gdb/solist.h b/gdb/solist.h
deleted file mode 100644
index 6ab5a06..0000000
--- a/gdb/solist.h
+++ /dev/null
@@ -1,225 +0,0 @@
-/* Shared library declarations for GDB, the GNU Debugger.
- Copyright (C) 1990-2025 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef GDB_SOLIST_H
-#define GDB_SOLIST_H
-
-#define SO_NAME_MAX_PATH_SIZE 512 /* FIXME: Should be dynamic */
-
-/* For domain_enum domain. */
-#include "symtab.h"
-#include "gdb_bfd.h"
-#include "gdbsupport/owning_intrusive_list.h"
-#include "target-section.h"
-
-/* Base class for target-specific link map information. */
-
-struct lm_info
-{
- lm_info () = default;
- lm_info (const lm_info &) = default;
- virtual ~lm_info () = 0;
-};
-
-using lm_info_up = std::unique_ptr<lm_info>;
-
-struct solib : intrusive_list_node<solib>
-{
- /* Free symbol-file related contents of SO and reset for possible reloading
- of SO. If we have opened a BFD for SO, close it. If we have placed SO's
- sections in some target's section table, the caller is responsible for
- removing them.
-
- This function doesn't mess with objfiles at all. If there is an
- objfile associated with SO that needs to be removed, the caller is
- responsible for taking care of that. */
- void clear () ;
-
- /* The following fields of the structure come directly from the
- dynamic linker's tables in the inferior, and are initialized by
- current_sos. */
-
- /* A pointer to target specific link map information. Often this
- will be a copy of struct link_map from the user process, but
- it need not be; it can be any collection of data needed to
- traverse the dynamic linker's data structures. */
- lm_info_up lm_info;
-
- /* Shared object file name, exactly as it appears in the
- inferior's link map. This may be a relative path, or something
- which needs to be looked up in LD_LIBRARY_PATH, etc. We use it
- to tell which entries in the inferior's dynamic linker's link
- map we've already loaded. */
- std::string so_original_name;
-
- /* Shared object file name, expanded to something GDB can open. */
- std::string so_name;
-
- /* The following fields of the structure are built from
- information gathered from the shared object file itself, and
- are set when we actually add it to our symbol tables.
-
- current_sos must initialize these fields to 0. */
-
- gdb_bfd_ref_ptr abfd;
-
- /* True if symbols have been read in. */
- bool symbols_loaded = false;
-
- /* objfile with symbols for a loaded library. Target memory is read from
- ABFD. OBJFILE may be NULL either before symbols have been loaded, if
- the file cannot be found or after the command "nosharedlibrary". */
- struct objfile *objfile = nullptr;
-
- std::vector<target_section> sections;
-
- /* Record the range of addresses belonging to this shared library.
- There may not be just one (e.g. if two segments are relocated
- differently). This is used for "info sharedlibrary" and
- the MI command "-file-list-shared-libraries". The latter has a format
- that supports outputting multiple segments once the related code
- supports them. */
- CORE_ADDR addr_low = 0, addr_high = 0;
-};
-
-struct solib_ops
-{
- /* Adjust the section binding addresses by the base address at
- which the object was actually mapped. */
- void (*relocate_section_addresses) (solib &so, target_section *);
-
- /* Reset private data structures associated with SO.
- This is called when SO is about to be reloaded.
- It is also called when SO is about to be freed. */
- void (*clear_so) (const solib &so);
-
- /* Free private data structures associated to PSPACE. This method
- should not free resources associated to individual so_list entries,
- those are cleared by the clear_so method. */
- void (*clear_solib) (program_space *pspace);
-
- /* Target dependent code to run after child process fork. */
- void (*solib_create_inferior_hook) (int from_tty);
-
- /* Construct a list of the currently loaded shared objects. This
- list does not include an entry for the main executable file.
-
- Note that we only gather information directly available from the
- inferior --- we don't examine any of the shared library files
- themselves. The declaration of `struct solib' says which fields
- we provide values for. */
- owning_intrusive_list<solib> (*current_sos) ();
-
- /* Find, open, and read the symbols for the main executable. If
- FROM_TTY is non-zero, allow messages to be printed. */
- int (*open_symbol_file_object) (int from_ttyp);
-
- /* Determine if PC lies in the dynamic symbol resolution code of
- the run time loader. */
- int (*in_dynsym_resolve_code) (CORE_ADDR pc);
-
- /* Find and open shared library binary file. */
- gdb_bfd_ref_ptr (*bfd_open) (const char *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.
- Falls back to using strcmp on so_original_name field when set
- to NULL. */
- int (*same) (const solib &gdb, const solib &inferior);
-
- /* Return whether a region of memory must be kept in a core file
- for shared libraries loaded before "gcore" is used to be
- handled correctly when the core file is loaded. This only
- applies when the section would otherwise not be kept in the
- core file (in particular, for readonly sections). */
- int (*keep_data_in_core) (CORE_ADDR vaddr,
- unsigned long size);
-
- /* Enable or disable optional solib event breakpoints as
- appropriate. This should be called whenever
- stop_on_solib_events is changed. This pointer can be
- NULL, in which case no enabling or disabling is necessary
- for this target. */
- void (*update_breakpoints) (void);
-
- /* Target-specific processing of solib events that will be
- performed before solib_add is called. This pointer can be
- 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<CORE_ADDR> (*find_solib_addr) (solib &so);
-
- /* Return which linker namespace contains the current so.
- If the linker or libc does not support linkage namespaces at all
- (which is basically all of them but solib-svr4), this function should
- be set to nullptr, so that "info shared" won't add an unnecessary
- column.
-
- If the namespace can not be determined (such as when we're stepping
- though the dynamic linker), this function should throw a
- gdb_exception_error. */
- int (*find_solib_ns) (const solib &so);
-
- /* Returns the number of active namespaces in the inferior. */
- int (*num_active_namespaces) ();
-
- /* Returns all solibs for a given namespace. If the namespace is not
- active, returns an empty vector. */
- std::vector<const solib *> (*get_solibs_in_ns) (int ns);
-};
-
-/* A unique pointer to a so_list. */
-using solib_up = std::unique_ptr<solib>;
-
-/* Find main executable binary file. */
-extern gdb::unique_xmalloc_ptr<char> exec_file_find (const char *in_pathname,
- int *fd);
-
-/* Find shared library binary file. */
-extern gdb::unique_xmalloc_ptr<char> solib_find (const char *in_pathname,
- int *fd);
-
-/* Open BFD for shared library file. */
-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<CORE_ADDR> indicating GDB is
- unable to find an address within the library SO. */
-extern std::optional<CORE_ADDR> default_find_solib_addr (solib &so);
-
-#endif /* GDB_SOLIST_H */
diff --git a/gdb/source-cache.c b/gdb/source-cache.c
index ebe451d..9d5151a 100644
--- a/gdb/source-cache.c
+++ b/gdb/source-cache.c
@@ -511,9 +511,7 @@ static void extract_lines_test ()
}
#endif
-void _initialize_source_cache ();
-void
-_initialize_source_cache ()
+INIT_GDB_FILE (source_cache)
{
add_cmd ("source-cache", class_maintenance, source_cache_flush_command,
_("Force gdb to flush its source code cache."),
diff --git a/gdb/source.c b/gdb/source.c
index 13cb8d6..0fd370b 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -1910,9 +1910,7 @@ source_lines_range::source_lines_range (int startline,
}
-void _initialize_source ();
-void
-_initialize_source ()
+INIT_GDB_FILE (source)
{
init_source_path ();
diff --git a/gdb/sparc-linux-nat.c b/gdb/sparc-linux-nat.c
index 8dccce9..18db599 100644
--- a/gdb/sparc-linux-nat.c
+++ b/gdb/sparc-linux-nat.c
@@ -65,9 +65,7 @@ fill_fpregset (const struct regcache *regcache,
sparc32_collect_fpregset (sparc_fpregmap, regcache, regnum, fpregs);
}
-void _initialize_sparc_linux_nat ();
-void
-_initialize_sparc_linux_nat ()
+INIT_GDB_FILE (sparc_linux_nat)
{
sparc_fpregmap = &sparc32_bsd_fpregmap;
diff --git a/gdb/sparc-linux-tdep.c b/gdb/sparc-linux-tdep.c
index 27706b7..6e23fdd 100644
--- a/gdb/sparc-linux-tdep.c
+++ b/gdb/sparc-linux-tdep.c
@@ -33,6 +33,7 @@
#include "tramp-frame.h"
#include "xml-syscall.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
/* The syscall's XML filename for sparc 32-bit. */
#define XML_SYSCALL_FILENAME_SPARC32 "syscalls/sparc-linux.xml"
@@ -436,8 +437,7 @@ sparc32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* GNU/Linux has SVR4-style shared libraries... */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
/* ...which means that we need some special handling when doing
prologue analysis. */
@@ -466,9 +466,7 @@ sparc32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
sparc32_linux_gdb_signal_to_target);
}
-void _initialize_sparc_linux_tdep ();
-void
-_initialize_sparc_linux_tdep ()
+INIT_GDB_FILE (sparc_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_LINUX,
sparc32_linux_init_abi);
diff --git a/gdb/sparc-nat.c b/gdb/sparc-nat.c
index c2d3833..1219612 100644
--- a/gdb/sparc-nat.c
+++ b/gdb/sparc-nat.c
@@ -309,9 +309,7 @@ sparc_xfer_wcookie (enum target_object object,
}
-void _initialize_sparc_nat ();
-void
-_initialize_sparc_nat ()
+INIT_GDB_FILE (sparc_nat)
{
/* Default to using SunOS 4 register sets. */
if (sparc_gregmap == NULL)
diff --git a/gdb/sparc-netbsd-nat.c b/gdb/sparc-netbsd-nat.c
index 8eee741..54cba0b 100644
--- a/gdb/sparc-netbsd-nat.c
+++ b/gdb/sparc-netbsd-nat.c
@@ -56,9 +56,7 @@ sparc32nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
static sparc_target<inf_ptrace_target> the_sparc_nbsd_nat_target;
-void _initialize_sparcnbsd_nat ();
-void
-_initialize_sparcnbsd_nat ()
+INIT_GDB_FILE (sparcnbsd_nat)
{
sparc_gregmap = &sparc32nbsd_gregmap;
sparc_fpregmap = &sparc32_bsd_fpregmap;
diff --git a/gdb/sparc-netbsd-tdep.c b/gdb/sparc-netbsd-tdep.c
index 84e3a97..8e8a1ba 100644
--- a/gdb/sparc-netbsd-tdep.c
+++ b/gdb/sparc-netbsd-tdep.c
@@ -313,13 +313,10 @@ sparc32nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
frame_unwind_append_unwinder (gdbarch, &sparc32nbsd_sigcontext_frame_unwind);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
}
-void _initialize_sparcnbsd_tdep ();
-void
-_initialize_sparcnbsd_tdep ()
+INIT_GDB_FILE (sparcnbsd_tdep)
{
gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_NETBSD,
sparc32nbsd_init_abi);
diff --git a/gdb/sparc-obsd-tdep.c b/gdb/sparc-obsd-tdep.c
index 3486799..ff6e915 100644
--- a/gdb/sparc-obsd-tdep.c
+++ b/gdb/sparc-obsd-tdep.c
@@ -254,9 +254,7 @@ sparc32obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
bsd_uthread_set_collect_uthread (gdbarch, sparc32obsd_collect_uthread);
}
-void _initialize_sparc32obsd_tdep ();
-void
-_initialize_sparc32obsd_tdep ()
+INIT_GDB_FILE (sparc32obsd_tdep)
{
gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_OPENBSD,
sparc32obsd_init_abi);
diff --git a/gdb/sparc-sol2-tdep.c b/gdb/sparc-sol2-tdep.c
index 5c6085a..337b929 100644
--- a/gdb/sparc-sol2-tdep.c
+++ b/gdb/sparc-sol2-tdep.c
@@ -207,8 +207,7 @@ sparc32_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* Solaris has SVR4-style shared libraries... */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
/* ...which means that we need some special handling when doing
prologue analysis. */
@@ -220,9 +219,7 @@ sparc32_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
frame_unwind_append_unwinder (gdbarch, &sparc32_sol2_sigtramp_frame_unwind);
}
-void _initialize_sparc_sol2_tdep ();
-void
-_initialize_sparc_sol2_tdep ()
+INIT_GDB_FILE (sparc_sol2_tdep)
{
gdbarch_register_osabi (bfd_arch_sparc, 0,
GDB_OSABI_SOLARIS, sparc32_sol2_init_abi);
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index 80914d9..4a12516 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -2264,9 +2264,7 @@ const struct sparc_fpregmap sparc32_bsd_fpregmap =
32 * 4, /* %fsr */
};
-void _initialize_sparc_tdep ();
-void
-_initialize_sparc_tdep ()
+INIT_GDB_FILE (sparc_tdep)
{
gdbarch_register (bfd_arch_sparc, sparc32_gdbarch_init);
}
diff --git a/gdb/sparc64-fbsd-nat.c b/gdb/sparc64-fbsd-nat.c
index 4848c77..d697841 100644
--- a/gdb/sparc64-fbsd-nat.c
+++ b/gdb/sparc64-fbsd-nat.c
@@ -61,9 +61,7 @@ sparc64fbsd_kvm_supply_pcb (struct regcache *regcache, struct pcb *pcb)
/* Add some extra features to the generic SPARC target. */
static sparc_target<fbsd_nat_target> the_sparc64_fbsd_nat_target;
-void _initialize_sparc64fbsd_nat ();
-void
-_initialize_sparc64fbsd_nat ()
+INIT_GDB_FILE (sparc64fbsd_nat)
{
add_inf_child_target (&the_sparc64_fbsd_nat_target);
diff --git a/gdb/sparc64-fbsd-tdep.c b/gdb/sparc64-fbsd-tdep.c
index 738c3d1..ba04a71 100644
--- a/gdb/sparc64-fbsd-tdep.c
+++ b/gdb/sparc64-fbsd-tdep.c
@@ -238,13 +238,10 @@ sparc64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* FreeBSD/sparc64 has SVR4-style shared libraries. */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
}
-void _initialize_sparc64fbsd_tdep ();
-void
-_initialize_sparc64fbsd_tdep ()
+INIT_GDB_FILE (sparc64fbsd_tdep)
{
gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
GDB_OSABI_FREEBSD, sparc64fbsd_init_abi);
diff --git a/gdb/sparc64-linux-nat.c b/gdb/sparc64-linux-nat.c
index 9a4b228..2884faa 100644
--- a/gdb/sparc64-linux-nat.c
+++ b/gdb/sparc64-linux-nat.c
@@ -87,9 +87,7 @@ fill_fpregset (const struct regcache *regcache,
sparc64_collect_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
}
-void _initialize_sparc64_linux_nat ();
-void
-_initialize_sparc64_linux_nat ()
+INIT_GDB_FILE (sparc64_linux_nat)
{
sparc_fpregmap = &sparc64_bsd_fpregmap;
diff --git a/gdb/sparc64-linux-tdep.c b/gdb/sparc64-linux-tdep.c
index 6e7281c..373dfb6 100644
--- a/gdb/sparc64-linux-tdep.c
+++ b/gdb/sparc64-linux-tdep.c
@@ -32,6 +32,7 @@
#include "tramp-frame.h"
#include "xml-syscall.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
/* ADI specific si_code */
#ifndef SEGV_ACCADI
@@ -383,8 +384,7 @@ sparc64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* GNU/Linux has SVR4-style shared libraries... */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_lp64_svr4_solib_ops);
/* ...which means that we need some special handling when doing
prologue analysis. */
@@ -409,9 +409,7 @@ sparc64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_report_signal_info (gdbarch, sparc64_linux_report_signal_info);
}
-void _initialize_sparc64_linux_tdep ();
-void
-_initialize_sparc64_linux_tdep ()
+INIT_GDB_FILE (sparc64_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
GDB_OSABI_LINUX, sparc64_linux_init_abi);
diff --git a/gdb/sparc64-nat.c b/gdb/sparc64-nat.c
index 6bb37d8..66451a0 100644
--- a/gdb/sparc64-nat.c
+++ b/gdb/sparc64-nat.c
@@ -68,9 +68,7 @@ sparc64_fpregset_supplies_p (struct gdbarch *gdbarch, int regnum)
return 0;
}
-void _initialize_sparc64_nat ();
-void
-_initialize_sparc64_nat ()
+INIT_GDB_FILE (sparc64_nat)
{
sparc_supply_gregset = sparc64_supply_gregset;
sparc_collect_gregset = sparc64_collect_gregset;
diff --git a/gdb/sparc64-netbsd-nat.c b/gdb/sparc64-netbsd-nat.c
index c4bec4c..1036160 100644
--- a/gdb/sparc64-netbsd-nat.c
+++ b/gdb/sparc64-netbsd-nat.c
@@ -169,9 +169,7 @@ sparc64nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
/* We've got nothing to add to the generic SPARC target. */
static sparc_target<inf_ptrace_target> the_sparc64_nbsd_nat_target;
-void _initialize_sparc64nbsd_nat ();
-void
-_initialize_sparc64nbsd_nat ()
+INIT_GDB_FILE (sparc64nbsd_nat)
{
sparc_supply_gregset = sparc64nbsd_supply_gregset;
sparc_collect_gregset = sparc64nbsd_collect_gregset;
diff --git a/gdb/sparc64-netbsd-tdep.c b/gdb/sparc64-netbsd-tdep.c
index 1919598..0227ec4 100644
--- a/gdb/sparc64-netbsd-tdep.c
+++ b/gdb/sparc64-netbsd-tdep.c
@@ -266,13 +266,10 @@ sparc64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* NetBSD/sparc64 has SVR4-style shared libraries. */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
}
-void _initialize_sparc64nbsd_tdep ();
-void
-_initialize_sparc64nbsd_tdep ()
+INIT_GDB_FILE (sparc64nbsd_tdep)
{
gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
GDB_OSABI_NETBSD, sparc64nbsd_init_abi);
diff --git a/gdb/sparc64-obsd-nat.c b/gdb/sparc64-obsd-nat.c
index 5f9bd46..60dd188 100644
--- a/gdb/sparc64-obsd-nat.c
+++ b/gdb/sparc64-obsd-nat.c
@@ -108,9 +108,7 @@ sparc64obsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
/* Add some extra features to the generic SPARC target. */
static sparc_target<obsd_nat_target> the_sparc64_obsd_nat_target;
-void _initialize_sparc64obsd_nat ();
-void
-_initialize_sparc64obsd_nat ()
+INIT_GDB_FILE (sparc64obsd_nat)
{
sparc_supply_gregset = sparc64_supply_gregset;
sparc_collect_gregset = sparc64_collect_gregset;
diff --git a/gdb/sparc64-obsd-tdep.c b/gdb/sparc64-obsd-tdep.c
index 657f548..83cc9c0 100644
--- a/gdb/sparc64-obsd-tdep.c
+++ b/gdb/sparc64-obsd-tdep.c
@@ -440,8 +440,7 @@ sparc64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
obsd_init_abi (info, gdbarch);
/* OpenBSD/sparc64 has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
/* OpenBSD provides a user-level threads implementation. */
@@ -449,9 +448,7 @@ sparc64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
bsd_uthread_set_collect_uthread (gdbarch, sparc64obsd_collect_uthread);
}
-void _initialize_sparc64obsd_tdep ();
-void
-_initialize_sparc64obsd_tdep ()
+INIT_GDB_FILE (sparc64obsd_tdep)
{
gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
GDB_OSABI_OPENBSD, sparc64obsd_init_abi);
diff --git a/gdb/sparc64-sol2-tdep.c b/gdb/sparc64-sol2-tdep.c
index 72a07ec..6d091f5 100644
--- a/gdb/sparc64-sol2-tdep.c
+++ b/gdb/sparc64-sol2-tdep.c
@@ -214,8 +214,7 @@ sparc64_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* Solaris has SVR4-style shared libraries... */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_lp64_solib_ops);
/* ...which means that we need some special handling when doing
prologue analysis. */
@@ -225,9 +224,7 @@ sparc64_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_software_single_step (gdbarch, NULL);
}
-void _initialize_sparc64_sol2_tdep ();
-void
-_initialize_sparc64_sol2_tdep ()
+INIT_GDB_FILE (sparc64_sol2_tdep)
{
gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
GDB_OSABI_SOLARIS, sparc64_sol2_init_abi);
diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c
index ee7d7ed..6846421 100644
--- a/gdb/sparc64-tdep.c
+++ b/gdb/sparc64-tdep.c
@@ -529,9 +529,7 @@ adi_assign_command (const char *args, int from_tty)
do_assign (next_address, cnt, version);
}
-void _initialize_sparc64_adi_tdep ();
-void
-_initialize_sparc64_adi_tdep ()
+INIT_GDB_FILE (sparc64_adi_tdep)
{
add_basic_prefix_cmd ("adi", class_support,
_("ADI version related commands."),
diff --git a/gdb/stabsread.c b/gdb/stabsread.c
index 409f303..6ee61e0 100644
--- a/gdb/stabsread.c
+++ b/gdb/stabsread.c
@@ -7200,9 +7200,7 @@ hashname (const char *name)
/* Initializer for this module. */
-void _initialize_stabsread ();
-void
-_initialize_stabsread ()
+INIT_GDB_FILE (stabsread)
{
undef_types_allocated = 20;
undef_types_length = 0;
diff --git a/gdb/stack.c b/gdb/stack.c
index 6542840..e633566 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -3262,9 +3262,7 @@ static struct cmd_list_element *select_frame_cmd_list = NULL;
/* Commands with a prefix of `info frame'. */
static struct cmd_list_element *info_frame_cmd_list = NULL;
-void _initialize_stack ();
-void
-_initialize_stack ()
+INIT_GDB_FILE (stack)
{
struct cmd_list_element *cmd;
diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c
index 8cc7599..3b692e2 100644
--- a/gdb/stap-probe.c
+++ b/gdb/stap-probe.c
@@ -1748,9 +1748,7 @@ info_probes_stap_command (const char *arg, int from_tty)
info_probes_for_spops (arg, from_tty, &stap_static_probe_ops);
}
-void _initialize_stap_probe ();
-void
-_initialize_stap_probe ()
+INIT_GDB_FILE (stap_probe)
{
all_static_probe_ops.push_back (&stap_static_probe_ops);
diff --git a/gdb/std-regs.c b/gdb/std-regs.c
index 2a3f93d..9940cb0 100644
--- a/gdb/std-regs.c
+++ b/gdb/std-regs.c
@@ -93,9 +93,7 @@ value_of_builtin_frame_ps_reg (const frame_info_ptr &frame, const void *baton)
error (_("Standard register ``$ps'' is not available for this target"));
}
-void _initialize_frame_reg ();
-void
-_initialize_frame_reg ()
+INIT_GDB_FILE (frame_reg)
{
/* Frame based $fp, $pc, $sp and $ps. These only come into play
when the target does not define its own version of these
diff --git a/gdb/svr4-tls-tdep.c b/gdb/svr4-tls-tdep.c
index 56e1470..75d06a4 100644
--- a/gdb/svr4-tls-tdep.c
+++ b/gdb/svr4-tls-tdep.c
@@ -233,9 +233,7 @@ svr4_tls_register_tls_methods (struct gdbarch_info info, struct gdbarch *gdbarch
gdbarch_data->get_tls_dtp_offset = get_tls_dtp_offset;
}
-void _initialize_svr4_tls_tdep ();
-void
-_initialize_svr4_tls_tdep ()
+INIT_GDB_FILE (svr4_tls_tdep)
{
add_setshow_boolean_cmd ("force-internal-tls-address-lookup", class_obscure,
&force_internal_tls_address_lookup, _("\
diff --git a/gdb/symfile-debug.c b/gdb/symfile-debug.c
index 9c5ce85..a5ff21e 100644
--- a/gdb/symfile-debug.c
+++ b/gdb/symfile-debug.c
@@ -895,9 +895,7 @@ show_debug_symfile (struct ui_file *file, int from_tty,
gdb_printf (file, _("Symfile debugging is %s.\n"), value);
}
-void _initialize_symfile_debug ();
-void
-_initialize_symfile_debug ()
+INIT_GDB_FILE (symfile_debug)
{
add_setshow_boolean_cmd ("symfile", no_class, &debug_symfile, _("\
Set debugging of the symfile functions."), _("\
diff --git a/gdb/symfile-mem.c b/gdb/symfile-mem.c
index 92672d7..274dc0f 100644
--- a/gdb/symfile-mem.c
+++ b/gdb/symfile-mem.c
@@ -204,9 +204,7 @@ add_vsyscall_page (inferior *inf)
}
}
-void _initialize_symfile_mem ();
-void
-_initialize_symfile_mem ()
+INIT_GDB_FILE (symfile_mem)
{
add_cmd ("add-symbol-file-from-memory", class_files,
add_symbol_file_from_memory_command,
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 9a6322d..0e47f50 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -1101,7 +1101,7 @@ symbol_file_add_with_addrs (const gdb_bfd_ref_ptr &abfd, const char *name,
no separate debug file. If there is a separate debug file which
does not have symbols, we'll have emitted this message for that
file, and so printing it twice is just redundant. */
- if (should_print && !objfile_has_symbols (objfile)
+ if (should_print && !objfile->has_symbols ()
&& objfile->separate_debug_objfile == nullptr)
gdb_printf (_("(No debugging symbols found in %ps)\n"),
styled_string (file_name_style.style (), name));
@@ -2323,7 +2323,7 @@ add_symbol_file_command (const char *args, int from_tty)
objf = symbol_file_add (filename.get (), add_flags, &section_addrs,
flags);
- if (!objfile_has_symbols (objf) && objf->per_bfd->minimal_symbol_count <= 0)
+ if (!objf->has_symbols () && objf->per_bfd->minimal_symbol_count <= 0)
warning (_("newly-added symbol file \"%ps\" does not provide any symbols"),
styled_string (file_name_style.style (), filename.get ()));
@@ -2662,7 +2662,7 @@ reread_symbols (int from_tty)
objfile->expand_all_symtabs ();
}
- if (!objfile_has_symbols (objfile))
+ if (!objfile->has_symbols ())
{
gdb_stdout->wrap_here (0);
gdb_printf (_("(no debugging symbols found)\n"));
@@ -3849,9 +3849,7 @@ test_set_ext_lang_command ()
#endif /* GDB_SELF_TEST */
-void _initialize_symfile ();
-void
-_initialize_symfile ()
+INIT_GDB_FILE (symfile)
{
struct cmd_list_element *c;
diff --git a/gdb/symmisc.c b/gdb/symmisc.c
index 8a95958..0cb6a1b 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -1051,9 +1051,7 @@ maintenance_info_line_tables (const char *regexp, int from_tty)
/* Do early runtime initializations. */
-void _initialize_symmisc ();
-void
-_initialize_symmisc ()
+INIT_GDB_FILE (symmisc)
{
add_cmd ("symbols", class_maintenance, maintenance_print_symbols, _("\
Print dump of current symbol definitions.\n\
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 5147aee..7d1a0b0 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -60,7 +60,6 @@
#include "cp-abi.h"
#include "cp-support.h"
#include "observable.h"
-#include "solist.h"
#include "macrotab.h"
#include "macroscope.h"
@@ -2163,13 +2162,6 @@ lookup_symbol_aux (const char *name, symbol_name_match_type match_type,
domain_name (domain).c_str (), language_str (language));
}
- /* Make sure we do something sensible with is_a_field_of_this, since
- the callers that set this parameter to some non-null value will
- certainly use it later. If we don't set it, the contents of
- is_a_field_of_this are undefined. */
- if (is_a_field_of_this != NULL)
- memset (is_a_field_of_this, 0, sizeof (*is_a_field_of_this));
-
langdef = language_def (language);
/* Search specified block and its superiors. Don't search
@@ -4499,7 +4491,7 @@ info_sources_filter::matches (const char *fullname) const
switch (m_match_type)
{
case match_on::DIRNAME:
- dirname = ldirname (fullname);
+ dirname = gdb_ldirname (fullname);
to_match = dirname.c_str ();
break;
case match_on::BASENAME:
@@ -4714,7 +4706,7 @@ info_sources_worker (struct ui_out *uiout,
if (uiout->is_mi_like_p ())
{
const char *debug_info_state;
- if (objfile_has_symbols (objfile))
+ if (objfile->has_symbols ())
{
if (debug_fully_readin)
debug_info_state = "fully-read";
@@ -4730,7 +4722,7 @@ info_sources_worker (struct ui_out *uiout,
if (!debug_fully_readin)
uiout->text ("(Full debug information has not yet been read "
"for this file.)\n");
- if (!objfile_has_symbols (objfile))
+ if (!objfile->has_symbols ())
uiout->text ("(Objfile has no debug information.)\n");
uiout->text ("\n");
}
@@ -6206,8 +6198,6 @@ default_collect_symbol_completion_matches_break_on
if (current_language->macro_expansion () == macro_expansion_c
&& code == TYPE_CODE_UNDEF)
{
- gdb::unique_xmalloc_ptr<struct macro_scope> scope;
-
/* This adds a macro's name to the current completion list. */
auto add_macro_name = [&] (const char *macro_name,
const macro_definition *,
@@ -6225,10 +6215,9 @@ default_collect_symbol_completion_matches_break_on
resulting expression will be evaluated at "file:line" -- but
at there does not seem to be a way to detect this at
completion time. */
- scope = default_macro_scope ();
- if (scope)
- macro_for_each_in_scope (scope->file, scope->line,
- add_macro_name);
+ macro_scope scope = default_macro_scope ();
+ if (scope.is_valid ())
+ macro_for_each_in_scope (scope.file, scope.line, add_macro_name);
/* User-defined macros are always visible. */
macro_for_each (macro_user_macros, add_macro_name);
@@ -7120,9 +7109,7 @@ info_module_var_func_command_completer (struct cmd_list_element *ignore,
-void _initialize_symtab ();
-void
-_initialize_symtab ()
+INIT_GDB_FILE (symtab)
{
cmd_list_element *c;
diff --git a/gdb/symtab.h b/gdb/symtab.h
index e547d10..0a57be5 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -2101,17 +2101,17 @@ struct field_of_this_result
symbol was not found in 'this'. If non-NULL, then one of the
other fields will be non-NULL as well. */
- struct type *type;
+ struct type *type = nullptr;
/* If the symbol was found as an ordinary field of 'this', then this
is non-NULL and points to the particular field. */
- struct field *field;
+ struct field *field = nullptr;
/* If the symbol was found as a function field of 'this', then this
is non-NULL and points to the particular field. */
- struct fn_fieldlist *fn_field;
+ struct fn_fieldlist *fn_field = nullptr;
};
/* Find the definition for a specified symbol name NAME
diff --git a/gdb/syscalls/riscv-canonicalize-syscall-gen.py b/gdb/syscalls/riscv-canonicalize-syscall-gen.py
index c7dda93..40039bb 100755
--- a/gdb/syscalls/riscv-canonicalize-syscall-gen.py
+++ b/gdb/syscalls/riscv-canonicalize-syscall-gen.py
@@ -111,7 +111,7 @@ class Generator:
canon_syscalls[syscall_num] = value
# this is a place for corner cases
elif syscall_name == "mmap":
- gdb_old_syscall_name = "gdb_old_mmap"
+ gdb_old_syscall_name = "gdb_sys_old_mmap"
value = (
f" case {syscall_num}: return {gdb_old_syscall_name};\n"
)
diff --git a/gdb/target-connection.c b/gdb/target-connection.c
index 60d7732..02eea05 100644
--- a/gdb/target-connection.c
+++ b/gdb/target-connection.c
@@ -149,10 +149,7 @@ info_connections_command (const char *args, int from_tty)
print_connection (current_uiout, args);
}
-void _initialize_target_connection ();
-
-void
-_initialize_target_connection ()
+INIT_GDB_FILE (target_connection)
{
add_info ("connections", info_connections_command,
_("\
diff --git a/gdb/target-dcache.c b/gdb/target-dcache.c
index 9fcdd1e..6be1224 100644
--- a/gdb/target-dcache.c
+++ b/gdb/target-dcache.c
@@ -161,9 +161,7 @@ maint_flush_dcache_command (const char *command, int from_tty)
gdb_printf (_("The dcache was flushed.\n"));
}
-void _initialize_target_dcache ();
-void
-_initialize_target_dcache ()
+INIT_GDB_FILE (target_dcache)
{
add_setshow_boolean_cmd ("stack-cache", class_support,
&stack_cache_enabled_1, _("\
diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c
index 8042d25..dc5fbac 100644
--- a/gdb/target-descriptions.c
+++ b/gdb/target-descriptions.c
@@ -1880,9 +1880,7 @@ maintenance_check_xml_descriptions (const char *dir, int from_tty)
(long) selftests::xml_tdesc.size (), failed);
}
-void _initialize_target_descriptions ();
-void
-_initialize_target_descriptions ()
+INIT_GDB_FILE (target_descriptions)
{
cmd_list_element *cmd;
diff --git a/gdb/target.c b/gdb/target.c
index 522bed8..f7c43f6 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -2464,6 +2464,7 @@ target_pre_inferior ()
if (!gdbarch_has_global_solist (current_inferior ()->arch ()))
{
no_shared_libraries (current_program_space);
+ current_program_space->unset_solib_ops ();
invalidate_target_mem_regions ();
@@ -3204,8 +3205,8 @@ target_ops::fileio_fstat (int fd, struct stat *sb, fileio_error *target_errno)
}
int
-target_ops::fileio_stat (struct inferior *inf, const char *filename,
- struct stat *sb, fileio_error *target_errno)
+target_ops::fileio_lstat (struct inferior *inf, const char *filename,
+ struct stat *sb, fileio_error *target_errno)
{
*target_errno = FILEIO_ENOSYS;
return -1;
@@ -3331,17 +3332,17 @@ 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)
+target_fileio_lstat (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);
+ int ret = t->fileio_lstat (inf, filename, sb, target_errno);
if (ret == -1 && *target_errno == FILEIO_ENOSYS)
continue;
- target_debug_printf_nofunc ("target_fileio_stat (%s) = %d (%d)",
+ target_debug_printf_nofunc ("target_fileio_lstat (%s) = %d (%d)",
filename, ret,
ret != -1 ? 0 : *target_errno);
return ret;
@@ -4502,10 +4503,7 @@ set_write_memory_registers_permission (const char *args, int from_tty,
update_observer_mode ();
}
-void _initialize_target ();
-
-void
-_initialize_target ()
+INIT_GDB_FILE (target)
{
the_debug_target = new debug_target ();
diff --git a/gdb/target.h b/gdb/target.h
index 2d3bac7..365e894 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -1016,8 +1016,8 @@ struct target_ops
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);
+ virtual int fileio_lstat (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). */
@@ -2256,8 +2256,8 @@ extern int target_fileio_fstat (int fd, struct stat *sb,
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);
+extern int target_fileio_lstat (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). */
diff --git a/gdb/testsuite/gdb.ada/dyn-bit-offset.exp b/gdb/testsuite/gdb.ada/dyn-bit-offset.exp
index 19d16b1..f8a4363 100644
--- a/gdb/testsuite/gdb.ada/dyn-bit-offset.exp
+++ b/gdb/testsuite/gdb.ada/dyn-bit-offset.exp
@@ -28,19 +28,52 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable $flags] != ""} {
return -1
}
+# GCC needs to have fixes:
+# - 809b46d2ccc ("Partially lift restriction from loc_list_from_tree_1")
+# - d7f24e37d4b ("Fix oversight about big-endian targets in latest change")
+set have_xfail [gnat_version_compare <= {16 1}]
+
clean_restart ${testfile}
set bp_location [gdb_get_line_number "STOP" ${testdir}/exam.adb]
runto "exam.adb:$bp_location"
+set re_pass \
+ [string_to_regexp \
+ " = (discr => 3, array_field => (-5, -6, -7), field => -5, another_field => -6)"]
+set re_xfail_le \
+ [string_to_regexp \
+ " = (discr => 3, array_field => (-5, -6, -7), field => -4, another_field => -4)"]
+set re_xfail_be \
+ [string_to_regexp \
+ " = (discr => 3, array_field => (-5, -6, -7), field => -6, another_field => -6)"]
+
gdb_test_multiple "print spr" "" {
- -re -wrap " = \\(discr => 3, array_field => \\(-5, -6, -7\\), field => -4, another_field => -6\\)" {
+ -re -wrap $re_pass {
pass $gdb_test_name
}
- -re -wrap " = \\(discr => 3, array_field => \\(-5, -6, -7\\), field => -4, another_field => -4\\)" {
- # A known GCC bug.
- xfail $gdb_test_name
+ -re -wrap $re_xfail_le|$re_xfail_be {
+ if { $have_xfail } {
+ xfail $gdb_test_name
+ } else {
+ fail $gdb_test_name
+ }
}
}
-gdb_test "print spr.field" " = -4"
+set re_pass " = -5"
+set re_xfail_le " = -4"
+set re_xfail_be " = -6"
+
+gdb_test_multiple "print spr.field" "" {
+ -re -wrap $re_pass {
+ pass $gdb_test_name
+ }
+ -re -wrap $re_xfail_le|$re_xfail_be {
+ if { $have_xfail } {
+ xfail $gdb_test_name
+ } else {
+ fail $gdb_test_name
+ }
+ }
+}
diff --git a/gdb/testsuite/gdb.ada/dyn-bit-offset/exam.adb b/gdb/testsuite/gdb.ada/dyn-bit-offset/exam.adb
index a882afd..5c7f70b 100644
--- a/gdb/testsuite/gdb.ada/dyn-bit-offset/exam.adb
+++ b/gdb/testsuite/gdb.ada/dyn-bit-offset/exam.adb
@@ -36,7 +36,7 @@ procedure Exam is
pragma No_Component_Reordering (Some_Packed_Record);
SPR : Some_Packed_Record := (Discr => 3,
- Field => -4,
+ Field => -5,
Another_Field => -6,
Array_Field => (-5, -6, -7));
diff --git a/gdb/testsuite/gdb.ada/finish-var-size.exp b/gdb/testsuite/gdb.ada/finish-var-size.exp
index e038ed4..ae30086 100644
--- a/gdb/testsuite/gdb.ada/finish-var-size.exp
+++ b/gdb/testsuite/gdb.ada/finish-var-size.exp
@@ -22,7 +22,13 @@ require {expr [gcc_major_version] >= 12}
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.ada/negative-bit-offset.exp b/gdb/testsuite/gdb.ada/negative-bit-offset.exp
new file mode 100644
index 0000000..c5fcae1
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/negative-bit-offset.exp
@@ -0,0 +1,36 @@
+# Copyright 2025 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 <http://www.gnu.org/licenses/>.
+
+# Test negative DW_AT_bit_offset.
+
+load_lib "ada.exp"
+
+require allow_ada_tests
+
+standard_ada_testfile prog
+
+# This particular output is only generated with -gdwarf-4.
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable \
+ {debug additional_flags=-gdwarf-4}] != ""} {
+ return
+}
+
+clean_restart ${testfile}
+
+set bp_location [gdb_get_line_number "STOP" ${testdir}/prog.adb]
+runto "prog.adb:$bp_location"
+
+gdb_test "print xp" \
+ [string_to_regexp "(x => 21, y => (-1, -2, -3, -4, -5, -6, -7, -8, -9, -10))"]
diff --git a/gdb/testsuite/gdb.ada/negative-bit-offset/prog.adb b/gdb/testsuite/gdb.ada/negative-bit-offset/prog.adb
new file mode 100644
index 0000000..e3c1775
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/negative-bit-offset/prog.adb
@@ -0,0 +1,36 @@
+-- Copyright 2025 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 <http://www.gnu.org/licenses/>.
+
+procedure Prog is
+
+ type Small is range -32 .. 31;
+ for Small'Size use 6;
+
+ type SomeArray is array (POSITIVE range <>) of Small;
+
+ type SomePackedArray is array (POSITIVE range <>) of Small;
+ pragma Pack (SomePackedArray);
+
+ type SomePackedRecord is record
+ X: Small;
+ Y: SomePackedArray (1 .. 10);
+ end record;
+ pragma Pack (SomePackedRecord);
+
+ XP: SomePackedRecord := (21, (-1, -2, -3, -4, -5, -6, -7, -8, -9, -10));
+
+begin
+ null; -- STOP
+end;
diff --git a/gdb/testsuite/gdb.arch/amd64-watchpoint-downgrade.exp b/gdb/testsuite/gdb.arch/amd64-watchpoint-downgrade.exp
index dcee040..5663b0d 100644
--- a/gdb/testsuite/gdb.arch/amd64-watchpoint-downgrade.exp
+++ b/gdb/testsuite/gdb.arch/amd64-watchpoint-downgrade.exp
@@ -58,7 +58,7 @@ gdb_test "starti" \
[multi_line \
"warning: watchpoint $num downgraded to software watchpoint" \
"" \
- "Program stopped\\." \
+ "(Program|Thread \[^\r\n\]) stopped\\." \
".*"]
# Watchpoint should now have downgraded to a s/w watchpoint.
diff --git a/gdb/testsuite/gdb.arch/i386-prologue-skip-cf-protection-stackalign.c b/gdb/testsuite/gdb.arch/i386-prologue-skip-cf-protection-stackalign.c
new file mode 100644
index 0000000..f55cee5
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/i386-prologue-skip-cf-protection-stackalign.c
@@ -0,0 +1,27 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2025 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 <http://www.gnu.org/licenses/>. */
+
+#include <alloca.h>
+
+int
+main (int argc, char **argv)
+{
+ volatile __attribute__ ((__aligned__ (64))) int a;
+ volatile char *p = (char *) alloca (argc * 12);
+ p[2] = 'b';
+ return 1;
+}
diff --git a/gdb/testsuite/gdb.arch/i386-prologue-skip-cf-protection.exp b/gdb/testsuite/gdb.arch/i386-prologue-skip-cf-protection.exp
index eb93127..06285ce 100644
--- a/gdb/testsuite/gdb.arch/i386-prologue-skip-cf-protection.exp
+++ b/gdb/testsuite/gdb.arch/i386-prologue-skip-cf-protection.exp
@@ -19,41 +19,65 @@
# This option places an `endbr32`/`endbr64` instruction at the start of
# all functions, which can interfere with prologue analysis.
-standard_testfile .c
-set binfile ${binfile}
+standard_testfile .c -stackalign.c
require {is_any_target x86_64-*-* i?86-*-*}
-
require supports_fcf_protection
-set opts {debug additional_flags=-fcf-protection=full}
+# Tests if breakpoint set on main is placed past main's entry.
+proc test_run {} {
+ # Get start address of function main.
+ set main_addr [get_integer_valueof &main -1]
+ gdb_assert {$main_addr != -1}
-if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable $opts] != "" } {
- untested "failed to compile"
- return
-}
+ set bp_addr -1
-clean_restart ${binfile}
+ # Put breakpoint on main, get the address where the breakpoint was installed.
+ gdb_test_multiple "break -q main" "break on main, get address" {
+ -re -wrap "Breakpoint $::decimal at ($::hex).*" {
+ set bp_addr $expect_out(1,string)
-# Get start address of function main.
-set main_addr [get_integer_valueof &main -1]
-gdb_assert {$main_addr != -1}
+ # Convert to decimal.
+ set bp_addr [expr $bp_addr]
-set bp_addr -1
+ pass $gdb_test_name
+ }
+ }
-# Put breakpoint on main, get the address where the breakpoint was installed.
-gdb_test_multiple "break -q main" "break on main, get address" {
- -re -wrap "Breakpoint $decimal at ($hex).*" {
- set bp_addr $expect_out(1,string)
+ # Make sure some prologue was skipped.
+ gdb_assert {$bp_addr != -1 && $bp_addr > $main_addr} \
+ "breakpoint placed past main's entry"
+}
- # Convert to decimal.
- set bp_addr [expr $bp_addr]
+with_test_prefix "skip-cf-protection" {
+ set opts {debug additional_flags=-fcf-protection=full}
- pass $gdb_test_name
+ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \
+ $opts] != "" } {
+ untested "failed to compile"
+ return
}
+
+ clean_restart ${binfile}
+
+ test_run
}
-if { $bp_addr != -1 } {
- # Make sure some prologue was skipped.
- gdb_assert {$bp_addr > $main_addr}
+# Now, make sure that the prologue analysis does not end up at function's entry
+# when stack alignment sequence is generated right after 'endbr64'/'endbr32'.
+# That could happen if GDB handled those incorrectly - there was a bug that
+# checked for those two in incorrect order, which caused such issue.
+with_test_prefix "skip-cf-protection-stackalign" {
+ # gcc is easier to make it produce the sequence of interest.
+ if { ![is_c_compiler_gcc] } {
+ unsupported "stackalign test part requires gcc compiler"
+ return
+ }
+
+ if { [prepare_for_testing "failed to prepare" "${testfile}-stackalign" \
+ $srcfile2 [list optimize=-O0 additional_flags=-fcf-protection=full]] } {
+ return
+ }
+
+ test_run
}
diff --git a/gdb/testsuite/gdb.base/attach-deleted-exec.exp b/gdb/testsuite/gdb.base/attach-deleted-exec.exp
index 82a7bb4..45fac0d 100644
--- a/gdb/testsuite/gdb.base/attach-deleted-exec.exp
+++ b/gdb/testsuite/gdb.base/attach-deleted-exec.exp
@@ -67,5 +67,49 @@ if { [regexp $re_nfs $filename] } {
gdb_assert { [string equal $filename /proc/${testpid}/exe] } $test
}
+# Restart GDB.
+clean_restart
+
+# Setup an empty sysroot. GDB will fail to find the executable within
+# the sysroot. Additionally, the presence of a sysroot should prevent
+# GDB from trying to load the executable from /proc/PID/exe.
+set sysroot [standard_output_file "sysroot"]
+gdb_test_no_output "set sysroot $sysroot" \
+ "setup sysroot"
+
+# Attach to the inferior. GDB should complain about failing to find
+# the executable. It is the name of the executable that GDB doesn't
+# find that we're interesting in here. For native targets GDB should
+# be looking for BINFILE, not /proc/PID/exe.
+#
+# For extended-remote targets things are unfortunately harder. Native
+# GDB looks for BINFILE because it understands that GDB will be
+# looking in the sysroot. But remote GDB doesn't know if GDB is using
+# a sysroot or not. As such, gdbserver will return /proc/PID/exe if
+# it knows that the file has been deleted locally. This isn't great
+# if GDB then plans to look in a sysroot, but equally, if the remote
+# file has been deleted, then the name GDB will return, will have had
+# " (deleted" appended, so we're unlikely to get a hit in the sysroot
+# either way.
+if { [target_info gdb_protocol] == "extended-remote" } {
+ set filename_re "/proc/$testpid/exe"
+} else {
+ set filename_re "\[^\r\n\]+/${testfile} \\(deleted\\)"
+}
+
+verbose -log "APB: warning: No executable has been specified, and target executable $filename_re could not be found\\. Try using the \"file\" command\\."
+
+gdb_test "attach $testpid" \
+ [multi_line \
+ "Attaching to process $decimal" \
+ "warning: No executable has been specified, and target executable $filename_re could not be found\\. Try using the \"file\" command\\." \
+ ".*"] \
+ "attach to inferior"
+
+# Check GDB hasn't managed to load an executable.
+gdb_test "info inferior" \
+ "\\*\[^)\]+\\)\\s*" \
+ "confirm no executable is loaded."
+
# Cleanup.
kill_wait_spawned_process $test_spawn_id
diff --git a/gdb/testsuite/gdb.base/bp-cond-failure.exp b/gdb/testsuite/gdb.base/bp-cond-failure.exp
index d645454..4d03e7b 100644
--- a/gdb/testsuite/gdb.base/bp-cond-failure.exp
+++ b/gdb/testsuite/gdb.base/bp-cond-failure.exp
@@ -75,7 +75,7 @@ proc run_test { cond_eval access_type bpexpr nloc } {
"Error in testing condition for breakpoint ${bp_num}.2:" \
"Cannot access memory at address 0x0" \
"" \
- "Breakpoint ${bp_num}.2, foo \\(c=49 ...\\) at \[^\r\n\]+:\[0-9\]+" \
+ "(Thread \[^\r\n\]+ hit )?Breakpoint ${bp_num}.2, foo \\(c=49 ...\\) at \[^\r\n\]+:\[0-9\]+" \
"${::decimal}\\s+\[^\r\n\]+ breakpoint here\\. \[^\r\n\]+"]
} else {
gdb_test "continue" \
@@ -84,7 +84,7 @@ proc run_test { cond_eval access_type bpexpr nloc } {
"Error in testing condition for breakpoint ${bp_num}:" \
"Cannot access memory at address 0x0" \
"" \
- "Breakpoint ${bp_num}, bar \\(\\) at \[^\r\n\]+:\[0-9\]+" \
+ "(Thread \[^\r\n\]+ hit )?Breakpoint ${bp_num}, bar \\(\\) at \[^\r\n\]+:\[0-9\]+" \
"${::decimal}\\s+\[^\r\n\]+ breakpoint here\\. \[^\r\n\]+"]
}
}
diff --git a/gdb/testsuite/gdb.base/bp-permanent.c b/gdb/testsuite/gdb.base/bp-permanent.c
index d586acc..72e5e8a 100644
--- a/gdb/testsuite/gdb.base/bp-permanent.c
+++ b/gdb/testsuite/gdb.base/bp-permanent.c
@@ -101,7 +101,7 @@ test_signal_no_handler (void)
}
static void
-test_signal_nested_handler ()
+test_signal_nested_handler (int sig)
{
test ();
}
diff --git a/gdb/testsuite/gdb.base/bp-permanent.exp b/gdb/testsuite/gdb.base/bp-permanent.exp
index 62ce3f6..c6c6269 100644
--- a/gdb/testsuite/gdb.base/bp-permanent.exp
+++ b/gdb/testsuite/gdb.base/bp-permanent.exp
@@ -134,7 +134,7 @@ proc test {always_inserted sw_watchpoint} {
unsupported "failed to stop at permanent breakpoint"
return
}
- -re "Program received signal SIGTRAP.*$gdb_prompt $" {
+ -re "received signal SIGTRAP.*$gdb_prompt $" {
pass $test
}
}
@@ -174,7 +174,7 @@ proc test {always_inserted sw_watchpoint} {
# disabled, it should act as if we hadn't created it in the first
# place. IOW, we should get a random signal, and, the breakpoint's
# command should not run.
- gdb_test "continue" "Program received signal SIGTRAP.*" \
+ gdb_test "continue" "received signal SIGTRAP.*" \
"disabled permanent breakpoint doesn't explain stop"
gdb_test "info breakpoints" \
diff --git a/gdb/testsuite/gdb.base/break-dbg.cc b/gdb/testsuite/gdb.base/break-dbg.cc
new file mode 100644
index 0000000..642ded0
--- /dev/null
+++ b/gdb/testsuite/gdb.base/break-dbg.cc
@@ -0,0 +1,31 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2025 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 <http://www.gnu.org/licenses/>. */
+
+volatile int global_var = 0;
+
+int
+foo ()
+{
+ return global_var;
+}
+
+int
+main ()
+{
+ int res = foo ();
+ return res;
+}
diff --git a/gdb/testsuite/gdb.base/break-dbg.exp b/gdb/testsuite/gdb.base/break-dbg.exp
new file mode 100644
index 0000000..3652b8e
--- /dev/null
+++ b/gdb/testsuite/gdb.base/break-dbg.exp
@@ -0,0 +1,70 @@
+# Copyright 2025 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 <http://www.gnu.org/licenses/>. */
+
+# Some basic testing of 'set debug breakpoint on'. At one point a bug
+# meant that some breakpoints would immediately trigger a segfault if
+# GDB tried to run with breakpoint debugging turned on.
+#
+# Test is compiled as C++ only so 'catch catch/throw/rethrow' have a
+# something to do. The original bug would trigger for any 'catch'
+# style breakpoint, so C++ isn't really a hard requirement.
+
+standard_testfile .cc
+
+require allow_cplus_tests
+
+if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \
+ {debug c++}] } {
+ return
+}
+
+if {![runto_main]} {
+ return
+}
+
+gdb_test "catch catch" "^Catchpoint $decimal \\(catch\\)"
+gdb_test "catch throw" "^Catchpoint $decimal \\(throw\\)"
+gdb_test "catch rethrow" "^Catchpoint $decimal \\(rethrow\\)"
+
+gdb_test "catch exec" "^Catchpoint $decimal \\(exec\\)"
+gdb_test "catch fork" "^Catchpoint $decimal \\(fork\\)"
+gdb_test "catch vfork" "^Catchpoint $decimal \\(vfork\\)"
+
+gdb_test "catch load" "^Catchpoint $decimal \\(load\\)"
+gdb_test "catch unload" "^Catchpoint $decimal \\(unload\\)"
+
+gdb_test "catch signal" "^Catchpoint $decimal \\(standard signals\\)"
+gdb_test "catch syscall" "^Catchpoint $decimal \\(any syscall\\)"
+
+gdb_test "watch -l global_var" "\[Ww]atchpoint $decimal: -location global_var"
+
+gdb_test_no_output "set debug breakpoint on"
+
+set saw_bp_debug_line false
+gdb_test_multiple "step" "" {
+ -re "^step\r\n" {
+ exp_continue
+ }
+ -re "^\\\[breakpoint\\\] \[^\r\n\]+\r\n" {
+ set saw_bp_debug_line true
+ exp_continue
+ }
+ -re "^$gdb_prompt $" {
+ gdb_assert { $saw_bp_debug_line } $gdb_test_name
+ }
+ -re "^\[^\r\n\]*\r\n" {
+ exp_continue
+ }
+}
diff --git a/gdb/testsuite/gdb.base/catch-fork-kill.exp b/gdb/testsuite/gdb.base/catch-fork-kill.exp
index 0fd853b..224a8df 100644
--- a/gdb/testsuite/gdb.base/catch-fork-kill.exp
+++ b/gdb/testsuite/gdb.base/catch-fork-kill.exp
@@ -32,6 +32,8 @@
standard_testfile
+require allow_fork_tests
+
# Build two programs -- one for fork, and another for vfork.
set testfile_fork "${testfile}-fork"
set testfile_vfork "${testfile}-vfork"
diff --git a/gdb/testsuite/gdb.base/catch-fork-static.exp b/gdb/testsuite/gdb.base/catch-fork-static.exp
index b171a6d..9d50d5d 100644
--- a/gdb/testsuite/gdb.base/catch-fork-static.exp
+++ b/gdb/testsuite/gdb.base/catch-fork-static.exp
@@ -21,9 +21,7 @@
# ld.so probes before reaching main, and ptrace flags were set then. But a
# static executable would just keep running and never catch the fork.
-# Until "catch fork" is implemented on other targets...
-#
-require {is_any_target "*-*-linux*" "*-*-openbsd*"}
+require allow_fork_tests
# Reusing foll-fork.c since it's a simple forking program.
standard_testfile foll-fork.c
diff --git a/gdb/testsuite/gdb.base/catch-signal-fork.exp b/gdb/testsuite/gdb.base/catch-signal-fork.exp
index dea0cc4..2a33ee1 100644
--- a/gdb/testsuite/gdb.base/catch-signal-fork.exp
+++ b/gdb/testsuite/gdb.base/catch-signal-fork.exp
@@ -14,6 +14,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
require {!target_info exists gdb,nosignals}
+require allow_fork_tests
standard_testfile
diff --git a/gdb/testsuite/gdb.base/corefile-shmem-zero-id-lib.c b/gdb/testsuite/gdb.base/corefile-shmem-zero-id-lib.c
new file mode 100644
index 0000000..58fdec6
--- /dev/null
+++ b/gdb/testsuite/gdb.base/corefile-shmem-zero-id-lib.c
@@ -0,0 +1,522 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2025 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 <http://www.gnu.org/licenses/>. */
+
+/* This file contains a library that can be preloaded into GDB on Linux
+ using the LD_PRELOAD technique.
+
+ The library intercepts calls to OPEN, CLOSE, READ, and PREAD in order to
+ fake the inode number of a shared memory mapping.
+
+ When GDB creates a core file (e.g. with the 'gcore' command), then
+ shared memory mappings should be included in the generated core file.
+
+ The 'id' for the shared memory mapping shares the inode slot in the
+ /proc/PID/smaps file, which is what GDB consults to decide which
+ mappings should be included in the core file.
+
+ It is possible for a shared memory mapping to have an 'id' of zero.
+
+ At one point there was a bug in GDB where mappings with an inode of zero
+ would not be included in the generated core file. This meant that most
+ shared memory mappings would be included in the generated core file,
+ but, if a shared memory mapping happened to get an 'id' of zero, then,
+ because this would appear as a zero inode in the smaps file, this shared
+ memory mapping would be excluded from the generated core file.
+
+ This preload library spots when GDB opens a /proc/PID/smaps file and
+ immediately copies the contents of this file into an internal buffer.
+ The buffer is then scanned looking for a shared memory mapping, and, if
+ a shared memory mapping is found, its 'id' (in the inode position) is
+ changed to zero.
+
+ Calls to read/pread are intercepted, and attempts to read from the smaps
+ file are then served from the modified buffer contents.
+
+ The close calls are monitored and, when the smaps file is closed, the
+ internal buffer is released.
+
+ This works with GDB (currently) because the requirements for access to
+ the smaps file are pretty simple. GDB opens the file and grabs the
+ entire contents with a single pread call and a large buffer. There's no
+ seeking within the file or anything like that.
+
+ The intention is that this library is preloaded into a GDB session which
+ is then used to start an inferior and generate a core file. GDB will
+ then see the zero inode for the shared memory mapping and should, if the
+ bug is correctly fixed, still add the shared memory mapping to the
+ generated core file. */
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdbool.h>
+#include <assert.h>
+
+/* Logging. */
+
+static void
+log_msg (const char *fmt, ...)
+{
+#ifdef LOGGING
+ va_list ap;
+
+ va_start (ap, fmt);
+ vfprintf (stderr, fmt, ap);
+ va_end (ap);
+#endif /* LOGGING */
+}
+
+/* Error handling, message and exit. */
+
+static void
+error (const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ vfprintf (stderr, fmt, ap);
+ va_end (ap);
+
+ exit (EXIT_FAILURE);
+}
+
+/* The type of the open() function. */
+typedef int (*open_func_type)(const char *pathname, int flags, ...);
+
+/* The type of the close() function. */
+typedef int (*close_func_type)(int fd);
+
+/* The type of the read() function. */
+typedef ssize_t (*read_func_type)(int fd, void *buf, size_t count);
+
+/* The type of the pread() function. */
+typedef ssize_t (*pread_func_type) (int fd, void *buf, size_t count, off_t offset);
+
+/* Structure that holds information about a /proc/PID/smaps file that has
+ been opened. */
+struct interesting_file
+{
+ /* The file descriptor for the opened file. */
+ int fd;
+
+ /* The read offset within the file. Set to zero when the file is
+ opened. Any 'read' calls will update this offset. */
+ size_t offset;
+
+ /* The size of the contents within the buffer. This is not the total
+ buffer size (which might be larger). Attempts to read beyond SIZE
+ indicate an attempt to read beyond the end of the file. */
+ size_t size;
+
+ /* The (possibly modified) contents of the file. */
+ char *content;
+};
+
+/* We only track a single interesting file. Currently, for the use case
+ we imagine, GDB will only ever open one /proc/PID/smaps file at once. */
+struct interesting_file the_file = { -1, 0, 0, NULL };
+
+/* Update the contents of the global THE_FILE buffer. It is assumed that
+ the file contents have already been loaded into THE_FILE's content
+ buffer.
+
+ Look for any lines that represent a shared memory mapping and modify
+ the inode field (which holds the shared memory id) to be zero. */
+static void
+update_file_content_buffer (void)
+{
+ assert (the_file.content != NULL);
+
+ char *start = the_file.content;
+ do
+ {
+ /* Every line, even the last one, ends with a newline. */
+ char *end = strchrnul (start, '\n');
+ assert (end != NULL);
+ assert (*end != '\0');
+
+ /* Attribute lines start with an uppercase letter. The lines we want
+ to modify should start with a lower case hex character,
+ i.e. [0-9a-f]. Also, every line that we want to consider should
+ be long enough, but just in case, check the longest possible
+ filename that we care about. */
+ if (isxdigit (*start) && (isdigit (*start) || islower (*start))
+ && (end - start) > 23)
+ {
+ /* There are two possible filenames that we look for:
+ /SYSV%08x
+ /SYSV%08x (deleted)
+ The END pointer is pointing to the first character after the
+ filename.
+
+ Setup OFFSET to be the offset from END to the start of the
+ filename. As we check the filename we set OFFSET to 0 if the
+ filename doesn't match one of the expected patterns. */
+ size_t offset;
+ if (strncmp ((end - 13), "/SYSV", 5) == 0)
+ offset = 13;
+ else if (strncmp ((end - 23), "/SYSV", 5) == 0)
+ {
+ if (strncmp ((end - 10), " (deleted)", 10) == 0)
+ offset = 23;
+ else
+ offset = 0;
+ }
+ else
+ offset = 0;
+
+ for (int i = 0; i < 8 && offset != 0; ++i)
+ {
+ if (!isdigit (*(end - offset + 5 + i)))
+ offset = 0;
+ }
+
+ /* If OFFSET is non-zero then the filename on this line looks
+ like a shared memory mapping, and OFFSET is the offset from
+ END to the first character of the filename. */
+ if (offset != 0)
+ {
+ log_msg ("[LD_PRELOAD] shared memory entry: %.*s\n",
+ offset, (end - offset));
+
+ /* Set PTR to the first character before the filename. This
+ should be a white space character. */
+ char *ptr = end - offset - 1;
+ assert (isspace (*ptr));
+
+ /* Walk backwards until we find the inode field. */
+ while (isspace (*ptr))
+ --ptr;
+
+ /* Now replace every character in the inode field, except the
+ first one, with a space character. */
+ while (!isspace (*(ptr - 1)))
+ {
+ assert (isdigit (*ptr));
+ *ptr = ' ';
+ --ptr;
+ }
+
+ /* Replace the first character with '0'. */
+ assert (isdigit (*ptr));
+ *ptr = '0';
+
+ /* This print is checked for from GDB. */
+ printf ("[LD_PRELOAD] updated a shared memory mapping\n");
+ }
+ }
+
+ /* Update START to point to the next line. The last line of the
+ file will be empty. */
+ assert (*end == '\n');
+ start = end;
+ while (*start == '\n')
+ ++start;
+ }
+ while (*start != '\0');
+}
+
+/* Return true if PATHNAME has for form "/proc/PID/smaps" (without the
+ quotes). Otherwise, return false. */
+
+static bool
+is_smaps_file (const char *pathname)
+{
+ if (strncmp (pathname, "/proc/", 6) == 0)
+ {
+ int idx = 6;
+ while (isdigit (pathname[idx]))
+ idx++;
+ if (idx > 6 && strcmp (&pathname[idx], "/smaps") == 0)
+ return true;
+ }
+
+ return false;
+}
+
+/* Return true if PATHNAME should be considered interesting. PATHNAME is
+ interesting if it has the form /proc/PID/smaps, and there is no
+ interesting file already opened. */
+
+static bool
+is_interesting_pathname (const char *pathname)
+{
+ return the_file.fd == -1 && is_smaps_file (pathname);
+}
+
+/* Read the contents of an interesting file from FD (and open file
+ descriptor) into the global THE_FILE variable, making the file FD the
+ current interesting file. There should be no already open interesting
+ file when this function is called.
+
+ The contents of the file FD are read into a memory buffer and updated so
+ that any shared memory mappings listed within FD (which will be an smaps
+ file) will have the id zero. */
+
+static void
+read_interesting_file_contents (int fd)
+{
+#define BLOCK_SIZE 1024
+ /* Slurp contents into a local buffer. */
+ size_t buffer_size = 1024;
+ size_t offset = 0;
+
+ assert (the_file.size == 0);
+ assert (the_file.content == NULL);
+ assert (the_file.fd == -1);
+ assert (the_file.offset == 0);
+
+ do
+ {
+ the_file.content = (char *) realloc (the_file.content, buffer_size);
+ if (the_file.content == NULL)
+ error ("[LD_PRELOAD] Failed allocating memory: %s\n", strerror (errno));
+
+ ssize_t bytes_read = read (fd, the_file.content + offset, BLOCK_SIZE);
+ if (bytes_read == -1)
+ error ("[LD_PRELOAD] Failed reading file: %s\n", strerror (errno));
+
+ the_file.size += bytes_read;
+
+ if (bytes_read < BLOCK_SIZE)
+ break;
+
+ offset += BLOCK_SIZE;
+ buffer_size += BLOCK_SIZE;
+ }
+ while (true);
+
+ /* Add a null terminator. This makes the update easier. We know
+ there will be space because we only break out of the loop above
+ when the last read returns less than BLOCK_SIZE bytes. This means
+ we allocated an extra BLOCK_SIZE bytes, but didn't fill them all.
+ This means there must be at least 1 byte available for the null. */
+ the_file.content[the_file.size] = '\0';
+
+ /* Reset the seek pointer. */
+ if (lseek (fd, 0, SEEK_SET) == (off_t) -1)
+ error ("[LD_PRELOAD] Failed to lseek in file: %s\n", strerror (errno));
+
+ /* Record the file descriptor, this is used in read, pread, and close
+ in order to spot when we need to intercept the call. */
+ the_file.fd = fd;
+
+ update_file_content_buffer ();
+#undef BLOCK_SIZE
+}
+
+/* Intercept calls to 'open'. If this is an attempt to open a
+ /proc/PID/smaps file then intercept it, load the file contents into a
+ buffer and update the file contents. For all other open requests, just
+ forward to the real open function. */
+int
+open (const char *pathname, int flags, ...)
+{
+ /* Pointer to the real open function. */
+ static open_func_type real_open = NULL;
+
+ /* Mode is only used if the O_CREAT flag is set in FLAGS. */
+ mode_t mode = 0;
+
+ /* Set true if this is a /proc/PID/smaps file. */
+ bool is_interesting = is_interesting_pathname (pathname);
+
+ /* Check if O_CREAT is in flags. If it is, get the mode. */
+ if (flags & O_CREAT)
+ {
+ va_list args;
+ va_start (args, flags);
+ mode = va_arg (args, mode_t);
+ va_end (args);
+ }
+
+ /* Debug. */
+ if (is_interesting)
+ log_msg ("[LD_PRELOAD] Opening file: %s\n", pathname);
+
+ /* Make sure we have a pointer to the real open() function. */
+ if (real_open == NULL)
+ {
+ /* Get the address of the real open() function. */
+ real_open = (open_func_type) dlsym (RTLD_NEXT, "open");
+ if (real_open == NULL)
+ error ("[LD_PRELOAD] dlsym() error for 'open': %s\n", dlerror ());
+ }
+
+ /* Call the original open() function with the provided arguments. */
+ int res = -1;
+ if (flags & O_CREAT)
+ res = real_open (pathname, flags, mode);
+ else
+ res = real_open (pathname, flags);
+
+ if (res != -1 && is_interesting)
+ read_interesting_file_contents (res);
+
+ return res;
+}
+
+/* Like above, but for open64. */
+
+int
+open64 (const char *pathname, int flags, ...)
+{
+ /* Pointer to the real open64 function. */
+ static open_func_type real_open64 = NULL;
+
+ /* Mode is only used if the O_CREAT flag is set in FLAGS. */
+ mode_t mode = 0;
+
+ /* Set true if this is a /proc/PID/smaps file. */
+ bool is_interesting = is_interesting_pathname (pathname);
+
+ /* Check if O_CREAT is in flags. If it is, get the mode. */
+ if (flags & O_CREAT)
+ {
+ va_list args;
+ va_start (args, flags);
+ mode = va_arg (args, mode_t);
+ va_end (args);
+ }
+
+ /* Debug. */
+ if (is_interesting)
+ log_msg ("[LD_PRELOAD] Opening file: %s\n", pathname);
+
+ /* Make sure we have a pointer to the real open64() function. */
+ if (real_open64 == NULL)
+ {
+ /* Get the address of the real open64() function. */
+ real_open64 = (open_func_type) dlsym (RTLD_NEXT, "open64");
+ if (real_open64 == NULL)
+ error ("[LD_PRELOAD] dlsym() error for 'open64': %s\n", dlerror ());
+ }
+
+ /* Call the original open64() function with the provided arguments. */
+ int res = -1;
+ if (flags & O_CREAT)
+ res = real_open64 (pathname, flags, mode);
+ else
+ res = real_open64 (pathname, flags);
+
+ if (res != -1 && is_interesting)
+ read_interesting_file_contents (res);
+
+ return res;
+}
+
+/* Intercept the 'close' function. If this is a previously opened
+ interesting file then clean up. Otherwise, forward to the normal close
+ function. */
+int
+close (int fd)
+{
+ static close_func_type real_close = NULL;
+
+ if (fd == the_file.fd)
+ {
+ the_file.fd = -1;
+ free (the_file.content);
+ the_file.content = NULL;
+ the_file.offset = 0;
+ the_file.size = 0;
+ log_msg ("[LD_PRELOAD] Closing file.\n");
+ }
+
+ /* Make sure we have a pointer to the real open() function. */
+ if (real_close == NULL)
+ {
+ /* Get the address of the real open() function. */
+ real_close = (close_func_type) dlsym (RTLD_NEXT, "close");
+ if (real_close == NULL)
+ error ("[LD_PRELOAD] dlsym() error for 'close': %s\n", dlerror ());
+ }
+
+ return real_close (fd);
+}
+
+/* Intercept 'pread' calls. If this is a pread from a previously opened
+ interesting file, then read from the in memory buffer. Otherwise,
+ forward to the real pread function. */
+ssize_t
+pread (int fd, void *buf, size_t count, off_t offset)
+{
+ static pread_func_type real_pread = NULL;
+
+ if (fd == the_file.fd)
+ {
+ size_t max;
+
+ if (offset > the_file.size)
+ max = 0;
+ else
+ max = the_file.size - offset;
+ if (count > max)
+ count = max;
+
+ memcpy (buf, the_file.content + offset, count);
+ log_msg ("[LD_PRELOAD] Read from file.\n");
+ return count;
+ }
+
+ if (real_pread == NULL)
+ {
+ /* Get the address of the real read() function. */
+ real_pread = (pread_func_type) dlsym (RTLD_NEXT, "pread");
+ if (real_pread == NULL)
+ error ("[LD_PRELOAD] dlsym() error for 'pread': %s\n", dlerror ());
+ }
+
+ return real_pread (fd, buf, count, offset);
+}
+
+/* Intercept 'read' calls. If this is a read from a previously opened
+ interesting file, then read from the in memory buffer. Otherwise,
+ forward to the real read function. */
+ssize_t
+read (int fd, void *buf, size_t count)
+{
+ static read_func_type real_read = NULL;
+
+ if (fd == the_file.fd)
+ {
+ ssize_t bytes_read = pread (fd, buf, count, the_file.offset);
+ if (bytes_read > 0)
+ the_file.offset += bytes_read;
+ return bytes_read;
+ }
+
+ if (real_read == NULL)
+ {
+ /* Get the address of the real read() function. */
+ real_read = (read_func_type) dlsym (RTLD_NEXT, "read");
+ if (real_read == NULL)
+ error ("[LD_PRELOAD] dlsym() error for 'read': %s\n", dlerror ());
+ }
+
+ return real_read (fd, buf, count);
+}
diff --git a/gdb/testsuite/gdb.base/corefile-shmem-zero-id.c b/gdb/testsuite/gdb.base/corefile-shmem-zero-id.c
new file mode 100644
index 0000000..92d2edf
--- /dev/null
+++ b/gdb/testsuite/gdb.base/corefile-shmem-zero-id.c
@@ -0,0 +1,63 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2025 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 <http://www.gnu.org/licenses/>. */
+
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include <time.h>
+
+void
+breakpt (void)
+{
+ /* Nothing. */
+}
+
+int
+main (void)
+{
+ /* Create a shared memory mapping. */
+ int sid = shmget (IPC_PRIVATE, 0x1000, IPC_CREAT | IPC_EXCL | 0777);
+ if (sid == -1)
+ {
+ perror ("shmget");
+ exit (1);
+ }
+
+ /* Attach the shared memory mapping. */
+ void *addr = shmat (sid, NULL, SHM_RND);
+ if (addr == (void *) -1L)
+ {
+ perror ("shmat");
+ exit (1);
+ }
+
+ breakpt ();
+
+ /* Mark the shared memory mapping as deleted -- once the last user
+ has finished with it. */
+ if (shmctl (sid, IPC_RMID, NULL) != 0)
+ {
+ perror ("shmctl");
+ exit (1);
+ }
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/corefile-shmem-zero-id.exp b/gdb/testsuite/gdb.base/corefile-shmem-zero-id.exp
new file mode 100644
index 0000000..57c665e
--- /dev/null
+++ b/gdb/testsuite/gdb.base/corefile-shmem-zero-id.exp
@@ -0,0 +1,228 @@
+# Copyright 2025 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 <http://www.gnu.org/licenses/>.
+
+# This test script tries to check GDB's ability to create a core file
+# (e.g. with 'gcore' command) when there's a shared memory mapping
+# with the id zero.
+#
+# Testing this case is hard. Older kernels don't even seem to give
+# out the shared memory id zero. And on new kernels you still cannot
+# guarantee to grab the zero id for testing; the id might be in use by
+# some other process, or the kernel might just not give out that id
+# for some other reason.
+#
+# To figure out which mappings to include in the core file, GDB reads
+# the /proc/PID/smaps file. There is a field in this file which for
+# file backed mappings, holds the inode of the file. But for shared
+# memory mappings this field holds the shared memory id. The problem
+# was that GDB would ignore any entry in /proc/PID/smaps with an inode
+# entry of zero, which would catch the shared memory mapping with a
+# zero id.
+#
+# There was an attempt to write a test which spammed out requests for
+# shared memory mappings and tried to find the one with id zero, but
+# this was still really unreliable.
+#
+# This test takes a different approach. We compile a library which we
+# preload into the GDB process. This library intercepts calls to
+# open, close, read, and pread, and watches for an attempt to open the
+# /proc/PID/smaps file.
+#
+# When we see that file being opened, we copy the file contents into a
+# memory buffer and modify the buffer so that the inode field for any
+# shared memory mappings is set to zero. We then intercept calls to
+# read and pread and return results from that in memory buffer.
+#
+# The test executable itself create a shared memory mapping (which
+# might have any id).
+#
+# GDB, with the pre-load library in place, start the inferior and then
+# uses the 'gcore' command to dump a core file. When GDB opens the
+# smaps file and reads from it, the preload library ensures that GDB
+# sees an inode of zero.
+#
+
+# This test only works on Linux
+require isnative
+require {!is_remote host}
+require {!is_remote target}
+require {istarget *-linux*}
+require gcore_cmd_available
+
+standard_testfile .c -lib.c
+
+set libfile ${testfile}-lib
+set libobj [standard_output_file ${libfile}.so]
+
+# Compile the preload library. We only get away with this as we
+# limit this test to running when ISNATIVE is true.
+if { [build_executable "build preload lib" $libobj $srcfile2 \
+ {debug shlib libs=-ldl}] == -1 } {
+ return
+}
+
+# Now compile the inferior executable.
+if {[build_executable "build executable" $testfile $srcfile] == -1} {
+ return
+}
+
+# Spawn GDB with LIBOBJ preloaded using LD_PRELOAD.
+save_vars { env(LD_PRELOAD) env(ASAN_OPTIONS) } {
+ if { ![info exists env(LD_PRELOAD) ]
+ || $env(LD_PRELOAD) == "" } {
+ set env(LD_PRELOAD) "$libobj"
+ } else {
+ append env(LD_PRELOAD) ":$libobj"
+ }
+
+ # Prevent address sanitizer error:
+ # ASan runtime does not come first in initial library list; you should
+ # either link runtime to your application or manually preload it with
+ # LD_PRELOAD.
+ append_environment_default ASAN_OPTIONS verify_asan_link_order 0
+
+ clean_restart $binfile
+
+ # Start GDB with the modified environment, this means that, when
+ # using remote targets, gdbserver will also use the preload
+ # library.
+ if {![runto_main]} {
+ return
+ }
+}
+
+gdb_breakpoint breakpt
+gdb_continue_to_breakpoint "run to breakpt"
+
+# Check the /proc/PID/smaps file itself. The call to 'cat' should
+# inherit the preload library, so should see the modified file
+# contents. Check that the shared memory mapping line has an id of
+# zero. This confirms that the preload library is working. If the
+# preload library breaks then we'll start seeing non-zero shared
+# memory ids, which always worked, so we'd never know that this test
+# is broken!
+#
+# This check ensures the test is working as expected.
+set shmem_line_count 0
+set fixup_line_count 0
+set inf_pid [get_inferior_pid]
+gdb_test_multiple "shell cat /proc/${inf_pid}/smaps" "check smaps" {
+ -re "^\\\[LD_PRELOAD\\\] updated a shared memory mapping\r\n" {
+ incr fixup_line_count
+ exp_continue
+ }
+ -re "^\[^\r\n\]+($decimal)\\s+/SYSV\[0-9\]{8}(?: \\(deleted\\))?\r\n" {
+ set id $expect_out(1,string)
+ if { $id == 0 } {
+ incr shmem_line_count
+ }
+ exp_continue
+ }
+ -re "^$gdb_prompt $" {
+ with_test_prefix $gdb_test_name {
+ gdb_assert { $shmem_line_count == 1 } \
+ "single shared memory mapping found"
+ gdb_assert { $fixup_line_count == 1 } \
+ "single fixup line found"
+ }
+ }
+ -re "^\[^\r\n\]+\r\n" {
+ exp_continue
+ }
+}
+
+# Now generate a core file. This will use the preload library to read
+# the smaps file. The code below is copied from 'proc gdb_gcore_cmd',
+# but we don't use that as we also look for a message that is printed
+# by the LD_PRELOAD library. This is an extra level of check that the
+# preload library is triggering when needed.
+set corefile [standard_output_file ${testfile}.core]
+set saw_ld_preload_msg false
+set saw_saved_msg false
+with_timeout_factor 3 {
+ gdb_test_multiple "gcore $corefile" "save core file" {
+ -re "^\\\[LD_PRELOAD\\\] updated a shared memory mapping\r\n" {
+ # GDB actually reads the smaps file multiple times when
+ # creating a core file, so we'll see multiple of these
+ # fixup lines.
+ set saw_ld_preload_msg true
+ exp_continue
+ }
+ -re "^Saved corefile \[^\r\n\]+\r\n" {
+ set saw_saved_msg true
+ exp_continue
+ }
+ -re "^$gdb_prompt $" {
+ with_test_prefix $gdb_test_name {
+ gdb_assert { $saw_saved_msg } \
+ "saw 'Saved corefile' message"
+
+ # If we're using a remote target then the message from
+ # the preload library will go to gdbservers stdout,
+ # not GDB's, so don't check for it.
+ if { [gdb_protocol_is_native] } {
+ gdb_assert { $saw_ld_preload_msg } \
+ "saw LD_PRELOAD message from library"
+ }
+ }
+ }
+ -re "^\[^\r\n\]*\r\n" {
+ exp_continue
+ }
+ }
+}
+
+# Restart GDB. This time we are _not_ using the preload library. We
+# no longer need it as we are only analysing the core file now.
+clean_restart $binfile
+
+# Load the core file.
+gdb_test "core-file $corefile" \
+ "Program terminated with signal SIGTRAP, Trace/breakpoint trap\\..*" \
+ "load core file"
+
+# Look through the mappings. We _should_ see the shared memory
+# mapping. We _should_not_ see any of the special '[blah]' style
+# mappings, e.g. [vdso], [vstack], [vsyscalls], etc.
+set saw_special_mapping false
+set saw_shmem_mapping false
+gdb_test_multiple "info proc mappings" "" {
+ -re "\r\nStart Addr\[^\r\n\]+File\\s*\r\n" {
+ exp_continue
+ }
+
+ -re "^$hex\\s+$hex\\s+$hex\\s+$hex\\s+\\\[\\S+\\\]\\s*\r\n" {
+ set saw_special_mapping true
+ exp_continue
+ }
+
+ -re "^$hex\\s+$hex\\s+$hex\\s+$hex\\s+/SYSV\[0-9\]+ \\(deleted\\)\\s*\r\n" {
+ set saw_shmem_mapping true
+ exp_continue
+ }
+
+ -re "^$hex\\s+$hex\\s+$hex\\s+$hex\[^\r\n\]*\r\n" {
+ exp_continue
+ }
+
+ -re "^$gdb_prompt $" {
+ with_test_prefix $gdb_test_name {
+ gdb_assert { $saw_shmem_mapping } \
+ "check shared memory mapping exists"
+ gdb_assert { !$saw_special_mapping } \
+ "check no special mappings added"
+ }
+ }
+}
diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp
index 3abd049..01e3cc1 100644
--- a/gdb/testsuite/gdb.base/default.exp
+++ b/gdb/testsuite/gdb.base/default.exp
@@ -253,10 +253,39 @@ gdb_test "h" "List of classes of commands:(\[^\r\n\]*\[\r\n\])+aliases -- User-d
gdb_test "help" "List of classes of commands:(\[^\r\n\]*\[\r\n\])+aliases -- User-defined aliases of other commands(\[^\r\n\]*\[\r\n\])+breakpoints -- Making program stop at certain points(\[^\r\n\]*\[\r\n\])+data -- Examining data(\[^\r\n\]*\[\r\n\])+files -- Specifying and examining files(\[^\r\n\]*\[\r\n\])+obscure -- Obscure features(\[^\r\n\]*\[\r\n\])+running -- Running the program(\[^\r\n\]*\[\r\n\])+stack -- Examining the stack(\[^\r\n\]*\[\r\n\])+status -- Status inquiries(\[^\r\n\]*\[\r\n\])+support -- Support facilities(\[^\r\n\]*\[\r\n\])+user-defined -- User-defined commands(\[^\r\n\]*\[\r\n\])+Type \"help\" followed by a class name for a list of commands in that class.(\[^\r\n\]*\[\r\n\])+Type \"help\" followed by command name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
#test handle
gdb_test "handle" "Argument required .signal to handle.*"
-#test info "i" abbreviation
-gdb_test "i" "List of \"info\" subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help info\" followed by subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "info \"i\" abbreviation"
+
+proc test_info_command { command message } {
+ set saw_info_header 0
+ set saw_help_info 0
+ set saw_command_abbrev 0
+ gdb_test_multiple $command $message -lbl {
+ -re "\r\nList of \"info\" subcommands:" {
+ verbose "Info header displayed"
+ set saw_info_header 1
+ exp_continue
+ }
+ -re "Type \"help info\" followed by subcommand name for full documentation\\." {
+ verbose "Help info displayed"
+ set saw_help_info 1
+ exp_continue
+ }
+ -re "\r\nCommand name abbreviations are allowed if unambiguous\\." {
+ verbose "Command name abbreviations displayed"
+ set saw_command_abbrev 1
+ exp_continue
+ }
+ -re -wrap "" {
+ gdb_assert { $saw_info_header && $saw_help_info
+ && $saw_command_abbrev } $gdb_test_name
+ }
+ }
+}
+
+#test info "i" abbreviation
+test_info_command "i" "info \"i\" abbreviation"
#test info
-gdb_test "info" "List of \"info\" subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help info\" followed by subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
+test_info_command "info" "info"
+
#test ignore
gdb_test "ignore" "Argument required .a breakpoint number.*"
#test info address
@@ -379,38 +408,52 @@ gdb_test "info registers" "The program has no registers now."
gdb_test "info s" "No stack." "info stack \"s\" abbreviation"
#test info stack
gdb_test "info stack" "No stack."
-#test info set
-# Test improved to check three parts:
-# 1) confirm
-# 2) prompt
-# 3) write
-# And only succeed if all three are matched.
-# This should fix an old problem on native solaris 2.8,
-# where this test fails due to this line:
+
+#test "info set" and "show" commands
+# The test needs to match the "prompt: ..." part to fix an old problem on native
+# Solaris 2.8, where this test fails due to this line:
# prompt: Gdb's prompt is "(gdb) ".^M
-set set_confirm_seen 0
-set set_prompt_seen 0
-gdb_test_multiple "info set" "info set" {
- -re "confirm: Whether to confirm potentially dangerous operations is o\[a-z\]*.(\[^\r\n\]*\[\r\n\])+history filename: The filename in which to record the command history is (\[^\r\n\]*\[\r\n\])+listsize: Number of source lines gdb will list by default is 10" {
- verbose "Confirm dislayed"
- set set_confirm_seen 1
- exp_continue
- }
- -re "Gdb's prompt is \"$gdb_prompt \"" {
- verbose "GDB prompt displayed"
- set set_prompt_seen 1
- exp_continue
- }
- -re "Writing into executable.*$gdb_prompt $" {
- verbose "write displayed"
- if { $set_prompt_seen && $set_confirm_seen } {
- pass "info set"
- } else {
- verbose "prompt $set_prompt_seen confirm $set_confirm_seen"
- fail "info set (incomplete output)"
+proc test_info_set_show { command } {
+ set set_confirm_seen 0
+ set set_history_filename_seen 0
+ set set_listsize_seen 0
+ set set_prompt_seen 0
+ set set_write_seen 0
+ gdb_test_multiple $command $command -lbl {
+ -re "\r\nconfirm: Whether to confirm potentially dangerous operations is o\[a-z\]+\\." {
+ verbose "Confirm displayed"
+ set set_confirm_seen 1
+ exp_continue
+ }
+ -re "\r\nhistory filename: The filename in which to record the command history is \[^\r\n\]+\\." {
+ verbose "History filename displayed"
+ set set_history_filename_seen 1
+ exp_continue
+ }
+ -re "\r\nlistsize: Number of source lines gdb will list by default is 10\\." {
+ verbose "Listsize displayed"
+ set set_listsize_seen 1
+ exp_continue
+ }
+ -re "\r\nprompt: Gdb's prompt is \"$::gdb_prompt \"" {
+ verbose "GDB prompt displayed"
+ set set_prompt_seen 1
+ exp_continue
+ }
+ -re "write: Writing into executable and core files is o\[a-z\]+\\." {
+ verbose "Write displayed"
+ set set_write_seen 1
+ exp_continue
+ }
+ -re -wrap "" {
+ gdb_assert { $set_confirm_seen && $set_history_filename_seen
+ && $set_listsize_seen && $set_prompt_seen
+ && $set_write_seen } $gdb_test_name
}
}
}
+test_info_set_show "info set"
+
gdb_test "info symbol" "Argument required .address.."
#test info source
gdb_test "info source" "No current source file..*"
@@ -591,12 +634,41 @@ gdb_test "set history" "List of \"set history\" subcommands:(\[^\r\n\]*\[\r\n\])
gdb_test "set language" "Requires an argument. Valid arguments are auto, local, unknown, ada, asm, c, c.., d, fortran, go, minimal, modula-2, objective-c, opencl, pascal, rust."
#test set listsize
gdb_test "set listsize" "Argument required .integer to set it to.*"
+
+proc test_set_print { command message } {
+ set saw_info_header 0
+ set saw_help_info 0
+ set saw_command_abbrev 0
+ gdb_test_multiple $command $message -lbl {
+ -re "\r\nList of \"set print\" subcommands:" {
+ verbose "Info header displayed"
+ set saw_info_header 1
+ exp_continue
+ }
+ -re "Type \"help set print\" followed by subcommand name for full documentation\\." {
+ verbose "Help info displayed"
+ set saw_help_info 1
+ exp_continue
+ }
+ -re "\r\nCommand name abbreviations are allowed if unambiguous\\." {
+ verbose "Command name abbreviations displayed"
+ set saw_command_abbrev 1
+ exp_continue
+ }
+ -re -wrap "" {
+ gdb_assert { $saw_info_header && $saw_help_info
+ && $saw_command_abbrev } $gdb_test_name
+ }
+ }
+}
+
#test set print "p" abbreviation
-gdb_test "set p" "List of \"set print\" subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help set print\" followed by subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set print \"p\" abbreviation"
+test_set_print "set p" "set print \"p\" abbreviation"
#test set print "pr" abbreviation
-gdb_test "set pr" "List of \"set print\" subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help set print\" followed by subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set print \"pr\" abbreviation"
+test_set_print "set pr" "set print \"pr\" abbreviation"
#test set print
-gdb_test "set print" "List of \"set print\" subcommands:(\[^\r\n\]*\[\r\n\])+Type \"help set print\" followed by subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
+test_set_print "set print" "set print"
+
#test set print address
gdb_test_no_output "set print address" "set print address"
#test set print array
@@ -700,7 +772,7 @@ set show_conv_list \
{$_shell_exitsignal = void} \
{$_shell_exitcode = 0} \
{$_active_linker_namespaces = 1} \
- {$_current_linker_namespace = <error: No registers.>}\
+ {$_linker_namespace = <error: No registers.>}\
}
if [allow_python_tests] {
append show_conv_list \
@@ -741,12 +813,47 @@ gdb_test "show history" "history expansion: *History expansion on command input
gdb_test "show language" "The current source language is \"auto; currently c\"."
#test show listsize
gdb_test "show listsize" "Number of source lines gdb will list by default is 10."
+
+proc test_show_print { command } {
+ set saw_print_address 0
+ set saw_print_frame_args 0
+ set saw_print_symbol 0
+ set saw_print_vtbl 0
+ gdb_test_multiple $command $command -lbl {
+ -re "\r\nprint address: Printing of addresses is o\[a-z\]+\\." {
+ verbose "Print address displayed"
+ set saw_print_address 1
+ exp_continue
+ }
+ -re "\r\nprint frame-arguments: Printing of non-scalar frame arguments is \[^\r\n\]+\\." {
+ verbose "Print frame-arguments displayed"
+ set saw_print_frame_args 1
+ exp_continue
+ }
+ -re "\r\nprint symbol: Printing of symbols when printing pointers is o\[a-z\]+\\." {
+ verbose "Print symbol displayed"
+ set saw_print_symbol 1
+ exp_continue
+ }
+ -re "\r\nprint vtbl: Printing of C\\+\\+ virtual function tables is o\[a-z\]+\\." {
+ verbose "Print vtbl displayed"
+ set saw_print_vtbl 1
+ exp_continue
+ }
+ -re -wrap "" {
+ gdb_assert { $saw_print_address && $saw_print_frame_args
+ && $saw_print_symbol && $saw_print_vtbl } $gdb_test_name
+ }
+ }
+}
+
#test show print "p" abbreviation
-gdb_test "show p" ".*"
+test_show_print "show p"
#test show print "pr" abbreviation
-gdb_test "show pr" ".*"
+test_show_print "show pr"
#test show print
-gdb_test "show print" ".*"
+test_show_print "show print"
+
#test show paths
gdb_test "show paths" "Executable and object file path:.*"
#test show print address
@@ -792,30 +899,10 @@ gdb_test "show width" "Number of characters gdb thinks are in a line is.*"
#test show write
# This is only supported on targets which use exec.o.
gdb_test "show write" "Writing into executable and core files is o.*"
+
#test show
-set show_confirm_seen 0
-set show_prompt_seen 0
-gdb_test_multiple "show" "show" {
- -re "confirm: *Whether to confirm potentially dangerous operations is on.(\[^\r\n\]*\[\r\n\])+history filename: *The filename in which to record the command history is (\[^\r\n\]*\[\r\n\])+history save: *Saving of the history record on exit is on.(\[^\r\n\]*\[\r\n\])+history size: *The size of the command history is(\[^\r\n\]*\[\r\n\])+listsize: *Number of source lines gdb will list by default is 10(\[^\r\n]*\[\r\n\])+print elements: *Limit on string chars or array elements to print is 200." {
- verbose "Confirm displayed"
- set show_confirm_seen 1
- exp_continue
- }
- -re "Gdb's prompt is \"$gdb_prompt \"" {
- verbose "GDB prompt displayed"
- set show_prompt_seen 1
- exp_continue
- }
- -re "Writing into executable.*$gdb_prompt $" {
- verbose "write displayed"
- if { $show_prompt_seen && $show_confirm_seen } {
- pass "show"
- } else {
- verbose "prompt $show_prompt_seen confirm $show_confirm_seen"
- fail "show (incomplete output)"
- }
- }
-}
+test_info_set_show "show"
+
#history saving should stay disabled
gdb_test_no_output "set history save off" "set history save off"
#test stepi "si" abbreviation
diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
index 8f52199..4d3e8eb 100644
--- a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
+++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
@@ -112,7 +112,7 @@ proc_with_prefix test_conv_vars {} {
gdb_test "print \$_active_linker_namespaces" "1" \
"1 namespace before starting inferior"
- gdb_test "print \$_current_linker_namespace" "No registers." \
+ gdb_test "print \$_linker_namespace" "No registers." \
"No current namespace before starting inferior"
if { ![runto_main] } {
@@ -121,7 +121,7 @@ proc_with_prefix test_conv_vars {} {
gdb_test "print \$_active_linker_namespaces" "1" \
"Before activating namespaces"
- gdb_test "print \$_current_linker_namespace" ".*\"\\\[\\\[0\\\]\\\]\"" \
+ gdb_test "print \$_linker_namespace" ".* = 0" \
"Still in the default namespace"
gdb_breakpoint "inc" allow-pending
@@ -130,10 +130,16 @@ proc_with_prefix test_conv_vars {} {
foreach_with_prefix dl {3 2 1} {
gdb_continue_to_breakpoint "inc"
- gdb_test "print \$_current_linker_namespace" ".*\"\\\[\\\[$dl\\\]\\\]\"" \
+ gdb_test "print \$_linker_namespace" ".* = $dl" \
"Verify we're in namespace $dl"
}
+ # Check that we display the namespace of the selected
+ # frame, not the lowermost one.
+ gdb_test "up" "\#1.*in main.*"
+ gdb_test "print \$_linker_namespace" ".* = 0" \
+ "print namespace of selected frame"
+
gdb_continue_to_breakpoint "first dlclose"
gdb_test "print \$_active_linker_namespaces" "4" "all SOs loaded"
@@ -154,7 +160,7 @@ proc_with_prefix test_conv_vars {} {
# breakpoints and pending breakpoints at the same time with
# gdb_breakpoint.
gdb_test "next" ".*assert.*" "load the first SO"
- gdb_breakpoint "inc if \$_streq(\$_current_linker_namespace, \"\[\[2\]\]\")"
+ gdb_breakpoint "inc if \$_linker_namespace == 2"
gdb_continue_to_breakpoint "inc"
gdb_continue_to_end "" continue 1
}
@@ -163,6 +169,12 @@ proc_with_prefix test_conv_vars {} {
proc test_info_linker_namespaces {} {
clean_restart $::binfile
+ # Check that "info linker-namespaces" while the inferior is not running
+ # doesn't crash.
+ gdb_test "info linker-namespaces" \
+ "Current inferior does not support linker namespaces\\. Use \"info sharedlibrary\" instead\\." \
+ "info linker-namespaces before running"
+
if { ![runto_main] } {
return
}
diff --git a/gdb/testsuite/gdb.base/filename-completion.exp b/gdb/testsuite/gdb.base/filename-completion.exp
index cb3fc90..c10941c 100644
--- a/gdb/testsuite/gdb.base/filename-completion.exp
+++ b/gdb/testsuite/gdb.base/filename-completion.exp
@@ -385,7 +385,7 @@ proc run_quoting_and_escaping_tests { root } {
remove-symbol-file \
"target core" "target exec" "target tfile" \
"maint print c-tdesc" "save gdb-index"
- "save gdb-index -dwarf-5" }
+ "save gdb-index -dwarf-5" "shell ls"}
if { [allow_compile_tests] } {
lappend all_cmds "compile file"
}
@@ -408,6 +408,31 @@ proc run_quoting_and_escaping_tests { root } {
run_quoting_and_escaping_tests_1 $root $cmd
}
}
+
+ # Some additional testing of shell command. Test 'shell' and '!'
+ # when there are multiple filenames on the command line. This
+ # focuses on completion of the final filename. There is also some
+ # testing of the shell command above, this tests completion within
+ # the line.
+ foreach_with_prefix shell_cmd { "shell " "!" "pipe print 1 | " } {
+ foreach suffix { "aaa/aa bb" "bb2/dir 1/unique file" } {
+ set dir $root/$suffix
+
+ regsub -all " " "$dir" "\\ " dir_with_backslash
+
+ with_test_prefix "suffix='$suffix'" {
+ with_test_prefix "with_backslash" {
+ run_quoting_and_escaping_tests_1 $root "${shell_cmd}ls $dir_with_backslash"
+ }
+ with_test_prefix "with double quotes" {
+ run_quoting_and_escaping_tests_1 $root "${shell_cmd}ls \"$dir\""
+ }
+ with_test_prefix "with single quotes" {
+ run_quoting_and_escaping_tests_1 $root "${shell_cmd}ls '$dir'"
+ }
+ }
+ }
+ }
}
# Helper for run_unquoted_tests. ROOT is the root directory as setup
diff --git a/gdb/testsuite/gdb.base/foll-exec-c++.exp b/gdb/testsuite/gdb.base/foll-exec-c++.exp
new file mode 100644
index 0000000..d96310b
--- /dev/null
+++ b/gdb/testsuite/gdb.base/foll-exec-c++.exp
@@ -0,0 +1,24 @@
+# Copyright 2025 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 <http://www.gnu.org/licenses/>.
+
+# This file is part of the gdb testsuite
+
+# See foll-exec.exp.tcl for test details. This file runs the test
+# using the C++ compiler.
+
+require allow_cplus_tests
+set lang c++
+
+source $srcdir/$subdir/foll-exec.exp.tcl
diff --git a/gdb/testsuite/gdb.base/foll-exec-c.exp b/gdb/testsuite/gdb.base/foll-exec-c.exp
new file mode 100644
index 0000000..67f62cc
--- /dev/null
+++ b/gdb/testsuite/gdb.base/foll-exec-c.exp
@@ -0,0 +1,23 @@
+# Copyright 2025 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 <http://www.gnu.org/licenses/>.
+
+# This file is part of the gdb testsuite
+
+# See foll-exec.exp.tcl for test details. This file runs the test
+# using the C compiler.
+
+set lang c
+
+source $srcdir/$subdir/foll-exec.exp.tcl
diff --git a/gdb/testsuite/gdb.base/foll-exec.c b/gdb/testsuite/gdb.base/foll-exec.c
index a1c9b70..291f803 100644
--- a/gdb/testsuite/gdb.base/foll-exec.c
+++ b/gdb/testsuite/gdb.base/foll-exec.c
@@ -19,25 +19,38 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
-
+#include <libgen.h>
+#include <assert.h>
#include <limits.h>
int global_i = 100;
+#ifndef EXECD_PROG
+#define EXECD_PROG "execd-prog"
+#endif
+
int main (int argc, char ** argv)
{
int local_j = global_i + 1;
int local_k = local_j + 1;
char prog[PATH_MAX];
- int len;
+ size_t len = PATH_MAX - 1;
+
+ printf ("foll-exec is about to execlp(%s)...\n", EXECD_PROG);
+
+ prog [len] = '\0';
+
+ strncpy (prog, dirname (argv[0]), len);
+ len -= strlen (prog);
+ assert (len > 0);
- printf ("foll-exec is about to execlp(execd-prog)...\n");
+ strncat (prog, "/", len);
+ len -= 1;
+ assert (len > 0);
- strcpy (prog, argv[0]);
- len = strlen (prog);
- /* Replace "foll-exec" with "execd-prog". */
- memcpy (prog + len - 9, "execd-prog", 10);
- prog[len + 1] = 0;
+ strncat (prog, EXECD_PROG, len);
+ len -= strlen (EXECD_PROG);
+ assert (len > 0);
/* In the following function call, maximum line length exceed the limit 80.
This is intentional and required for clang compiler such that complete
@@ -45,7 +58,7 @@ int main (int argc, char ** argv)
multi-line. */
execlp (prog, /* tbreak-execlp */ prog, "execlp arg1 from foll-exec", (char *) 0);
- printf ("foll-exec is about to execl(execd-prog)...\n");
+ printf ("foll-exec is about to execl(%s)...\n", EXECD_PROG);
/* In the following function call, maximum line length exceed the limit 80.
This is intentional and required for clang compiler such that complete
@@ -61,7 +74,7 @@ int main (int argc, char ** argv)
argv[0] = prog;
- printf ("foll-exec is about to execv(execd-prog)...\n");
+ printf ("foll-exec is about to execv(%s)...\n", EXECD_PROG);
execv (prog, argv); /* tbreak-execv */
}
diff --git a/gdb/testsuite/gdb.base/foll-exec.exp b/gdb/testsuite/gdb.base/foll-exec.exp.tcl
index ad4c3516..8f96a55 100644
--- a/gdb/testsuite/gdb.base/foll-exec.exp
+++ b/gdb/testsuite/gdb.base/foll-exec.exp.tcl
@@ -22,33 +22,55 @@ require {istarget "*-linux*"}
standard_testfile foll-exec.c
-set testfile2 "execd-prog"
-set srcfile2 ${testfile2}.c
-set binfile2 [standard_output_file ${testfile2}]
+# Compile a program that performs an exec as EXECER_LANG, and a
+# program that will be exec'd as EXECEE_LANG. Either language can be
+# 'c' or 'c++'. Then run various test associated with 'catch exec'
+# using the compiled programs.
+proc do_exec_tests { execer_lang execee_lang } {
+ global srcfile testfile
+ global gdb_prompt
-set compile_options debug
+ # First compile the program to be exec'd, the execee.
+ set execee_base_filename "execd-prog"
+ set srcfile2 ${execee_base_filename}.c
+ set execee_testfile "execd-prog-${execee_lang}"
+ set execee_testfile_re [string_to_regexp $execee_testfile]
+ set execee_binfile [standard_output_file $execee_testfile]
-# build the first test case
-if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable $compile_options] != "" } {
- untested "failed to compile"
- return -1
-}
+ set execee_flags debug
+ if { $execee_lang == "c++" } {
+ lappend execee_flags "c++"
+ }
-if { [is_remote target] } {
- gdb_remote_download target $binfile2
-}
+ if { [build_executable "failed to build $execee_testfile" $execee_testfile \
+ $srcfile2 $execee_flags] == -1 } {
+ return
+ }
-if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable $compile_options] != "" } {
- untested "failed to compile"
- return -1
-}
+ if { [is_remote target] } {
+ gdb_remote_download target $execee_binfile
+ }
-proc do_exec_tests {} {
- global binfile srcfile srcfile2 testfile testfile2
- global gdb_prompt
+
+ # Now compile the program to do the exec, the execer.
+ set execer_testfile "$testfile-${execee_lang}"
+ set execer_binfile [standard_output_file $execer_testfile]
+
+ set execer_flags debug
+ if { $execer_lang == "c++" } {
+ lappend execer_flags "c++"
+ }
+ lappend execer_flags "additional_flags=-DEXECD_PROG=\"${execee_testfile}\""
+
+ if { [build_executable "failed to build $execer_testfile" $execer_testfile \
+ $srcfile $execer_flags] == -1 } {
+ return
+ }
+
+ # Now we can start running the tests.
+ clean_restart $execer_binfile
# Start the program running, and stop at main.
- #
if {![runto_main]} {
return
}
@@ -71,7 +93,7 @@ proc do_exec_tests {} {
return
}
- clean_restart $binfile
+ clean_restart $execer_binfile
# Start the program running, and stop at main.
#
@@ -120,7 +142,7 @@ proc do_exec_tests {} {
set execd_line [gdb_get_line_number "after-exec" $srcfile2]
send_gdb "next\n"
gdb_expect {
- -re ".*xecuting new program: .*${testfile2}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\
+ -re ".*xecuting new program: .*${execee_testfile_re}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\
{pass "step through execlp call"}
-re "$gdb_prompt $" {fail "step through execlp call"}
timeout {fail "(timeout) step through execlp call"}
@@ -160,7 +182,7 @@ proc do_exec_tests {} {
# Explicitly kill this program, or a subsequent rerun actually runs
# the exec'd program, not the original program...
- clean_restart $binfile
+ clean_restart $execer_binfile
# Start the program running, and stop at main.
#
@@ -193,7 +215,7 @@ proc do_exec_tests {} {
send_gdb "continue\n"
gdb_expect {
- -re ".*xecuting new program:.*${testfile2}.*Catchpoint .*(exec\'d .*${testfile2}).*$gdb_prompt $"\
+ -re ".*xecuting new program:.*${execee_testfile_re}.*Catchpoint .*(exec\'d .*${execee_testfile_re}).*$gdb_prompt $"\
{pass "hit catch exec"}
-re "$gdb_prompt $" {fail "hit catch exec"}
timeout {fail "(timeout) hit catch exec"}
@@ -210,7 +232,7 @@ proc do_exec_tests {} {
#
set msg "info shows catchpoint exec pathname"
gdb_test_multiple "info breakpoints" $msg {
- -re ".*catchpoint.*keep y.*exec, program \".*${testfile2}\".*$gdb_prompt $" {
+ -re ".*catchpoint.*keep y.*exec, program \".*${execee_testfile_re}\".*$gdb_prompt $" {
pass $msg
}
}
@@ -228,7 +250,7 @@ proc do_exec_tests {} {
# Explicitly kill this program, or a subsequent rerun actually runs
# the exec'd program, not the original program...
- clean_restart $binfile
+ clean_restart $execer_binfile
# Start the program running, and stop at main.
#
@@ -269,7 +291,7 @@ proc do_exec_tests {} {
#
send_gdb "next 2\n"
gdb_expect {
- -re ".*xecuting new program: .*${testfile2}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\
+ -re ".*xecuting new program: .*${execee_testfile_re}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\
{pass "step through execl call"}
-re "$gdb_prompt $" {fail "step through execl call"}
timeout {fail "(timeout) step through execl call"}
@@ -295,7 +317,7 @@ proc do_exec_tests {} {
# Explicitly kill this program, or a subsequent rerun actually runs
# the exec'd program, not the original program...
- clean_restart $binfile
+ clean_restart $execer_binfile
# Start the program running, and stop at main.
#
@@ -330,7 +352,7 @@ proc do_exec_tests {} {
}
send_gdb "next\n"
gdb_expect {
- -re ".*xecuting new program: .*${testfile2}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\
+ -re ".*xecuting new program: .*${execee_testfile_re}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\
{pass "step through execv call"}
-re "$gdb_prompt $" {fail "step through execv call"}
timeout {fail "(timeout) step through execv call"}
@@ -356,7 +378,7 @@ proc do_exec_tests {} {
# Explicitly kill this program, or a subsequent rerun actually runs
# the exec'd program, not the original program...
- clean_restart $binfile
+ clean_restart $execer_binfile
# Start the program running, and stop at main.
#
@@ -370,13 +392,13 @@ proc do_exec_tests {} {
#
send_gdb "continue\n"
gdb_expect {
- -re ".*xecuting new program: .*${testfile2}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\
+ -re ".*xecuting new program: .*${execee_testfile_re}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\
{pass "continue through exec"}
-re "$gdb_prompt $" {fail "continue through exec"}
timeout {fail "(timeout) continue through exec"}
}
}
-clean_restart $binfile
-
-do_exec_tests
+foreach_with_prefix execee_lang { c c++ } {
+ do_exec_tests $lang $execee_lang
+}
diff --git a/gdb/testsuite/gdb.base/foll-fork-syscall.c b/gdb/testsuite/gdb.base/foll-fork-syscall.c
new file mode 100644
index 0000000..ef695f5
--- /dev/null
+++ b/gdb/testsuite/gdb.base/foll-fork-syscall.c
@@ -0,0 +1,35 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2025 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 <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include <stdio.h>
+
+int
+main (int argc, char **argv)
+{
+ int pid, x = 0;
+
+ pid = fork ();
+ if (pid == 0) /* set breakpoint here */
+ printf ("I am the child\n");
+ else
+ printf ("I am the parent\n");
+
+ chdir (".");
+ ++x; /* set exit breakpoint here */
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/foll-fork-syscall.exp b/gdb/testsuite/gdb.base/foll-fork-syscall.exp
new file mode 100644
index 0000000..21ef334
--- /dev/null
+++ b/gdb/testsuite/gdb.base/foll-fork-syscall.exp
@@ -0,0 +1,143 @@
+# Copyright 2025 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 <http://www.gnu.org/licenses/>.
+
+# Test catching syscalls with all permutations of follow-fork parent/child
+# and detach-on-fork on/off.
+
+# Test relies on checking follow-fork output. Do not run if gdb debug is
+# enabled because it will be redirected to the log.
+require !gdb_debug_enabled
+require {is_any_target "i?86-*-*" "x86_64-*-*"}
+require allow_fork_tests
+
+standard_testfile
+
+if {[build_executable "failed to prepare" $testfile $srcfile debug]} {
+ return -1
+}
+
+proc setup_gdb {} {
+ global testfile
+
+ clean_restart $testfile
+
+ if {![runto_main]} {
+ return false
+ }
+
+ # Set a breakpoint after the fork is "complete."
+ if {![gdb_breakpoint [gdb_get_line_number "set breakpoint here"]]} {
+ return false
+ }
+
+ # Set exit breakpoint (to prevent inferior from exiting).
+ if {![gdb_breakpoint [gdb_get_line_number "set exit breakpoint here"]]} {
+ return false
+ }
+ return true
+}
+
+# Check that fork catchpoints are supported, as an indicator for whether
+# fork-following is supported. Return 1 if they are, else 0.
+
+proc_with_prefix check_fork_catchpoints {} {
+ global gdb_prompt
+
+ if { ![setup_gdb] } {
+ return false
+ }
+
+ # Verify that the system supports "catch fork".
+ gdb_test "catch fork" "Catchpoint \[0-9\]* \\(fork\\)" "insert first fork catchpoint"
+ set has_fork_catchpoints false
+ gdb_test_multiple "continue" "continue to first fork catchpoint" {
+ -re ".*Your system does not support this type\r\nof catchpoint.*$gdb_prompt $" {
+ unsupported "continue to first fork catchpoint"
+ }
+ -re ".*Catchpoint.*$gdb_prompt $" {
+ set has_fork_catchpoints true
+ pass "continue to first fork catchpoint"
+ }
+ }
+
+ return $has_fork_catchpoints
+}
+
+proc_with_prefix test_catch_syscall {follow-fork-mode detach-on-fork} {
+ # Start with shiny new gdb instance.
+ if {![setup_gdb]} {
+ return
+ }
+
+ # The "Detaching..." and "Attaching..." messages may be hidden by
+ # default.
+ gdb_test_no_output "set verbose"
+
+ # Setup modes to test.
+ gdb_test_no_output "set follow-fork-mode ${follow-fork-mode}"
+ gdb_test_no_output "set detach-on-fork ${detach-on-fork}"
+
+ gdb_test "catch fork" "Catchpoint . \\(fork\\)"
+ gdb_test "catch syscall chdir" "Catchpoint . \\(syscall 'chdir'.*\\)"
+
+ # Which inferior we're expecting to follow. Assuming the parent
+ # will be inferior #1, and the child will be inferior #2.
+ if {${follow-fork-mode} == "parent"} {
+ set following_inf 1
+ } else {
+ set followin_inf 2
+ }
+ # Next stop should be the fork catchpoint.
+ set expected_re ""
+ append expected_re "Catchpoint . \\(forked process.*"
+ gdb_test "continue" $expected_re "continue to fork catchpoint"
+
+ # Next stop should be the breakpoint after the fork.
+ set expected_re ".*"
+ if {${follow-fork-mode} == "child" || ${detach-on-fork} == "off"} {
+ append expected_re "\\\[New inferior.*"
+ }
+ if {${detach-on-fork} == "on"} {
+ append expected_re "\\\[Detaching after fork from "
+ if {${follow-fork-mode} == "parent"} {
+ append expected_re "child"
+ } else {
+ append expected_re "parent"
+ }
+ append expected_re " process.*"
+ }
+ append expected_re "Breakpoint .*set breakpoint here.*"
+ gdb_test "continue" $expected_re "continue to breakpoint after fork"
+
+ # Next stop should be the syscall catchpoint.
+ set expected_re ".*Catchpoint . \\(call to syscall chdir\\).*"
+ gdb_test continue $expected_re "continue to chdir syscall"
+}
+
+# Check for follow-fork support.
+if {![check_fork_catchpoints]} {
+ untested "follow-fork not supported"
+ return
+}
+
+# Test all permutations.
+foreach_with_prefix follow-fork-mode {"parent" "child"} {
+
+ # Do not run tests when not detaching from the parent.
+ # See breakpoints/13457 for discussion.
+ foreach_with_prefix detach-on-fork {"on"} {
+ test_catch_syscall ${follow-fork-mode} ${detach-on-fork}
+ }
+}
diff --git a/gdb/testsuite/gdb.base/foll-fork.exp b/gdb/testsuite/gdb.base/foll-fork.exp
index 94755c6..12db516 100644
--- a/gdb/testsuite/gdb.base/foll-fork.exp
+++ b/gdb/testsuite/gdb.base/foll-fork.exp
@@ -17,6 +17,8 @@
# enabled as it will be redirected to the log.
require !gdb_debug_enabled
+require allow_fork_tests
+
standard_testfile
if {[build_executable "failed to prepare" $testfile $srcfile debug]} {
diff --git a/gdb/testsuite/gdb.base/foll-vfork.exp b/gdb/testsuite/gdb.base/foll-vfork.exp
index 266df46..6ca7711 100644
--- a/gdb/testsuite/gdb.base/foll-vfork.exp
+++ b/gdb/testsuite/gdb.base/foll-vfork.exp
@@ -18,12 +18,7 @@
# either execs or exits --- since those events take somewhat different
# code paths in GDB, both variants are exercised.
-# Until "set follow-fork-mode" and "catch vfork" are implemented on
-# other targets...
-#
-if {![istarget "*-linux*"]} {
- continue
-}
+require allow_fork_tests
standard_testfile .c -exit.c vforked-prog.c
diff --git a/gdb/testsuite/gdb.base/fork-no-detach-follow-child-dlopen.exp b/gdb/testsuite/gdb.base/fork-no-detach-follow-child-dlopen.exp
index 311d7ba..2d47d5d 100644
--- a/gdb/testsuite/gdb.base/fork-no-detach-follow-child-dlopen.exp
+++ b/gdb/testsuite/gdb.base/fork-no-detach-follow-child-dlopen.exp
@@ -23,6 +23,7 @@
# in the source of the shlib, and "list" should display the source where
# the program stopped.
+require allow_fork_tests
require allow_shlib_tests
standard_testfile .c -shlib.c
diff --git a/gdb/testsuite/gdb.base/fork-print-inferior-events.exp b/gdb/testsuite/gdb.base/fork-print-inferior-events.exp
index 26ed2f9..19ace00 100644
--- a/gdb/testsuite/gdb.base/fork-print-inferior-events.exp
+++ b/gdb/testsuite/gdb.base/fork-print-inferior-events.exp
@@ -19,6 +19,8 @@
# inferior-events [on,off]', 'set follow-fork-mode [child,parent]' and
# 'set detach-on-fork [on,off]' are the correct ones.
+require allow_fork_tests
+
# This test relies on "run", so it cannot run on target remote stubs.
require !use_gdb_stub
diff --git a/gdb/testsuite/gdb.base/fork-running-state.exp b/gdb/testsuite/gdb.base/fork-running-state.exp
index 4b810a6..c446800 100644
--- a/gdb/testsuite/gdb.base/fork-running-state.exp
+++ b/gdb/testsuite/gdb.base/fork-running-state.exp
@@ -17,6 +17,8 @@
# in non-stop). GDB used to miss updating the parent/child running
# states after a fork.
+require allow_fork_tests
+
standard_testfile
# The test proper.
diff --git a/gdb/testsuite/gdb.base/infcall-failure.exp b/gdb/testsuite/gdb.base/infcall-failure.exp
index 66bccd1..e7aeac1 100644
--- a/gdb/testsuite/gdb.base/infcall-failure.exp
+++ b/gdb/testsuite/gdb.base/infcall-failure.exp
@@ -131,7 +131,13 @@ proc_with_prefix run_cond_hits_segfault_test { async_p non_stop_p } {
[multi_line \
"Continuing\\." \
"" \
- "Program received signal SIGSEGV, Segmentation fault\\." \
+ [string cat \
+ [string_to_regexp \
+ "Program received signal SIGSEGV, Segmentation fault."] \
+ "("] \
+ [string cat \
+ [string_to_regexp "Address not mapped to object."] \
+ ")?"] \
"${::hex} in func_segfault \\(\\) at \[^\r\n\]+:${::segv_line}" \
"${::decimal}\\s+\[^\r\n\]+Segfault here\[^\r\n\]+" \
"Error in testing condition for breakpoint ${bp_1_num}:" \
@@ -161,7 +167,13 @@ proc_with_prefix run_call_hits_segfault_test { async_p non_stop_p } {
gdb_test "call func_segfault ()" \
[multi_line \
"" \
- "Program received signal SIGSEGV, Segmentation fault\\." \
+ [string cat \
+ [string_to_regexp \
+ "Program received signal SIGSEGV, Segmentation fault."] \
+ "("] \
+ [string cat \
+ [string_to_regexp "Address not mapped to object."] \
+ ")?"] \
"${::hex} in func_segfault \\(\\) at \[^\r\n\]+:${::segv_line}" \
"${::decimal}\\s+\[^\r\n\]+Segfault here\[^\r\n\]+" \
"The program being debugged was signaled while in a function called from GDB\\." \
diff --git a/gdb/testsuite/gdb.base/inferior-died.exp b/gdb/testsuite/gdb.base/inferior-died.exp
index 3992561..764a88d 100644
--- a/gdb/testsuite/gdb.base/inferior-died.exp
+++ b/gdb/testsuite/gdb.base/inferior-died.exp
@@ -13,10 +13,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-# Until "set follow-fork-mode" and "catch fork" are implemented on
-# other targets...
-#
-require {istarget "*-*-linux*"}
+require allow_fork_tests
require support_displaced_stepping
diff --git a/gdb/testsuite/gdb.base/info-shared.exp b/gdb/testsuite/gdb.base/info-shared.exp
index 6f1b2d6..e81b28e 100644
--- a/gdb/testsuite/gdb.base/info-shared.exp
+++ b/gdb/testsuite/gdb.base/info-shared.exp
@@ -79,6 +79,9 @@ proc check_info_shared { test expect1 expect2 } {
}
}
+# Check that "info shared" before running doesn't crash.
+check_info_shared "info sharedlibrary before running" 0 0
+
# Start the inferior, and check neither of the libraries are loaded at
# the start.
if ![runto_main] {
diff --git a/gdb/testsuite/gdb.base/interrupt-daemon.exp b/gdb/testsuite/gdb.base/interrupt-daemon.exp
index 161f854..8b8c61d 100644
--- a/gdb/testsuite/gdb.base/interrupt-daemon.exp
+++ b/gdb/testsuite/gdb.base/interrupt-daemon.exp
@@ -16,6 +16,8 @@
# Make sure that we can interrupt an inferior that forks and moves to
# its own session.
+require allow_fork_tests
+
standard_testfile
if {[build_executable "failed to build" $testfile $srcfile {debug}]} {
diff --git a/gdb/testsuite/gdb.base/jit-elf-fork.exp b/gdb/testsuite/gdb.base/jit-elf-fork.exp
index 81d3350..c1fa428 100644
--- a/gdb/testsuite/gdb.base/jit-elf-fork.exp
+++ b/gdb/testsuite/gdb.base/jit-elf-fork.exp
@@ -15,6 +15,7 @@
# Test fork handling of an inferior that has JIT-ed objfiles.
+require allow_fork_tests
require allow_shlib_tests
load_lib jit-elf-helpers.exp
diff --git a/gdb/testsuite/gdb.base/kill-detach-inferiors-cmd.exp b/gdb/testsuite/gdb.base/kill-detach-inferiors-cmd.exp
index ef4bb88..57ec330 100644
--- a/gdb/testsuite/gdb.base/kill-detach-inferiors-cmd.exp
+++ b/gdb/testsuite/gdb.base/kill-detach-inferiors-cmd.exp
@@ -19,6 +19,7 @@
# commands.
require can_spawn_for_attach
+require allow_multi_inferior_tests
standard_testfile
set executable $testfile
diff --git a/gdb/testsuite/gdb.base/maint.exp b/gdb/testsuite/gdb.base/maint.exp
index 52282bc..7936e53 100644
--- a/gdb/testsuite/gdb.base/maint.exp
+++ b/gdb/testsuite/gdb.base/maint.exp
@@ -52,6 +52,40 @@ if {[prepare_for_testing "failed to prepare" $testfile \
return -1
}
+# Check "maint set per-command" warnings. We do this early so that
+# the following tests don't need to expect them, as GDB only warns
+# once.
+
+with_test_prefix "warnings" {
+ # Potential warning given by "maint set per-command time".
+ set maybe_per_command_warning \
+ "(?:warning: per-thread run time information not available on this platform)?"
+
+ # This one should not issue the "per-command time" warning.
+ with_test_prefix "per-command space" {
+ gdb_test_no_output "mt set per-command space on"
+ gdb_test_no_output "mt set per-command space off"
+ }
+
+ # These might warn. "per-command on" enables all sub commands, so
+ # might trigger the "per-command time" warning.
+ foreach cmd {"per-command" "per-command time"} {
+ with_test_prefix $cmd {
+ # GDB only warns once, so restart between commands.
+ clean_restart $binfile
+ gdb_test "mt set $cmd on" "$maybe_per_command_warning"
+ gdb_test "mt set $cmd off" "command started"
+ gdb_test_no_output "mt set $cmd on" \
+ "mt set $cmd on, again"
+ gdb_test "mt set $cmd off" "command started" \
+ "mt set $cmd off, again"
+ }
+ }
+
+ # We've already warned once above, so the following tests don't
+ # need to expect the warning.
+}
+
set readnow_p [readnow]
# The commands we test here produce many lines of output; disable "press
@@ -205,8 +239,8 @@ set re \
"( Number of \"partial\" symbols read: $decimal" \
")?( Number of psym tables \\(not yet expanded\\): $decimal" \
")?( Total memory used for psymbol cache: $decimal" \
- ")?( Number of read CUs: $decimal" \
- " Number of unread CUs: $decimal" \
+ ")?( Number of read units: $decimal" \
+ " Number of unread units: $decimal" \
")? Total memory used for objfile obstack: $decimal" \
" Total memory used for BFD obstack: $decimal" \
" Total memory used for string cache: $decimal" \
diff --git a/gdb/testsuite/gdb.base/multi-forks.exp b/gdb/testsuite/gdb.base/multi-forks.exp
index 61a240f..3facccb 100644
--- a/gdb/testsuite/gdb.base/multi-forks.exp
+++ b/gdb/testsuite/gdb.base/multi-forks.exp
@@ -13,11 +13,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-# Until "set follow-fork-mode" and "catch fork" are implemented on
-# other targets...
-#
-require {istarget "*-*-linux*"}
-
+require allow_fork_tests
standard_testfile .c
diff --git a/gdb/testsuite/gdb.base/options.exp b/gdb/testsuite/gdb.base/options.exp
index 7822e4a..a0947e2 100644
--- a/gdb/testsuite/gdb.base/options.exp
+++ b/gdb/testsuite/gdb.base/options.exp
@@ -508,12 +508,26 @@ proc_with_prefix test-thread-apply {} {
proc_with_prefix test-info-threads {} {
test_gdb_complete_multiple "info threads " "" "" {
"-gid"
+ "-running"
+ "-stopped"
"ID"
}
+ test_gdb_complete_multiple "info threads " "-" "" {
+ "-gid"
+ "-running"
+ "-stopped"
+ }
+
test_gdb_complete_unique \
- "info threads -" \
+ "info threads -g" \
"info threads -gid"
+ test_gdb_complete_unique \
+ "info threads -r" \
+ "info threads -running"
+ test_gdb_complete_unique \
+ "info threads -s" \
+ "info threads -stopped"
# "ID" isn't really something the user can type.
test_gdb_complete_none "info threads I"
diff --git a/gdb/testsuite/gdb.base/pie-fork.exp b/gdb/testsuite/gdb.base/pie-fork.exp
index 48c01d9..86407b4 100644
--- a/gdb/testsuite/gdb.base/pie-fork.exp
+++ b/gdb/testsuite/gdb.base/pie-fork.exp
@@ -16,6 +16,8 @@
# Test that we can follow forks properly when the executable is
# position-independent.
+require allow_fork_tests
+
standard_testfile
set opts [list debug pie]
diff --git a/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp b/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp
index 22913ca..eaee010 100644
--- a/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp
+++ b/gdb/testsuite/gdb.base/run-control-while-bg-execution.exp
@@ -49,6 +49,11 @@ if {[build_executable "failed to prepare" $testfile $srcfile]} {
# - run: use the run command
# - attach: start a process outside of GDB and attach it
proc do_test { action1 action2 } {
+
+ if {$action1 == "add" && ![allow_multi_inferior_tests]} {
+ return
+ }
+
save_vars { ::GDBFLAGS } {
append ::GDBFLAGS " -ex \"maintenance set target-non-stop on\""
clean_restart $::binfile
diff --git a/gdb/testsuite/gdb.base/sigall.exp b/gdb/testsuite/gdb.base/sigall.exp
index b23e3c5..461a92b 100644
--- a/gdb/testsuite/gdb.base/sigall.exp
+++ b/gdb/testsuite/gdb.base/sigall.exp
@@ -41,13 +41,14 @@ proc test_one_sig {nextsig} {
setup_xfail "i*86-pc-linuxoldld-gnu" "i*86-pc-linuxaout-gnu"
}
# On Linux SPARC64 systems SIGLOST==SIGPWR and gdb identifies
- # the raised signal as PWR.
- if {$thissig == "LOST" && [istarget "sparc64-*-linux*"]} {
+ # the raised signal as PWR. Same for Cygwin.
+ if {$thissig == "LOST"
+ && ([istarget "sparc64-*-linux*"] || [istarget "*-*-cygwin*"])} {
set esig "PWR"
}
gdb_test "continue" \
- "Continuing.*Program received signal SIG$esig.*" \
+ "Continuing.* received signal SIG$esig.*" \
"get signal $esig"
}
@@ -177,7 +178,7 @@ gdb_test "handle SIGTERM stop print" \
"SIGTERM\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Yes.*"
gdb_test "b handle_TERM" "Breakpoint \[0-9\]+ .*"
gdb_test "continue" \
- "Continuing.*Program received signal SIGTERM.*" \
+ "Continuing.* received signal SIGTERM.*" \
"get signal TERM"
gdb_test "continue" "Breakpoint.*handle_TERM.*" "send signal TERM"
gdb_continue_to_end "continue to sigall exit"
diff --git a/gdb/testsuite/gdb.base/step-over-exit.exp b/gdb/testsuite/gdb.base/step-over-exit.exp
index 2370f97..6dfa7bb 100644
--- a/gdb/testsuite/gdb.base/step-over-exit.exp
+++ b/gdb/testsuite/gdb.base/step-over-exit.exp
@@ -13,11 +13,14 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-standard_testfile
-
# Test a thread is doing step-over a syscall instruction which is exit,
# and GDBserver should cleanup its state of step-over properly.
+# The testcase relies on follow-fork-mode child.
+require allow_fork_tests
+
+standard_testfile
+
set syscall_insn ""
# Define the syscall instruction for each target.
diff --git a/gdb/testsuite/gdb.base/style.exp b/gdb/testsuite/gdb.base/style.exp
index c10be3b..503671b 100644
--- a/gdb/testsuite/gdb.base/style.exp
+++ b/gdb/testsuite/gdb.base/style.exp
@@ -751,6 +751,280 @@ proc test_enable_styling_warning { } {
}
}
+# Run an 'apropos' command. Each line of output starts with a
+# non-default style (command style). Ensure that pagination triggers
+# during the 'apropos' output such that, at the point pagination kicks
+# in, a non-default style is in effect.
+#
+# Then, at the pagination prompt, quit the command.
+#
+# Next, run a command which switches to a different style, and then
+# back to the current style.
+#
+# At one point, a bug in the pagination code would leave the
+# non-default style from the 'apropos' command recorded as the current
+# style, such that the second command would switch back to the earlier
+# style.
+proc test_pagination_cmd_after_quit_styling {} {
+ with_ansi_styling_terminal {
+ clean_restart
+ }
+
+ # We're going to use 'apropos time'. Check that with a height of
+ # 12 lines, each line starts with a non-default style, and that we
+ # do see the pagination prompt. This means that there are more
+ # than 12 lines for this command.
+ with_test_prefix "validate apropos output" {
+ gdb_test_no_output "set height 12"
+
+ set saw_pagination_prompt false
+ gdb_test_multiple "apropos time" "" {
+ -re "^apropos time\r\n" {
+ exp_continue
+ }
+ -re "^\033\\\[39;49;1;27m\[^\r\n\]+\r\n" {
+ exp_continue
+ }
+ -re "^$::pagination_prompt$" {
+ set saw_pagination_prompt true
+ send_gdb "q\n"
+ exp_continue
+ }
+ -re "^q\r\n" {
+ exp_continue
+ }
+ -re "^Quit\r\n" {
+ exp_continue
+ }
+ -re "^$::gdb_prompt $" {
+ gdb_assert { $saw_pagination_prompt } $gdb_test_name
+ }
+ -re "^\[^\r\n\]+\r\n" {
+ exp_continue
+ }
+ }
+ }
+
+ # Now reduce the height to 10 and re-run 'apropos time'. Based on
+ # the previous check, we know that this is going to present the
+ # pagination prompt when a non-default style is in use.
+ gdb_test_no_output "set height 10"
+
+ set saw_pagination_prompt false
+ gdb_test_multiple "apropos time" "" {
+ -re "$::pagination_prompt" {
+ set saw_pagination_prompt true
+ send_gdb "q\n"
+ exp_continue
+ }
+ -re "\r\n$::gdb_prompt $" {
+ gdb_assert { $saw_pagination_prompt } $gdb_test_name
+ }
+ }
+
+ # The help output for this maintenance command switches to a
+ # different style, and then back to the default. If the
+ # pagination bug still exists, then this would switch back to the
+ # non-default style that was in use when pagination kicked in
+ # above.
+ gdb_test "maintenance time" \
+ "^\"\033\\\[39;49;1;27mmaintenance time\033\\\[m\" takes a numeric argument\\."
+}
+
+# Helper for test_pagination_prompt_styling. Return false if STR, a
+# line that appears immediately before a pagination prompt, matches
+# the pattern for needing a style reset at the end, but does not have
+# the style reset.
+#
+# In all other cases, return true. So lines that don't match the
+# known pattern for neededing a style reset will always return true,
+# as will lines that match the pattern, and do have the style reset.
+proc previous_line_is_ok { str } {
+
+ # Create a copy of STR with all the '\033' characters removed.
+ # Then compare string lengths to get a count of the '\033'
+ # charactes present in STR.
+ regsub -all "\033" $str {} stripped
+ set count [expr [string length $str] - [string length $stripped]]
+
+ # If STR switched styles, then it _must_ switch back again,
+ # otherwise the pagination prompt will be in the wrong style.
+ # This means that there _must_ be an even number of '\033'
+ # characters in STR. If there is not then we switched style, but
+ # failed to switch back.
+ if { [expr $count % 2] != 0 } {
+ return false
+ }
+
+ # For lines that don't match this pattern, we cannot comment on
+ # where the style reset should occur, so lets just claim the line
+ # is fine.
+ if { ![regexp "\\s+$::hex - $::hex is \[^\r\n\]+ in " $str] } {
+ return true
+ }
+
+ # This line did match the above pattern, so we know that a style
+ # reset _must_ occur at the end of the line. If it doesn't then
+ # this line is not OK.
+ if { ![regexp "\033\\\[m$" $str] } {
+ return false
+ }
+
+ # All tests passed, this line looks OK.
+ return true
+}
+
+# Test that the pagination prompt is displayed unstyled. This is done
+# by looking at the 'info files' output and selecting a width that
+# will mean we should get a pagination prompt part way through a
+# styled filename.
+#
+# Then, re-run 'info files' and check that for every pagination
+# prompt, the previous line disables styling as expected.
+proc test_pagination_prompt_styling {} {
+ with_ansi_styling_terminal {
+ clean_restart $::binfile
+ }
+
+ if {![runto_main]} {
+ return
+ }
+
+ # Set height so we actually get a pagination prompt.
+ gdb_test_no_output "set height 3"
+
+ # Scan the 'info files' output and set DESIRED_WIDTH such that it
+ # will trigger pagination part-way through a styled filename.
+ set desired_width 0
+ gdb_test_multiple "info files" "find good test width" {
+ -re "^info files\r\n" {
+ exp_continue
+ }
+
+ -re "^$::pagination_prompt$" {
+ send_gdb "\n"
+ exp_continue
+ }
+
+ -re "^$::gdb_prompt $" {
+ }
+
+ -re "^((\\s+$::hex - $::hex is \[^\r\n\]+ in )\[^\r\n\]+)\r\n" {
+ if { $desired_width == 0 } {
+ set full_line $expect_out(1,string)
+ set inner_line $expect_out(2,string)
+ set desired_width [expr [string length $inner_line] + ([string length $full_line] - [string length $inner_line]) / 2]
+ }
+ exp_continue
+ }
+
+ -re "^\[^\r\n\]*\r\n" {
+ exp_continue
+ }
+ }
+
+ # Now setup the screen width.
+ gdb_test_no_output "set width $desired_width"
+
+ # Re-run 'info files'. Check that the content before any
+ # pagination prompt correctly disables styling.
+ set saw_bad_line false
+ set prev_line ""
+ gdb_test_multiple "info files" "check pagination prompt styling" {
+ -re "^info files\r\n" {
+ exp_continue
+ }
+
+ -re "^$::pagination_prompt$" {
+ if { ![previous_line_is_ok $prev_line] } {
+ set saw_bad_line true
+ }
+ send_gdb "\n"
+ exp_continue
+ }
+
+ -re "^(\[^\r\n\]+)$::pagination_prompt$" {
+ set prev_line $expect_out(1,string)
+ if { ![previous_line_is_ok $prev_line] } {
+ set saw_bad_line true
+ }
+ send_gdb "\n"
+ exp_continue
+ }
+
+ -re "^$::gdb_prompt $" {
+ gdb_assert { !$saw_bad_line } $gdb_test_name
+ }
+
+ -re "^(\[^\r\n\]*)\r\n" {
+ set prev_line $expect_out(1,string)
+ exp_continue
+ }
+ }
+}
+
+# Test that GDB can correctly restore the current style after a
+# pagination prompt.
+#
+# Set the logging file to a garbage string based on LENGTH (is
+# actually 2x LENGTH), then 'show logging file'. Press return at the
+# pagination prompt, and check that the reset of the filename is
+# styled correctly, and that GDB correctly switches back to the
+# default style once the logging file has finished.
+proc test_pagination_continue_styling_1 { length } {
+ with_ansi_styling_terminal {
+ clean_restart $::binfile
+ }
+
+ set filename [string repeat "ax" $length]
+
+ gdb_test_no_output "set logging file $filename"
+
+ gdb_test_no_output "set height 3"
+ gdb_test_no_output "set width 80"
+
+ set saw_bad_styling false
+ gdb_test_multiple "show logging file" "" {
+ -re "^show logging file\r\n" {
+ exp_continue
+ }
+
+ -re "^The current logfile is \"\033\\\[32;49;22;27m(?:ax)+\033\\\[m" {
+ exp_continue
+ }
+
+ -re "^\r\n\033\\\[32;49;22;27m(?:ax)+\033\\\[m(?=--)" {
+ exp_continue
+ }
+
+ -re "^\r\n\033\\\[32;49;22;27m(?:ax)+(?=--)" {
+ set saw_bad_styling true
+ exp_continue
+ }
+
+ -re "^\r\n\033\\\[32;49;22;27m(?:ax)+\033\\\[m\"\\.\r\n" {
+ exp_continue
+ }
+
+ -re "^$::gdb_prompt $" {
+ gdb_assert { !$saw_bad_styling } $gdb_test_name
+ }
+
+ -re "^$::pagination_prompt$$" {
+ send_gdb "\n"
+ exp_continue
+ }
+ }
+}
+
+# Wrapper around test_pagination_continue_styling_1, calls that
+# function with different lengths.
+proc test_pagination_continue_styling { } {
+ foreach_with_prefix length { 80 160 } {
+ test_pagination_continue_styling_1 $length
+ }
+}
+
# Check to see if the Python styling of disassembler output is
# expected or not, this styling requires Python support in GDB, and
# the Python pygments module to be available.
@@ -793,3 +1067,6 @@ test_colorsupport_truecolor
test_colorsupport_truecolor_only
test_enable_styling_warning
+test_pagination_cmd_after_quit_styling
+test_pagination_prompt_styling
+test_pagination_continue_styling
diff --git a/gdb/testsuite/gdb.base/user-namespace-attach.c b/gdb/testsuite/gdb.base/user-namespace-attach.c
new file mode 100644
index 0000000..684ce1c
--- /dev/null
+++ b/gdb/testsuite/gdb.base/user-namespace-attach.c
@@ -0,0 +1,35 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2025 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 <http://www.gnu.org/licenses/>. */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+
+volatile int spin_p = 1;
+
+int
+main ()
+{
+ alarm (60);
+
+ printf ("pid = %lld\n", ((long long) getpid ()));
+
+ while (spin_p)
+ sleep (1);
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/user-namespace-attach.exp b/gdb/testsuite/gdb.base/user-namespace-attach.exp
new file mode 100644
index 0000000..741093c
--- /dev/null
+++ b/gdb/testsuite/gdb.base/user-namespace-attach.exp
@@ -0,0 +1,148 @@
+# Copyright 2025 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 <http://www.gnu.org/licenses/>.
+
+# Check that GDB can attach to a process started using 'unshare'. The
+# inferior is started in a separate mnt namespace.
+
+require can_spawn_for_attach
+
+standard_testfile
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile] == -1} {
+ return
+}
+
+# This test relies (at least in some parts) on the sysroot being
+# 'target:'. Grab the current sysroot now so we can skip those tests
+# if the board file has changed the sysroot.
+set sysroot ""
+set test "show sysroot"
+gdb_test_multiple $test $test {
+ -re -wrap "The current system root is \"(.*)\"\\." {
+ set sysroot $expect_out(1,string)
+ }
+}
+
+# Start a process using 'unshare FLAGS', then attach to the process
+# from GDB. Check that the attach worked as expected.
+proc run_test { flags } {
+
+ # If FLAGS contains '--mount' then a separate mnt namespace will
+ # be created, in which case the executable will have been read
+ # from the 'target:'. Otherwise, the executable will have been
+ # read from the local filesystem, and there will be no prefix.
+ #
+ # Of course, this only applies if the sysroot is 'target:', some
+ # boards change this, so skip these tests on those boards.
+ if { [lsearch -exact [split $flags " "] "--mount"] != -1 } {
+ if { $::sysroot ne "target:" } {
+ return
+ }
+
+ set prefix "target:"
+ } else {
+ set prefix ""
+ }
+
+ set unshare_cmd "unshare $flags"
+
+ # Run '/bin/true' using UNSHARE_CMD. If the flags in UNSHARE_CMD
+ # aren't supported then this will fail, this means we shouldn't
+ # spawn the command with our test executable and try attaching.
+ #
+ # This will also fail if /bin/true isn't present, or doesn't work
+ # as we expect. But this should be fine for many targets.
+ set res [remote_exec target "$unshare_cmd /bin/true"]
+ if { [lindex $res 0] != 0 } {
+ unsupported "unshare flags not supported"
+ return
+ }
+
+ set inferior_spawn_id \
+ [spawn_wait_for_attach [list "$unshare_cmd $::binfile"]]
+ if { $inferior_spawn_id == -1 } {
+ unsupported "failed to spawn for attach"
+ return
+ }
+
+ set inferior_pid [spawn_id_get_pid $inferior_spawn_id]
+
+ clean_restart
+
+ set saw_bad_warning false
+ gdb_test_multiple "attach $inferior_pid" "attach to inferior" {
+ -re "^attach $::decimal\r\n" {
+ exp_continue
+ }
+
+ -re "^warning: \[^\r\n\]+: could not open as an executable file: \[^\r\n\]+\r\n" {
+ set saw_bad_warning true
+ exp_continue
+ }
+
+ -re "^warning: \[^\r\n\]+: can't open to read symbols: \[^\r\n\]+\r\n" {
+ set saw_bad_warning true
+ exp_continue
+ }
+
+ -re "^warning: Could not load vsyscall page because no executable was specified\r\n" {
+ # This warning is a secondary consequence of the above bad
+ # warnings, so don't count this as a bad warnings, ignore
+ # it instead.
+ exp_continue
+ }
+
+ -re "^warning:\\s+$::decimal\\s*\[^\r\n\]+: No such file or directory\r\n" {
+ # This unrelated warning is seen when GDB stops in libc,
+ # and the source code for libc is not available.
+ exp_continue
+ }
+
+ -re "^warning: \[^\r\n\]+\r\n" {
+ # If we ignore "other" warnings then, should the above
+ # warnings strings change we'll start ignoring the bad
+ # warnings, and the test will appear to pass.
+ #
+ # If you are seeing a warning here that really has nothing
+ # to do with the test failing, then the correct solution
+ # is to add a new regexp to specifically match _that_
+ # warning, and ignore it.
+ set saw_bad_warning true
+ exp_continue
+ }
+
+ -re "^$::gdb_prompt $" {
+ gdb_assert { !$saw_bad_warning } $gdb_test_name
+ }
+
+ -re "^\[^\r\n\]*\r\n" {
+ exp_continue
+ }
+ }
+
+ # Ensure GDB could access the executable.
+ set binfile_re [string_to_regexp $::binfile]
+ gdb_test "info inferiors" \
+ "\r\n\\*\\s+$::decimal\\s+\[^\r\n\]+\\s+${prefix}${binfile_re}\\s*"
+}
+
+set test_flags [list \
+ "--mount --map-root-user" \
+ "--user" \
+ "--user --map-root-user"]
+
+foreach_with_prefix flags $test_flags {
+ run_test $flags
+}
diff --git a/gdb/testsuite/gdb.base/vfork-follow-parent.exp b/gdb/testsuite/gdb.base/vfork-follow-parent.exp
index fca2993..8cb785d 100644
--- a/gdb/testsuite/gdb.base/vfork-follow-parent.exp
+++ b/gdb/testsuite/gdb.base/vfork-follow-parent.exp
@@ -19,6 +19,8 @@
# schedule-multiple on" or "set detach-on-fork on". Test these two resolution
# methods.
+require allow_fork_tests
+
standard_testfile .c vforked-prog.c
set binfile ${testfile}-exit
diff --git a/gdb/testsuite/gdb.base/watch-before-fork.exp b/gdb/testsuite/gdb.base/watch-before-fork.exp
index 074cfbd..509561e 100644
--- a/gdb/testsuite/gdb.base/watch-before-fork.exp
+++ b/gdb/testsuite/gdb.base/watch-before-fork.exp
@@ -20,6 +20,8 @@
# This test uses "awatch".
require allow_hw_watchpoint_access_tests
+require allow_fork_tests
+
standard_testfile
if {[build_executable "failed to prepare" $testfile $srcfile debug]} {
diff --git a/gdb/testsuite/gdb.base/watch-vfork.exp b/gdb/testsuite/gdb.base/watch-vfork.exp
index 1bc61bc..503727d 100644
--- a/gdb/testsuite/gdb.base/watch-vfork.exp
+++ b/gdb/testsuite/gdb.base/watch-vfork.exp
@@ -17,6 +17,8 @@
standard_testfile .c
+require allow_fork_tests
+
if { [build_executable ${testfile}.exp ${testfile} $srcfile {debug}] } {
untested "failed to compile"
return -1
diff --git a/gdb/testsuite/gdb.base/watchpoint-hw-attach.exp b/gdb/testsuite/gdb.base/watchpoint-hw-attach.exp
index b3892f3..fa63edb 100644
--- a/gdb/testsuite/gdb.base/watchpoint-hw-attach.exp
+++ b/gdb/testsuite/gdb.base/watchpoint-hw-attach.exp
@@ -26,29 +26,18 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} {
return -1
}
-if ![runto_main] {
- return -1
-}
+set test_spawn_id [spawn_wait_for_attach $binfile]
+set testpid [spawn_id_get_pid $test_spawn_id]
-# Run to the point where mypid in the test program has been
-# populated.
-gdb_breakpoint [gdb_get_line_number "pidacquired"]
-gdb_continue_to_breakpoint "pidacquired"
-
-# Get the PID of the test process.
-set testpid [get_integer_valueof "mypid" 0]
+gdb_test "attach $testpid" "Attaching to program: .*, process $testpid.*" "attach once"
gdb_test "detach" "Detaching from program: .*, process $testpid\r\n\\\[Inferior $decimal \\(process $testpid\\) detached\\\]"
-if {$testpid == ""} {
- return -1
-}
-
# A clean restart is needed to force the hardware watchpoint setup
# logic to run post attach rather than post inferior launch.
clean_restart $binfile
-gdb_test "attach $testpid" "Attaching to program: .*, process $testpid.*" "attach"
+gdb_test "attach $testpid" "Attaching to program: .*, process $testpid.*" "attach twice"
# Ensure the test program is in the top frame so the required
# variables are in scope.
@@ -62,3 +51,5 @@ gdb_test "watch watched_variable" \
gdb_test "continue" \
"continue.*Continuing.*\.Hardware watchpoint $decimal: watched_variable.*Old value = 0.*New value = 4.*watched_variable\\);"
+
+kill_wait_spawned_process $test_spawn_id
diff --git a/gdb/testsuite/gdb.btrace/multi-inferior.exp b/gdb/testsuite/gdb.btrace/multi-inferior.exp
index ed2acb2..d87a941 100644
--- a/gdb/testsuite/gdb.btrace/multi-inferior.exp
+++ b/gdb/testsuite/gdb.btrace/multi-inferior.exp
@@ -24,6 +24,8 @@
require allow_btrace_tests
+require allow_multi_inferior_tests
+
require !use_gdb_stub
standard_testfile
diff --git a/gdb/testsuite/gdb.cp/chained-calls.cc b/gdb/testsuite/gdb.cp/chained-calls.cc
index 9d12c98..9358c71 100644
--- a/gdb/testsuite/gdb.cp/chained-calls.cc
+++ b/gdb/testsuite/gdb.cp/chained-calls.cc
@@ -23,6 +23,8 @@ public:
S operator+ (const S &s);
+ int get ();
+
int a;
};
@@ -41,6 +43,12 @@ S::operator+ (const S &s)
return res;
}
+int
+S::get ()
+{
+ return a;
+}
+
S
f (int i)
{
@@ -162,6 +170,8 @@ public:
U (type t);
type get_type ();
+ int get ();
+
int a;
char c;
type tp[2];
@@ -191,6 +201,12 @@ U::get_type ()
}
int
+U::get ()
+{
+ return a;
+}
+
+int
main ()
{
int i = g(f(0));
@@ -198,6 +214,7 @@ main ()
B b = makeb ();
C c;
+ int z = f (42).get ();
return i + getb(b, 0); /* Break here */
}
diff --git a/gdb/testsuite/gdb.cp/chained-calls.exp b/gdb/testsuite/gdb.cp/chained-calls.exp
index 4f0597a..d34162c 100644
--- a/gdb/testsuite/gdb.cp/chained-calls.exp
+++ b/gdb/testsuite/gdb.cp/chained-calls.exp
@@ -42,3 +42,6 @@ gdb_test "p *c" ".* = {a = 5678}" "*c"
gdb_test "p *c + *c" ".* = {a = 11356}" "*c + *c"
gdb_test "p q(*c + *c)" ".* = {a = 11356}" "q(*c + *c)"
gdb_test "p make_int().get_type ()" ".* = INT" "make_int().get_type ()"
+gdb_test "p f(42).get()" " = 42" "f().get()"
+gdb_test "ptype f(42).get()" "type = int" "ptype f().get()"
+gdb_test "ptype make_int().get()" "type = int" "make_int().get()"
diff --git a/gdb/testsuite/gdb.cp/cpexprs.exp.tcl b/gdb/testsuite/gdb.cp/cpexprs.exp.tcl
index 1ac35af..5c3dfd6 100644
--- a/gdb/testsuite/gdb.cp/cpexprs.exp.tcl
+++ b/gdb/testsuite/gdb.cp/cpexprs.exp.tcl
@@ -28,17 +28,33 @@ proc test_breakpoint {func} {
delete_breakpoints
if { ! [gdb_breakpoint test_function] } {
fail "set test_function breakpoint for $func"
- } elseif { [gdb_test "continue" \
- "Continuing.\r\n\r\nBreakpoint $DEC+,.*test_function.*" \
- "continue to test_function for $func"] != 0 } {
- } else {
- gdb_breakpoint "$func"
- set i [expr {[string last : $func] + 1}]
- set efunc [string_to_regexp [string range $func $i end]]
- gdb_test "continue" \
- "Continuing.\r\n\r\nBreakpoint $DEC+,.*$efunc.*" \
- "continue to $func"
+ return
+ }
+
+ # Accept any input between "Continuing" and the breakpoint hit, as
+ # on Cygwin, we may see a "New Thread" notification. This is the
+ # Cygwin runtime spawning its own internal threads.
+ if { [gdb_test "continue" \
+ "Continuing.\r\n.*Breakpoint $DEC+,.*test_function.*" \
+ "continue to test_function for $func"] != 0 } {
+ return
}
+
+ # On some systems, the in-charge and not-in-charge dtors of a
+ # class may end up with the same address, so setting a breakpoint
+ # at a dtor like base::~base only finds one location. On other
+ # systems (e.g. Cygwin), the two dtors for the same class may have
+ # different addresses, so we find two locations for the
+ # breakpoint. Thus, expect that the breakpoint hit may or may not
+ # report a location number.
+ set bp_re "$DEC+(\.$DEC+)?"
+
+ gdb_breakpoint "$func"
+ set i [expr {[string last : $func] + 1}]
+ set efunc [string_to_regexp [string range $func $i end]]
+ gdb_test "continue" \
+ "Continuing.\r\n.*Breakpoint $bp_re,.*$efunc.*" \
+ "continue to $func"
}
# Add a function to the list of tested functions
diff --git a/gdb/testsuite/gdb.dap/attach.exp b/gdb/testsuite/gdb.dap/attach.exp
index 37e867c..5e1f634 100644
--- a/gdb/testsuite/gdb.dap/attach.exp
+++ b/gdb/testsuite/gdb.dap/attach.exp
@@ -33,11 +33,11 @@ set attach_id [dap_attach $testpid $binfile]
dap_check_request_and_response "configurationDone" configurationDone
+dap_check_response "attach response" attach $attach_id
+
dap_wait_for_event_and_check "stopped" stopped \
"body reason" attach
-dap_check_response "attach response" attach $attach_id
-
dap_shutdown true
kill_wait_spawned_process $test_spawn_id
diff --git a/gdb/testsuite/gdb.dap/log-message.exp b/gdb/testsuite/gdb.dap/log-message.exp
index 421df14..cce367d 100644
--- a/gdb/testsuite/gdb.dap/log-message.exp
+++ b/gdb/testsuite/gdb.dap/log-message.exp
@@ -40,6 +40,15 @@ set obj [dap_check_request_and_response "set breakpoint" \
[list s $srcfile] $line]]
set fn_bpno [dap_get_breakpoint_number $obj]
+set eol {\n}
+dap_wait_for_event_and_check "set breakpoint output, part 1" output \
+ {body category} stdout \
+ {body output} "No source file named log-message.c.$eol"
+
+dap_wait_for_event_and_check "set breakpoint output, part 2" output \
+ {body category} stdout \
+ {body output} "Breakpoint 1 (-source log-message.c -line $line) pending.$eol"
+
dap_check_request_and_response "configurationDone" configurationDone
dap_check_response "launch response" launch $launch_id
diff --git a/gdb/testsuite/gdb.dap/threads.c b/gdb/testsuite/gdb.dap/threads.c
new file mode 100644
index 0000000..168f044
--- /dev/null
+++ b/gdb/testsuite/gdb.dap/threads.c
@@ -0,0 +1,67 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2019-2025 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 <http://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+#define NUM 2
+
+static pthread_barrier_t threads_started_barrier;
+
+static void *
+thread_function (void *arg)
+{
+ pthread_barrier_wait (&threads_started_barrier);
+
+ while (1)
+ sleep (1);
+
+ pthread_exit (NULL);
+}
+
+static void
+all_started (void)
+{
+}
+
+int
+main ()
+{
+ pthread_t threads[NUM];
+ long i;
+
+ pthread_barrier_init (&threads_started_barrier, NULL, NUM + 1);
+
+ for (i = 1; i <= NUM; i++)
+ {
+ int res;
+
+ res = pthread_create (&threads[i - 1], NULL, thread_function, NULL);
+ }
+
+ pthread_barrier_wait (&threads_started_barrier);
+
+ all_started ();
+
+ printf ("sleeping\n");
+ fflush (stdout);
+ sleep (180);
+
+ exit (EXIT_SUCCESS);
+}
diff --git a/gdb/testsuite/gdb.dap/threads.exp b/gdb/testsuite/gdb.dap/threads.exp
new file mode 100644
index 0000000..c91d107
--- /dev/null
+++ b/gdb/testsuite/gdb.dap/threads.exp
@@ -0,0 +1,81 @@
+# Copyright 2025 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 <http://www.gnu.org/licenses/>.
+
+# Test DAP "threads" request.
+
+require allow_shlib_tests allow_dap_tests
+
+load_lib dap-support.exp
+
+standard_testfile
+
+set libname $testfile-solib
+set srcfile_lib $srcdir/$subdir/$libname.c
+set binfile_lib [standard_output_file $libname.so]
+
+if {[build_executable "failed to prepare" $testfile $srcfile \
+ {debug pthreads}] == -1} {
+ return
+}
+
+if {[dap_initialize] == ""} {
+ return
+}
+
+set launch_id [dap_launch $testfile]
+
+set obj [dap_check_request_and_response "set breakpoint on all_started function" \
+ setFunctionBreakpoints \
+ {o breakpoints [a [o name [s all_started]]]}]
+set fn_bpno [dap_get_breakpoint_number $obj]
+
+dap_check_request_and_response "configurationDone" configurationDone
+
+dap_check_response "launch response" launch $launch_id
+
+lassign [dap_wait_for_event_and_check "stopped at function breakpoint" \
+ stopped \
+ "body reason" breakpoint \
+ "body hitBreakpointIds" $fn_bpno] \
+ ignore \
+ all_events
+
+# Verify that we saw the correct number of thread events.
+set count 0
+foreach event $all_events {
+ if {[dict get $event type] == "event"
+ && [dict get $event event] == "thread"
+ && [dict get $event body reason] == "started"} {
+ incr count
+ }
+}
+gdb_assert {$count == 3} "correct number of thread events"
+
+dap_check_request_and_response "continue" continue \
+ {o threadId [i 1]}
+
+# Make sure that the inferior has really re-started -- note that there
+# is no "continue" event, because the "continue" request suppresses
+# those.
+dap_wait_for_event_and_check "output from inferior" output \
+ {body output} "sleeping\\n"
+
+lassign [dap_check_request_and_response "threads request" threads] \
+ response ignore
+
+gdb_assert {[llength [dict get $response body threads]] == 3} \
+ "correct number of threads"
+
+dap_shutdown true
diff --git a/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp b/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp
index 93f8f92..35bb401 100644
--- a/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp
+++ b/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp
@@ -46,7 +46,7 @@ set build_id_debug_file \
[standard_output_file [build_id_debug_filename_get $binfile]]
# Get the BINFILE.debug filename. This is the file we should be
-# moving to the BUILD_ID_DEBUG_FILE location, but we wont, we're going
+# moving to the BUILD_ID_DEBUG_FILE location, but we won't, we're going
# to move something else there instead.
set debugfile [standard_output_file "${binfile}.debug"]
diff --git a/gdb/testsuite/gdb.debuginfod/corefile-mapped-file.exp b/gdb/testsuite/gdb.debuginfod/corefile-mapped-file.exp
index 78fa252..dac4e6c 100644
--- a/gdb/testsuite/gdb.debuginfod/corefile-mapped-file.exp
+++ b/gdb/testsuite/gdb.debuginfod/corefile-mapped-file.exp
@@ -49,7 +49,7 @@
#
# 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
+# is mmapped 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
@@ -260,7 +260,7 @@ proc load_core_file { testname { line_re "" } } {
# 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"
+ perror "unexpected return value, code = $res, value = $string"
return -1
}
}
diff --git a/gdb/testsuite/gdb.debuginfod/solib-with-soname.exp b/gdb/testsuite/gdb.debuginfod/solib-with-soname.exp
index 9f1842c..1008e46 100644
--- a/gdb/testsuite/gdb.debuginfod/solib-with-soname.exp
+++ b/gdb/testsuite/gdb.debuginfod/solib-with-soname.exp
@@ -89,7 +89,7 @@ if {[lindex $status 0] != 0} {
}
# Build the executable. This links against libfoo.so, which is
-# poining at libfoo_1.so. Just to confuse things even more, this
+# pointing 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 } {
diff --git a/gdb/testsuite/gdb.dwarf2/ada-array-bound.c b/gdb/testsuite/gdb.dwarf2/ada-array-bound.c
new file mode 100644
index 0000000..5a7d397
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/ada-array-bound.c
@@ -0,0 +1,29 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2025 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 <http://www.gnu.org/licenses/>. */
+
+/* The data used for the structure. */
+
+unsigned char our_data[] = { 3, 7, 11, 13 };
+
+/* Dummy main function. */
+
+int
+main()
+{
+ asm ("main_label: .globl main_label");
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.dwarf2/ada-array-bound.exp b/gdb/testsuite/gdb.dwarf2/ada-array-bound.exp
new file mode 100644
index 0000000..f48df7b
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/ada-array-bound.exp
@@ -0,0 +1,89 @@
+# Copyright 2025 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 <http://www.gnu.org/licenses/>.
+
+# Test handling of an array type whose bound comes from the field of a
+# structure.
+
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+require dwarf2_support
+
+standard_testfile .c -debug.S
+
+# Set up the DWARF for the test.
+
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+ global srcdir subdir srcfile
+
+ cu {} {
+ DW_TAG_compile_unit {
+ {DW_AT_language @DW_LANG_Ada95}
+ {DW_AT_name $srcfile}
+ } {
+ declare_labels byte array disc struct
+
+ byte: DW_TAG_base_type {
+ {DW_AT_byte_size 1 DW_FORM_sdata}
+ {DW_AT_encoding @DW_ATE_unsigned}
+ {DW_AT_name byte}
+ }
+
+ array: DW_TAG_array_type {
+ {DW_AT_name array_type}
+ {DW_AT_type :$byte}
+ } {
+ DW_TAG_subrange_type {
+ {DW_AT_type :$byte}
+ {DW_AT_upper_bound :$disc}
+ }
+ }
+
+ struct: DW_TAG_structure_type {
+ {DW_AT_name discriminated}
+ {DW_AT_byte_size 4 DW_FORM_sdata}
+ } {
+ disc: DW_TAG_member {
+ {DW_AT_name disc}
+ {DW_AT_type :$byte}
+ {DW_AT_data_member_location 0 DW_FORM_sdata}
+ }
+ DW_TAG_member {
+ {DW_AT_name nums}
+ {DW_AT_type :$array}
+ {DW_AT_data_member_location 1 DW_FORM_sdata}
+ }
+ }
+
+ DW_TAG_variable {
+ {DW_AT_name "value"}
+ {DW_AT_type :$struct}
+ {DW_AT_external 1 DW_FORM_flag}
+ {DW_AT_location {DW_OP_addr [gdb_target_symbol "our_data"]}
+ SPECIAL_expr}
+ }
+ }
+ }
+}
+
+if { [prepare_for_testing "failed to prepare" ${testfile} \
+ [list $srcfile $asm_file] {nodebug}] } {
+ return -1
+}
+
+gdb_test_no_output "set language ada"
+gdb_test "print value" \
+ [string_to_regexp " = (disc => 3, nums => (7, 11, 13))"]
diff --git a/gdb/testsuite/gdb.dwarf2/dw-form-strx-out-of-bounds.exp b/gdb/testsuite/gdb.dwarf2/dw-form-strx-out-of-bounds.exp
index f2123fa..cb24b19 100644
--- a/gdb/testsuite/gdb.dwarf2/dw-form-strx-out-of-bounds.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw-form-strx-out-of-bounds.exp
@@ -18,7 +18,13 @@
# Out of bounds index.
set int_str_idx 1
+# With readnow, the dwarf error is printed during the file command, so skip
+# the test.
+require !readnow
+
+set prepare_for_testing_done 0
source $srcdir/$subdir/dw-form-strx.exp.tcl
+require {expr $prepare_for_testing_done == 1}
set re_dwarf_error \
[string_list_to_regexp \
diff --git a/gdb/testsuite/gdb.dwarf2/dw-form-strx.exp b/gdb/testsuite/gdb.dwarf2/dw-form-strx.exp
index 9b62edf..3f739c4 100644
--- a/gdb/testsuite/gdb.dwarf2/dw-form-strx.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw-form-strx.exp
@@ -18,6 +18,8 @@
# Correct index.
set int_str_idx 0
+set prepare_for_testing_done 0
source $srcdir/$subdir/dw-form-strx.exp.tcl
+require {expr $prepare_for_testing_done == 1}
gdb_test "ptype global_var" "type = int"
diff --git a/gdb/testsuite/gdb.dwarf2/dw-form-strx.exp.tcl b/gdb/testsuite/gdb.dwarf2/dw-form-strx.exp.tcl
index 15cfe27..bc5a654 100644
--- a/gdb/testsuite/gdb.dwarf2/dw-form-strx.exp.tcl
+++ b/gdb/testsuite/gdb.dwarf2/dw-form-strx.exp.tcl
@@ -24,15 +24,15 @@ set asm_file [standard_output_file $srcfile2]
# Debug info in the main file.
Dwarf::assemble $asm_file {
- declare_labels base_offset
+ declare_labels base_offset_cu1
- debug_str_offsets base_offset int
+ debug_str_offsets { base_offset base_offset_cu1 } int
cu {
version 5
} {
DW_TAG_compile_unit {
- {DW_AT_str_offsets_base $base_offset sec_offset}
+ {DW_AT_str_offsets_base $base_offset_cu1 sec_offset}
} {
declare_labels int4_type
@@ -56,5 +56,9 @@ Dwarf::assemble $asm_file {
if { [prepare_for_testing "failed to prepare" ${testfile} \
[list $srcfile $asm_file] {nodebug}] } {
- return -1
+ return
}
+
+# Let includers know prepare_for_testing was done, without having to check
+# source return status.
+set prepare_for_testing_done 1
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-modula2-self-type.S b/gdb/testsuite/gdb.dwarf2/dw2-modula2-self-type.S
index c09c6db..06a93ac 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-modula2-self-type.S
+++ b/gdb/testsuite/gdb.dwarf2/dw2-modula2-self-type.S
@@ -114,7 +114,11 @@ die221:
.byte 0x0
- .section .debug_str
+#ifdef __arm__
+ .section .debug_str,"MS",%progbits,1
+#else
+ .section .debug_str,"MS",@progbits,1
+#endif
.LASF1:
.string "2.mod"
.LASF0:
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym-warning.exp b/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym-warning.exp
index ea0fc03..6120878 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym-warning.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym-warning.exp
@@ -117,7 +117,7 @@ if ![runto_main] {
# the hole is there in the symbol table, but not the partial symbol table,
# we run into:
# (gdb) bt
-# warning: (Internal error: pc 0x555555554619 in read in psymtab, \
+# warning: (Internal error: pc 0x555555554619 in read in psymtab,
# but not in symtab.)
# ...
# (gdb)
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.S b/gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.S
index cd999f4..551dda7 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.S
+++ b/gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.S
@@ -160,7 +160,11 @@ d:
.byte 0
.byte 0
.byte 0
- .section .debug_str
+#ifdef __arm__
+ .section .debug_str,"MS",%progbits,1
+#else
+ .section .debug_str,"MS",@progbits,1
+#endif
.LASF2:
.string "GNU C 4.7.0 20110727 (experimental)"
.LASF0:
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-strp.S b/gdb/testsuite/gdb.dwarf2/dw2-strp.S
index c7ede95..db3e64f 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-strp.S
+++ b/gdb/testsuite/gdb.dwarf2/dw2-strp.S
@@ -163,7 +163,11 @@
.byte 0x0 /* Terminator */
/* String table */
- .section .debug_str
+#ifdef __arm__
+ .section .debug_str,"MS",%progbits,1
+#else
+ .section .debug_str,"MS",@progbits,1
+#endif
.Lproducer:
.string "GNU C 3.3.3"
.Lchar_str:
diff --git a/gdb/testsuite/gdb.dwarf2/dynamic-bit-offset.exp b/gdb/testsuite/gdb.dwarf2/dynamic-bit-offset.exp
new file mode 100644
index 0000000..f4e02da
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dynamic-bit-offset.exp
@@ -0,0 +1,95 @@
+# Copyright 2025 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 <http://www.gnu.org/licenses/>.
+
+# Test DW_AT_data_bit_offset with an expression. This is a DWARF
+# extension, but expected to be in DWARF 6. See
+# https://dwarfstd.org/issues/250501.1.html
+
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+require dwarf2_support
+
+standard_testfile ada-array-bound.c -debug.S
+
+# Set up the DWARF for the test.
+
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+ global srcdir subdir srcfile
+
+ cu {} {
+ DW_TAG_compile_unit {
+ {DW_AT_language @DW_LANG_Ada95}
+ {DW_AT_name $srcfile}
+ } {
+ declare_labels byte array struct
+
+ byte: DW_TAG_base_type {
+ {DW_AT_byte_size 1 DW_FORM_sdata}
+ {DW_AT_encoding @DW_ATE_unsigned}
+ {DW_AT_name byte}
+ }
+
+ array: DW_TAG_array_type {
+ {DW_AT_name array_type}
+ {DW_AT_type :$byte}
+ } {
+ DW_TAG_subrange_type {
+ {DW_AT_type :$byte}
+ {DW_AT_upper_bound 3 DW_FORM_sdata}
+ }
+ }
+
+ struct: DW_TAG_structure_type {
+ {DW_AT_name discriminated}
+ {DW_AT_byte_size 4 DW_FORM_sdata}
+ } {
+ DW_TAG_member {
+ {DW_AT_name disc}
+ {DW_AT_type :$byte}
+ {DW_AT_data_member_location 0 DW_FORM_sdata}
+ }
+
+ # We know this is always at offset 1 but use an
+ # expression just to test this code path. This is a
+ # DWARF extension. See
+ # https://dwarfstd.org/issues/250501.1.html.
+ DW_TAG_member {
+ {DW_AT_name nums}
+ {DW_AT_type :$array}
+ {DW_AT_data_bit_offset {DW_OP_lit8} SPECIAL_expr}
+ }
+ }
+
+ DW_TAG_variable {
+ {DW_AT_name "value"}
+ {DW_AT_type :$struct}
+ {DW_AT_external 1 DW_FORM_flag}
+ {DW_AT_location {DW_OP_addr [gdb_target_symbol "our_data"]}
+ SPECIAL_expr}
+ }
+ }
+ }
+}
+
+if {[prepare_for_testing "failed to prepare" ${testfile} \
+ [list $srcfile $asm_file] {nodebug}]} {
+ return -1
+}
+
+gdb_test_no_output "set language ada"
+gdb_test "print value" \
+ [string_to_regexp " = (disc => 3, nums => (7, 11, 13))"]
diff --git a/gdb/testsuite/gdb.dwarf2/fission-dw-form-strx.exp b/gdb/testsuite/gdb.dwarf2/fission-dw-form-strx.exp
new file mode 100644
index 0000000..4f5867c
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/fission-dw-form-strx.exp
@@ -0,0 +1,88 @@
+# Copyright 2025 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 <http://www.gnu.org/licenses/>.
+
+# Check support for a DW_FORM_strx attribute in a dwo file.
+
+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 -dw.S -dwo.S
+
+set main_asm_file [standard_output_file $srcfile2]
+set dwo_asm_file [standard_output_file $srcfile3]
+
+# Debug info in the main file.
+Dwarf::assemble $main_asm_file {
+ cu {
+ version 5
+ dwo_id 0xF00D
+ } {
+ compile_unit {
+ {DW_AT_dwo_name ${::gdb_test_file_name}.dwo DW_FORM_strp}
+ } {}
+ }
+}
+
+# Debug info in the DWO file.
+Dwarf::assemble $dwo_asm_file {
+ debug_str_offsets { dwo 1 } int
+
+ cu {
+ fission 1
+ version 5
+ dwo_id 0xF00D
+ } {
+ compile_unit {} {
+ declare_labels int4_type
+
+ int4_type: DW_TAG_base_type {
+ {DW_AT_byte_size 4 DW_FORM_sdata}
+ {DW_AT_encoding @DW_ATE_signed}
+ {DW_AT_name 0 DW_FORM_strx_id}
+ }
+
+ DW_TAG_variable {
+ {DW_AT_name global_var}
+ {DW_AT_type :$int4_type}
+ {DW_AT_location {
+ DW_OP_const1u 12
+ DW_OP_stack_value
+ } SPECIAL_expr}
+ }
+ }
+ }
+}
+
+# Build main file.
+if { [build_executable "${testfile}.exp" $binfile \
+ [list ${srcfile} ${main_asm_file}] {nodebug}] } {
+ return
+}
+
+# Build DWO file.
+set dwo_file [standard_output_file ${testfile}.dwo]
+if { [gdb_compile_shlib $dwo_asm_file $dwo_file nodebug] != "" } {
+ return
+}
+
+if { [is_remote host] } {
+ gdb_remote_download host $dwo_file
+}
+
+clean_restart $binfile
+
+gdb_test "ptype global_var" "type = int"
diff --git a/gdb/testsuite/gdb.dwarf2/pr11465.S b/gdb/testsuite/gdb.dwarf2/pr11465.S
index fed98bc..f3f2c57 100644
--- a/gdb/testsuite/gdb.dwarf2/pr11465.S
+++ b/gdb/testsuite/gdb.dwarf2/pr11465.S
@@ -344,7 +344,11 @@ die149: .uleb128 0x16 /* DW_TAG_variable */
.byte 0x0
.byte 0x0
.byte 0x0
- .section .debug_str
+#ifdef __arm__
+ .section .debug_str,"MS",%progbits,1
+#else
+ .section .debug_str,"MS",@progbits,1
+#endif
.LASF0:
.string "_ZN1N1fE"
.LASF7:
diff --git a/gdb/testsuite/gdb.guile/scm-cmd.exp b/gdb/testsuite/gdb.guile/scm-cmd.exp
index 9caca24..3709cb1 100644
--- a/gdb/testsuite/gdb.guile/scm-cmd.exp
+++ b/gdb/testsuite/gdb.guile/scm-cmd.exp
@@ -71,6 +71,65 @@ gdb_test_multiline "input subcommand" \
gdb_test "prefix-cmd subcmd ugh" "subcmd output, arg = ugh" "call subcmd"
+# Create a sub-command using a partial, but still unique, prefix.
+
+gdb_test_multiline "sub-command using partial prefix" \
+ "guile" "" \
+ "(register-command! (make-command \"prefix subcmd2\"" "" \
+ " #:command-class COMMAND_OBSCURE" "" \
+ " #:invoke (lambda (self arg from-tty)" "" \
+ " (display (format #f \"subcmd2 output, arg = ~a\\n\" arg)))))" "" \
+ "end" ""
+
+gdb_test "prefix-cmd subcmd2 ugh" "subcmd2 output, arg = ugh" "call subcmd2"
+
+# Now create a second prefix, similar to the first.
+
+gdb_test_multiline "create prefix-xxx prefix command" \
+ "guile" "" \
+ "(register-command! (make-command \"prefix-xxx\"" "" \
+ " #:command-class COMMAND_OBSCURE" "" \
+ " #:completer-class COMPLETE_NONE" "" \
+ " #:prefix? #t))" "" \
+ "end" ""
+
+# Now create a sub-command using an ambiguous prefix.
+
+gdb_test_multiline "sub-command using ambiguous partial prefix" \
+ "guile" "" \
+ "(register-command! (make-command \"prefix subcmd3\"" "" \
+ " #:command-class COMMAND_OBSCURE" "" \
+ " #:invoke (lambda (self arg from-tty)" "" \
+ " (display (format #f \"subcmd3 output, arg = ~a\\n\" arg)))))" "" \
+ "end" \
+ [multi_line \
+ "Out of range: could not find command prefix 'prefix' in position 1: \"prefix subcmd3\"" \
+ "Error while executing Scheme code\\."]
+
+# Check for errors when creating a command with an unknown prefix.
+
+gdb_test_multiline "try to create 'unknown-prefix subcmd'" \
+ "guile" "" \
+ "(register-command! (make-command \"unknown-prefix subcmd\"" "" \
+ " #:command-class COMMAND_OBSCURE" "" \
+ " #:invoke (lambda (self arg from-tty)" "" \
+ " (display \"called unknown-prefix subcmd\"))))" "" \
+ "end" \
+ [multi_line \
+ "Out of range: could not find command prefix 'unknown-prefix' in position 1: \"unknown-prefix subcmd\"" \
+ "Error while executing Scheme code\\."]
+
+gdb_test_multiline "try to create 'prefix-cmd unknown-prefix subcmd'" \
+ "guile" "" \
+ "(register-command! (make-command \"prefix-cmd unknown-prefix subcmd\"" "" \
+ " #:command-class COMMAND_OBSCURE" "" \
+ " #:invoke (lambda (self arg from-tty)" "" \
+ " (display \"called prefix-cmd unknown-prefix subcmd\"))))" "" \
+ "end" \
+ [multi_line \
+ "Out of range: could not find command prefix 'prefix-cmd unknown-prefix' in position 1: \"prefix-cmd unknown-prefix subcmd\"" \
+ "Error while executing Scheme code\\."]
+
# Test a subcommand in an existing GDB prefix.
gdb_test_multiline "input new subcommand" \
diff --git a/gdb/testsuite/gdb.guile/scm-frame.exp b/gdb/testsuite/gdb.guile/scm-frame.exp
index b5ec73f..9a27c42 100644
--- a/gdb/testsuite/gdb.guile/scm-frame.exp
+++ b/gdb/testsuite/gdb.guile/scm-frame.exp
@@ -52,7 +52,7 @@ gdb_test "guile (print (frame-read-var bf1 \"b\"))" \
"\"bar\"" "test b"
# Test the read-var function in another block other than the current
-# block (in this case, the super block). Test thar read-var is reading
+# block (in this case, the super block). Test that read-var is reading
# the correct variables of i and f but they are the correct value and type.
gdb_scm_test_silent_cmd "guile (define sb (block-superblock (frame-block bf1)))" \
"get superblock"
diff --git a/gdb/testsuite/gdb.guile/scm-parameter.exp b/gdb/testsuite/gdb.guile/scm-parameter.exp
index 8ab5d93..e35428a 100644
--- a/gdb/testsuite/gdb.guile/scm-parameter.exp
+++ b/gdb/testsuite/gdb.guile/scm-parameter.exp
@@ -67,9 +67,19 @@ with_test_prefix "test-param" {
gdb_test_no_output "set print test-param off"
gdb_test "show print test-param" "The state of the Test Parameter is off." "show parameter off"
gdb_test "guile (print (parameter-value test-param))" "= #f" "parameter value, false"
- gdb_test "help show print test-param" "Show the state of the boolean test-param.*" "show help"
- gdb_test "help set print test-param" "Set the state of the boolean test-param.*" "set help"
- gdb_test "help set print" "set print test-param -- Set the state of the boolean test-param.*" "general help"
+ gdb_test "help show print test-param" \
+ [multi_line \
+ "^Show the state of the boolean test-param\\." \
+ "When enabled, test param does something useful\\. When disabled, does nothing\\."] \
+ "show help"
+ gdb_test "help set print test-param" \
+ [multi_line \
+ "^Set the state of the boolean test-param\\." \
+ "When enabled, test param does something useful\\. When disabled, does nothing\\."] \
+ "set help"
+ gdb_test "help set print" \
+ "set print test-param -- Set the state of the boolean test-param.*" \
+ "general help"
gdb_test "guile (print (parameter? test-param))" "= #t"
gdb_test "guile (print (parameter? 42))" "= #f"
@@ -314,9 +324,17 @@ with_test_prefix "test-undocumented-param" {
gdb_test "show print test-undoc-param" "The state of the Test Parameter is on." "show parameter on"
gdb_test_no_output "set print test-undoc-param off"
gdb_test "show print test-undoc-param" "The state of the Test Parameter is off." "show parameter off"
- gdb_test "help show print test-undoc-param" "This command is not documented." "show help"
- gdb_test "help set print test-undoc-param" "This command is not documented." "set help"
- gdb_test "help set print" "set print test-undoc-param -- This command is not documented.*" "general help"
+ gdb_test "help show print test-undoc-param" \
+ [multi_line \
+ "^Show the current value of 'print test-undoc-param'\\." \
+ "This command is not documented\\."] \
+ "show help"
+ gdb_test "help set print test-undoc-param" \
+ [multi_line \
+ "Set the current value of 'print test-undoc-param'\\." \
+ "This command is not documented\\."] \
+ "set help"
+ gdb_test "help set print" "set print test-undoc-param -- Set the current value of 'print test-undoc-param'\\..*" "general help"
}
# Test a parameter with a restricted range, where we need to notify the user
@@ -379,13 +397,168 @@ gdb_test_no_output "guile (register-parameter! prev-ambig)"
with_test_prefix "previously-ambiguous" {
gdb_test "guile (print (parameter-value prev-ambig))" "= #f" "parameter value, false"
- gdb_test "show print s" "Command is not documented is off." "show parameter off"
+ gdb_test "show print s" \
+ "The current value of 'print s' is off\\." "show parameter off"
gdb_test_no_output "set print s on"
- gdb_test "show print s" "Command is not documented is on." "show parameter on"
+ gdb_test "show print s" \
+ "The current value of 'print s' is on\\." "show parameter on"
gdb_test "guile (print (parameter-value prev-ambig))" "= #t" "parameter value, true"
- gdb_test "help show print s" "This command is not documented." "show help"
- gdb_test "help set print s" "This command is not documented." "set help"
- gdb_test "help set print" "set print s -- This command is not documented.*" "general help"
+ gdb_test "help show print s" \
+ [multi_line \
+ "^Show the current value of 'print s'\\." \
+ "This command is not documented\\."] \
+ "show help"
+ gdb_test "help set print s" \
+ [multi_line \
+ "Set the current value of 'print s'\\." \
+ "This command is not documented\\."] \
+ "set help"
+ gdb_test "help set print" \
+ "set print s -- Set the current value of 'print s'\\..*" \
+ "general help"
+}
+
+gdb_test_multiline "create set/show foo1 prefix commands" \
+ "guile" "" \
+ "(register-command! (make-command \"set foo1\"" "" \
+ " #:command-class COMMAND_OBSCURE" "" \
+ " #:prefix? #t))" "" \
+ "(register-command! (make-command \"show foo1\"" "" \
+ " #:command-class COMMAND_OBSCURE" "" \
+ " #:prefix? #t))" "" \
+ "end"
+
+gdb_test_multiline "create set/show foo1 baz1 prefix commands" \
+ "guile" "" \
+ "(register-command! (make-command \"set foo1 baz1\"" "" \
+ " #:command-class COMMAND_OBSCURE" "" \
+ " #:prefix? #t))" "" \
+ "(register-command! (make-command \"show foo1 baz1\"" "" \
+ " #:command-class COMMAND_OBSCURE" "" \
+ " #:prefix? #t))" "" \
+ "end"
+
+gdb_test_multiline "create 'foo bar' parameter" \
+ "guile" "" \
+ "(register-parameter! (make-parameter \"foo bar\"" "" \
+ " #:command-class COMMAND_OBSCURE" "" \
+ " #:parameter-type PARAM_BOOLEAN" "" \
+ " #:show-func (lambda (self value)" "" \
+ " (format #f \"The state of 'foo bar' is ~a.\" value))" "" \
+ " #:initial-value #t))" "" \
+ "end"
+
+gdb_test "show foo1 bar" "^The state of 'foo bar' is on\\." "show parameter 'foo bar'"
+
+gdb_test_multiline "create set/show foo2 prefix commands" \
+ "guile" "" \
+ "(register-command! (make-command \"set foo2\"" "" \
+ " #:command-class COMMAND_OBSCURE" "" \
+ " #:prefix? #t))" "" \
+ "(register-command! (make-command \"show foo2\"" "" \
+ " #:command-class COMMAND_OBSCURE" "" \
+ " #:prefix? #t))" "" \
+ "end" ""
+
+gdb_test_multiline "create ambiguous 'foo baz' parameter" \
+ "guile" "" \
+ "(register-parameter! (make-parameter \"foo baz\"" "" \
+ " #:command-class COMMAND_OBSCURE" "" \
+ " #:parameter-type PARAM_BOOLEAN" "" \
+ " #:show-func (lambda (self value)" "" \
+ " (format #f \"The state of 'foo baz' is ~a.\" value))" "" \
+ " #:initial-value #t))" "" \
+ "end" \
+ [multi_line \
+ "Out of range: could not find command prefix 'foo' in position 1: \"foo baz\"" \
+ "Error while executing Scheme code."]
+
+with_test_prefix "empty doc string" {
+ gdb_test_multiline "empty doc string parameter" \
+ "guile" "" \
+ "(register-parameter! (make-parameter \"empty-doc-string\"" "" \
+ " #:command-class COMMAND_NONE" "" \
+ " #:parameter-type PARAM_ZINTEGER" "" \
+ " #:doc \"\"" "" \
+ " #:set-doc \"Set doc string.\"" "" \
+ " #:show-doc \"Show doc string.\"))" "" \
+ "end"
+
+ gdb_test "help set empty-doc-string" "^Set doc string\\."
+ gdb_test "help show empty-doc-string" "^Show doc string\\."
+}
+
+with_test_prefix "set/show parameter" {
+ # This first set/show prefix command doesn't have an invoke
+ # method. As such, GDB installs the default invoke behaviour; set
+ # prints the full list of sub-commands, and show prints all the
+ # sub-command values.
+ gdb_test_multiline "Setup set/show parameter prefix with no invoke" \
+ "guile" "" \
+ "(register-command! (make-command \"set test-prefix\"" "" \
+ " #:prefix? #t" "" \
+ " #:command-class COMMAND_NONE))" ""\
+ "(register-command! (make-command \"show test-prefix\"" "" \
+ " #:prefix? #t" "" \
+ " #:command-class COMMAND_NONE))" ""\
+ "(register-parameter! (make-parameter \"test-prefix param-1\"" "" \
+ " #:command-class COMMAND_NONE" "" \
+ " #:parameter-type PARAM_BOOLEAN))" "" \
+ "(register-parameter! (make-parameter \"test-prefix param-2\"" "" \
+ " #:command-class COMMAND_NONE" "" \
+ " #:parameter-type PARAM_UINTEGER))" "" \
+ "(register-parameter! (make-parameter \"test-prefix param-3\"" "" \
+ " #:command-class COMMAND_NONE" "" \
+ " #:parameter-type PARAM_STRING))" "" \
+ "end" ""
+
+ gdb_test "set test-prefix" \
+ [multi_line \
+ "List of \"set test-prefix\" subcommands:" \
+ "" \
+ "set test-prefix param-1 -- Set the current value of 'test-prefix param-1'." \
+ "set test-prefix param-2 -- Set the current value of 'test-prefix param-2'." \
+ "set test-prefix param-3 -- Set the current value of 'test-prefix param-3'." \
+ "" \
+ "Type \"help set test-prefix\" followed by subcommand name for full documentation\\." \
+ "Type \"apropos word\" to search for commands related to \"word\"\\." \
+ "Type \"apropos -v word\" for full documentation of commands related to \"word\"\\." \
+ "Command name abbreviations are allowed if unambiguous\\."]
+
+ gdb_test "show test-prefix" \
+ [multi_line \
+ "test-prefix param-1: The current value of 'test-prefix param-1' is off\\." \
+ "test-prefix param-2: The current value of 'test-prefix param-2' is 0\\." \
+ "test-prefix param-3: The current value of 'test-prefix param-3' is \"\"\\."]
+
+ # This next set/show prefix has an invoke method, which will be
+ # called instead of the default behaviour tested above.
+ gdb_test_multiline "Setup set/show parameter prefix with invoke" \
+ "guile" "" \
+ "(register-command! (make-command \"set test-prefix-2\"" "" \
+ " #:prefix? #t" "" \
+ " #:command-class COMMAND_NONE" ""\
+ " #:invoke (lambda (self arg from-tty)" "" \
+ " (display \"invoke -- set\\n\"))))" "" \
+ "(register-command! (make-command \"show test-prefix-2\"" "" \
+ " #:prefix? #t" "" \
+ " #:command-class COMMAND_NONE" ""\
+ " #:invoke (lambda (self arg from-tty)" "" \
+ " (display \"invoke -- show\\n\"))))" "" \
+ "(register-parameter! (make-parameter \"test-prefix-2 param-1\"" "" \
+ " #:command-class COMMAND_NONE" "" \
+ " #:parameter-type PARAM_BOOLEAN))" "" \
+ "(register-parameter! (make-parameter \"test-prefix-2 param-2\"" "" \
+ " #:command-class COMMAND_NONE" "" \
+ " #:parameter-type PARAM_UINTEGER))" "" \
+ "(register-parameter! (make-parameter \"test-prefix-2 param-3\"" "" \
+ " #:command-class COMMAND_NONE" "" \
+ " #:parameter-type PARAM_STRING))" "" \
+ "end" ""
+
+ gdb_test "set test-prefix-2" "^invoke -- set"
+
+ gdb_test "show test-prefix-2" "^invoke -- show"
}
rename scm_param_test_maybe_no_output ""
diff --git a/gdb/testsuite/gdb.linespec/linespec.exp b/gdb/testsuite/gdb.linespec/linespec.exp
index 69744dd..86b55bb 100644
--- a/gdb/testsuite/gdb.linespec/linespec.exp
+++ b/gdb/testsuite/gdb.linespec/linespec.exp
@@ -194,6 +194,12 @@ gdb_test "break lspec.h:$line" \
"Breakpoint \[0-9\]+ at $hex: file .*lspec.h, line $line." \
"set breakpoint in f1"
+# This should only have a single location -- in no_multi_locs.
+set line [gdb_get_line_number no_multi_locs]
+gdb_test "break $line" \
+ "Breakpoint \[0-9\]+ at $hex: file .*$srcfile, line $line." \
+ "set breakpoint at no_multi_locs"
+
#
# Multi-inferior tests.
#
diff --git a/gdb/testsuite/gdb.linespec/lspec.cc b/gdb/testsuite/gdb.linespec/lspec.cc
index bb660fb..ab0a193 100644
--- a/gdb/testsuite/gdb.linespec/lspec.cc
+++ b/gdb/testsuite/gdb.linespec/lspec.cc
@@ -13,6 +13,8 @@ int body_elsewhere()
#include "body.h"
}
+void no_multi_locs () { {int var = 0;} }
+
int main()
{
return dupname(0) + m(0) + n(0) + f1() + f2() + body_elsewhere();
diff --git a/gdb/testsuite/gdb.mi/interrupt-thread-group.exp b/gdb/testsuite/gdb.mi/interrupt-thread-group.exp
index ff35109..869fb1c 100644
--- a/gdb/testsuite/gdb.mi/interrupt-thread-group.exp
+++ b/gdb/testsuite/gdb.mi/interrupt-thread-group.exp
@@ -54,7 +54,7 @@ mi_send_resuming_command "exec-continue --thread-group i1" \
# We can't run a second inferior on stub targets. We can still test with one
# inferior and ensure that the command has the desired effect.
-set use_second_inferior [expr {![use_gdb_stub]}]
+set use_second_inferior [expr {![use_gdb_stub] && [allow_multi_inferior_tests]}]
if { $use_second_inferior } {
mi_gdb_test "-add-inferior" \
diff --git a/gdb/testsuite/gdb.mi/mi-condbreak-throw.exp b/gdb/testsuite/gdb.mi/mi-condbreak-throw.exp
index 9897b2b..0a89a8a 100644
--- a/gdb/testsuite/gdb.mi/mi-condbreak-throw.exp
+++ b/gdb/testsuite/gdb.mi/mi-condbreak-throw.exp
@@ -16,7 +16,7 @@
# Check that when GDB fails to evaluate the condition of a conditional
# breakpoint we only get one *stopped notification. In this test case
# the breakpoint condition fails due to throwing an uncaught C++
-# excpetion.
+# exception.
require allow_cplus_tests
diff --git a/gdb/testsuite/gdb.mi/mi-multi-commands.exp b/gdb/testsuite/gdb.mi/mi-multi-commands.exp
index 20b8d46..3bc63eb 100644
--- a/gdb/testsuite/gdb.mi/mi-multi-commands.exp
+++ b/gdb/testsuite/gdb.mi/mi-multi-commands.exp
@@ -90,7 +90,7 @@ proc run_test { args } {
# looking for. However, due to the unpredictable
# intermingling, it's much easier if we drop the ^ anchor.
# However, with this gone dejagnu would sometimes match the
- # second comand output before the first commands output.
+ # second command output before the first commands output.
#
# This approach just looks for the first command output, then,
# once that has been found, we start looking for the second
diff --git a/gdb/testsuite/gdb.mi/mi-var-display.exp b/gdb/testsuite/gdb.mi/mi-var-display.exp
index 61b3894..5535368 100644
--- a/gdb/testsuite/gdb.mi/mi-var-display.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-display.exp
@@ -96,7 +96,7 @@ mi_gdb_test "-var-evaluate-expression bar" \
# Desc: change value of bar
mi_gdb_test "-var-assign bar 3" \
"\\^done,value=\"0x3\"" \
- "assing to variable bar"
+ "assign to variable bar"
mi_gdb_test "-var-set-format bar decimal" \
"\\^done,format=\"decimal\",value=\"3\"" \
@@ -152,7 +152,7 @@ mi_gdb_test "-var-evaluate-expression foo" \
# Desc: change value of foo
mi_gdb_test "-var-assign foo 3" \
"\\^done,value=\"03\"" \
- "assing to variable foo"
+ "assign to variable foo"
mi_gdb_test "-var-set-format foo decimal" \
"\\^done,format=\"decimal\",value=\"3\"" \
diff --git a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
index 9198cfb..f85e108 100644
--- a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
+++ b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
@@ -40,6 +40,8 @@ standard_testfile
# gdbserver modes are supported.
require !use_gdb_stub
+require allow_multi_inferior_tests
+
set compile_options "debug pthreads"
if {[build_executable $testfile.exp $testfile ${srcfile} ${compile_options}] == -1} {
untested "failed to compile"
@@ -985,7 +987,7 @@ proc_with_prefix test_mi_stack_select_frame { mode } {
# Now use the '-stack-select-frame' command with the --frame
# option, this verifies that even when the frame GDB would
- # swith to is the same as the frame specified with --frame, an
+ # switch to is the same as the frame specified with --frame, an
# event is still sent to the CLI.
set cli_re [make_cli_re $mode -1 -1 0]
diff --git a/gdb/testsuite/gdb.multi/attach-no-multi-process.exp b/gdb/testsuite/gdb.multi/attach-no-multi-process.exp
index 28aabaf..502f309 100644
--- a/gdb/testsuite/gdb.multi/attach-no-multi-process.exp
+++ b/gdb/testsuite/gdb.multi/attach-no-multi-process.exp
@@ -59,7 +59,10 @@ proc test {target_non_stop} {
"switch to inferior 2"
set res [gdbserver_start "--multi" ""]
set gdbserver_gdbport [lindex $res 1]
- gdb_target_cmd "extended-remote" $gdbserver_gdbport
+ if { [gdb_target_cmd_ext "extended-remote" $gdbserver_gdbport] == 2 } {
+ unsupported "non-stop RSP"
+ return
+ }
# Start a program, then attach to it.
set spawn_id_list [spawn_wait_for_attach [list $binfile]]
diff --git a/gdb/testsuite/gdb.multi/attach-while-running.exp b/gdb/testsuite/gdb.multi/attach-while-running.exp
index 5b63030..723ebb2 100644
--- a/gdb/testsuite/gdb.multi/attach-while-running.exp
+++ b/gdb/testsuite/gdb.multi/attach-while-running.exp
@@ -37,6 +37,7 @@
standard_testfile
require can_spawn_for_attach
+require allow_multi_inferior_tests
if { [build_executable "failed to prepare" ${testfile} ${srcfile}] } {
return
@@ -49,7 +50,7 @@ proc do_test {} {
}
gdb_test -no-prompt-anchor "run &"
- gdb_test "add-inferior" "Added inferior 2 on connection 1 .*"
+ gdb_test -no-prompt-anchor "add-inferior" "Added inferior 2 on connection 1 .*"
gdb_test "inferior 2" "Switching to inferior 2 .*"
set spawn_id [spawn_wait_for_attach $::binfile]
diff --git a/gdb/testsuite/gdb.multi/bp-thread-specific.exp b/gdb/testsuite/gdb.multi/bp-thread-specific.exp
index 32b7602..3fe4c20 100644
--- a/gdb/testsuite/gdb.multi/bp-thread-specific.exp
+++ b/gdb/testsuite/gdb.multi/bp-thread-specific.exp
@@ -19,6 +19,8 @@
# Also check that the correct thread-ids are used in the saved
# breakpoints file.
+require allow_multi_inferior_tests
+
# The plain remote target can't do multiple inferiors.
require !use_gdb_stub
diff --git a/gdb/testsuite/gdb.multi/dummy-frame-restore.exp b/gdb/testsuite/gdb.multi/dummy-frame-restore.exp
index 1a9d413..4119e3f 100644
--- a/gdb/testsuite/gdb.multi/dummy-frame-restore.exp
+++ b/gdb/testsuite/gdb.multi/dummy-frame-restore.exp
@@ -19,6 +19,8 @@ set executable ${testfile}
# The plain remote target can't do multiple inferiors.
require !use_gdb_stub
+require allow_multi_inferior_tests
+
if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug}]} {
return -1
}
diff --git a/gdb/testsuite/gdb.multi/multi-arch.exp b/gdb/testsuite/gdb.multi/multi-arch.exp
index d0ae511..1d41ba5 100644
--- a/gdb/testsuite/gdb.multi/multi-arch.exp
+++ b/gdb/testsuite/gdb.multi/multi-arch.exp
@@ -18,6 +18,8 @@
set testfile "multi-arch"
+require allow_multi_inferior_tests
+
# The plain remote target can't do multiple inferiors.
require !use_gdb_stub
diff --git a/gdb/testsuite/gdb.multi/multi-attach.exp b/gdb/testsuite/gdb.multi/multi-attach.exp
index 2d702ee..210c8ca 100644
--- a/gdb/testsuite/gdb.multi/multi-attach.exp
+++ b/gdb/testsuite/gdb.multi/multi-attach.exp
@@ -17,6 +17,8 @@
# Test attaching to multiple threaded programs.
+require allow_multi_inferior_tests
+
standard_testfile
require can_spawn_for_attach
diff --git a/gdb/testsuite/gdb.multi/multi-exit.exp b/gdb/testsuite/gdb.multi/multi-exit.exp
index 71236c1..8393067 100644
--- a/gdb/testsuite/gdb.multi/multi-exit.exp
+++ b/gdb/testsuite/gdb.multi/multi-exit.exp
@@ -24,6 +24,8 @@
standard_testfile
+require allow_multi_inferior_tests
+
require !use_gdb_stub
if {[build_executable "failed to prepare" $testfile $srcfile]} {
diff --git a/gdb/testsuite/gdb.multi/multi-kill.exp b/gdb/testsuite/gdb.multi/multi-kill.exp
index 48a2534..7d66ab0 100644
--- a/gdb/testsuite/gdb.multi/multi-kill.exp
+++ b/gdb/testsuite/gdb.multi/multi-kill.exp
@@ -24,6 +24,8 @@
standard_testfile
+require allow_multi_inferior_tests
+
require !use_gdb_stub
if {[build_executable "failed to prepare" $testfile $srcfile {debug}]} {
diff --git a/gdb/testsuite/gdb.multi/multi-re-run.exp b/gdb/testsuite/gdb.multi/multi-re-run.exp
index 002de57..4caadea 100644
--- a/gdb/testsuite/gdb.multi/multi-re-run.exp
+++ b/gdb/testsuite/gdb.multi/multi-re-run.exp
@@ -20,6 +20,8 @@
# misbehave, including failing to load libthread_db.so. See PR
# gdb/25410.
+require allow_multi_inferior_tests
+
# Build two executables, with different symbols.
set exec1 "multi-re-run-1"
diff --git a/gdb/testsuite/gdb.multi/multi-target.exp.tcl b/gdb/testsuite/gdb.multi/multi-target.exp.tcl
index 8c24602..dc88ca4 100644
--- a/gdb/testsuite/gdb.multi/multi-target.exp.tcl
+++ b/gdb/testsuite/gdb.multi/multi-target.exp.tcl
@@ -175,6 +175,10 @@ proc multi_target_prepare {} {
return 0
}
+ if {![allow_multi_inferior_tests]} {
+ return 0
+ }
+
# The plain remote target can't do multiple inferiors.
if {[target_info gdb_protocol] != ""} {
return 0
diff --git a/gdb/testsuite/gdb.multi/multi-term-settings.exp b/gdb/testsuite/gdb.multi/multi-term-settings.exp
index 2f8b3b8..38322be 100644
--- a/gdb/testsuite/gdb.multi/multi-term-settings.exp
+++ b/gdb/testsuite/gdb.multi/multi-term-settings.exp
@@ -25,6 +25,8 @@
standard_testfile
+require allow_multi_inferior_tests
+
require can_spawn_for_attach
if [build_executable "failed to prepare" $testfile $srcfile {debug}] {
diff --git a/gdb/testsuite/gdb.multi/start-inferior-specific.exp b/gdb/testsuite/gdb.multi/start-inferior-specific.exp
index 819c1c3..74f984c 100644
--- a/gdb/testsuite/gdb.multi/start-inferior-specific.exp
+++ b/gdb/testsuite/gdb.multi/start-inferior-specific.exp
@@ -25,6 +25,8 @@
standard_testfile .c -other.c
+require allow_multi_inferior_tests
+
require !use_gdb_stub
set srcfile_other ${srcfile2}
diff --git a/gdb/testsuite/gdb.multi/stop-all-on-exit.exp b/gdb/testsuite/gdb.multi/stop-all-on-exit.exp
index b4ff09c..47071f3 100644
--- a/gdb/testsuite/gdb.multi/stop-all-on-exit.exp
+++ b/gdb/testsuite/gdb.multi/stop-all-on-exit.exp
@@ -18,6 +18,8 @@
# Test that in all-stop mode with multiple inferiors, GDB stops all
# threads upon receiving an exit event from one of the inferiors.
+require allow_multi_inferior_tests
+
# This is a test specific for a native target, where we use the
# "-exec" argument to "add-inferior" and we explicitly don't do
# "maint set target-non-stop on".
diff --git a/gdb/testsuite/gdb.multi/tids-gid-reset.exp b/gdb/testsuite/gdb.multi/tids-gid-reset.exp
index 6cc27eb..1785ac2 100644
--- a/gdb/testsuite/gdb.multi/tids-gid-reset.exp
+++ b/gdb/testsuite/gdb.multi/tids-gid-reset.exp
@@ -54,6 +54,8 @@ with_test_prefix "single-inferior" {
# non-extended gdbserver is not supported.
require !use_gdb_stub
+require allow_multi_inferior_tests
+
# Test with multiple inferiors. This time, since we restart inferior
# 1 while inferior 2 still has threads, then the new thread 1.1 should
# end up with GID == 3, since we won't be able to reset the global
diff --git a/gdb/testsuite/gdb.multi/tids.exp b/gdb/testsuite/gdb.multi/tids.exp
index b84f908..436a38a 100644
--- a/gdb/testsuite/gdb.multi/tids.exp
+++ b/gdb/testsuite/gdb.multi/tids.exp
@@ -124,6 +124,9 @@ with_test_prefix "single inferior" {
gdb_test "print \$_inferior_thread_count" " = 1"
}
+# The rest of the tests require running multiple inferiors.
+require allow_multi_inferior_tests
+
# "info threads" while there are multiple inferiors should show
# qualified thread IDs.
with_test_prefix "two inferiors" {
@@ -290,7 +293,7 @@ with_test_prefix "two inferiors" {
# Try both the convenience variable and the literal number.
foreach thr {"\$thr" "20" "1.20" "\$inf.1" "30.1" } {
set expected [string_to_regexp $thr]
- gdb_test "info threads $thr" "No threads match '${expected}'."
+ gdb_test "info threads $thr" "No threads matched\\."
# "info threads" works like a filter. If there's any other
# valid thread in the list, there's no error.
info_threads "$thr 1.1" "1.1"
@@ -412,7 +415,7 @@ with_test_prefix "two inferiors" {
# Check that we do parse the inferior number and don't confuse it.
gdb_test "info threads 3.1" \
- "No threads match '3.1'\."
+ "No threads matched\\."
}
if { [allow_python_tests] } {
diff --git a/gdb/testsuite/gdb.multi/watchpoint-multi-exit.exp b/gdb/testsuite/gdb.multi/watchpoint-multi-exit.exp
index 70c3da9..3446296 100644
--- a/gdb/testsuite/gdb.multi/watchpoint-multi-exit.exp
+++ b/gdb/testsuite/gdb.multi/watchpoint-multi-exit.exp
@@ -17,6 +17,8 @@
# watchpoints don't end up with stale locations, preventing resumption
# of other inferiors.
+require allow_fork_tests
+
standard_testfile
if {[build_executable "failed to build" $testfile $srcfile {debug}]} {
diff --git a/gdb/testsuite/gdb.multi/watchpoint-multi.exp b/gdb/testsuite/gdb.multi/watchpoint-multi.exp
index f448689..b0c8731 100644
--- a/gdb/testsuite/gdb.multi/watchpoint-multi.exp
+++ b/gdb/testsuite/gdb.multi/watchpoint-multi.exp
@@ -16,6 +16,8 @@
standard_testfile
set executable ${testfile}
+require allow_multi_inferior_tests
+
# Multiple inferiors are needed, therefore both native and extended gdbserver
# modes are supported. Only non-extended gdbserver is not supported.
require !use_gdb_stub
diff --git a/gdb/testsuite/gdb.opt/break-on-_exit.exp b/gdb/testsuite/gdb.opt/break-on-_exit.exp
index 2b94be8..9295fea 100644
--- a/gdb/testsuite/gdb.opt/break-on-_exit.exp
+++ b/gdb/testsuite/gdb.opt/break-on-_exit.exp
@@ -25,7 +25,7 @@
# for libc, then the breakpoint is set on the exec-local _exit@plt instead,
# and that functionality will also not be used.
#
-# We may get the required setup in case of a libc with misssing separate
+# We may get the required setup in case of a libc with missing separate
# debuginfo, but we want the same effect if that debuginfo is installed.
#
# So, we use -readnever to read minimal symbols, but not non-miminal symbols.
diff --git a/gdb/testsuite/gdb.pascal/integers.exp b/gdb/testsuite/gdb.pascal/integers.exp
index 5c878c5..c9974a1 100644
--- a/gdb/testsuite/gdb.pascal/integers.exp
+++ b/gdb/testsuite/gdb.pascal/integers.exp
@@ -59,7 +59,7 @@ gdb_test "next" "l := k;" "next to 'l := k' line"
gdb_test "print j" " = 2"
# k should be equal to 3
gdb_test "print k" " = 3"
-# But l shoud still be zero
+# But l should still be zero
if { $pascal_compiler_is_gpc } {
setup_xfail *-*-*
}
diff --git a/gdb/testsuite/gdb.python/py-cmd.exp b/gdb/testsuite/gdb.python/py-cmd.exp
index f76c176..5ac5712 100644
--- a/gdb/testsuite/gdb.python/py-cmd.exp
+++ b/gdb/testsuite/gdb.python/py-cmd.exp
@@ -328,4 +328,89 @@ proc_with_prefix test_command_redefining_itself {} {
"call command redefining itself 2"
}
+# Try to create commands using unknown prefixes and check GDB gives an
+# error. There's also a test in here for an ambiguous prefix, which
+# gives the same error.
+proc_with_prefix test_unknown_prefix {} {
+ clean_restart
+
+ gdb_test_no_output "python gdb.Command('foo1', gdb.COMMAND_NONE, prefix=True)"
+ gdb_test_no_output "python gdb.Command('foo cmd', gdb.COMMAND_NONE)"
+
+ foreach prefix { "xxx" "foo xxx" "foo1 xxx" } {
+ gdb_test "python gdb.Command('$prefix cmd', gdb.COMMAND_NONE)" \
+ [multi_line \
+ "Python Exception <class 'RuntimeError'>: Could not find command prefix $prefix\\." \
+ "Error occurred in Python: Could not find command prefix $prefix\\."]
+ }
+
+ gdb_test_no_output "python gdb.Command('foo2', gdb.COMMAND_NONE, prefix=True)"
+
+ foreach prefix { "foo" "foo xxx" "foo1 xxx" "foo2 xxx" } {
+ gdb_test "python gdb.Command('$prefix cmd2', gdb.COMMAND_NONE)" \
+ [multi_line \
+ "Python Exception <class 'RuntimeError'>: Could not find command prefix $prefix\\." \
+ "Error occurred in Python: Could not find command prefix $prefix\\."]
+ }
+}
+
+# Check what happens if a command object is called without an 'invoke'
+# method.
+proc_with_prefix test_deleting_invoke_methods {} {
+ clean_restart
+
+ gdb_test_multiline "create 'foo' prefix command" \
+ "python" "" \
+ "class test_prefix(gdb.Command):" "" \
+ " def __init__ (self):" "" \
+ " super().__init__ (\"foo\", gdb.COMMAND_USER, prefix=True)" "" \
+ " def invoke (self, arg, from_tty):" "" \
+ " print(\"In 'foo' invoke: %s\" % arg)" "" \
+ "foo = test_prefix()" "" \
+ "end" ""
+
+ gdb_test_multiline "create 'foo bar' command" \
+ "python" "" \
+ "class test_cmd(gdb.Command):" "" \
+ " def __init__ (self):" "" \
+ " super().__init__ (\"foo bar\", gdb.COMMAND_USER)" "" \
+ " def invoke (self, arg, from_tty):" "" \
+ " print(\"In 'foo bar' invoke: %s\" % arg)" "" \
+ "foo_bar = test_cmd()" "" \
+ "end" ""
+
+ gdb_test "foo def" "In 'foo' invoke: def" \
+ "call 'foo' with an unknown sub-command"
+
+ gdb_test "foo bar def" "In 'foo bar' invoke: def" \
+ "call 'foo bar' with arguments"
+
+ gdb_test_no_output "python del(foo_bar.__class__.invoke)" \
+ "delete invoke from test_cmd class"
+
+ with_test_prefix "after deleting test_cmd.invoke" {
+ gdb_test "foo def" "In 'foo' invoke: def" \
+ "call 'foo' with an unknown sub-command"
+
+ gdb_test "foo bar def" \
+ "^Python command object missing 'invoke' method\\." \
+ "call 'foo bar' with arguments"
+ }
+
+ gdb_test_no_output "python del(foo.__class__.invoke)" \
+ "delete invoke from test_prefix class"
+
+ with_test_prefix "after deleting test_prefix.invoke" {
+ gdb_test "foo def" \
+ "^Python command object missing 'invoke' method\\." \
+ "call 'foo' with an unknown sub-command"
+
+ gdb_test "foo bar def" \
+ "^Python command object missing 'invoke' method\\." \
+ "call 'foo bar' with arguments"
+ }
+}
+
test_command_redefining_itself
+test_unknown_prefix
+test_deleting_invoke_methods
diff --git a/gdb/testsuite/gdb.python/py-parameter-prefix.exp b/gdb/testsuite/gdb.python/py-parameter-prefix.exp
new file mode 100644
index 0000000..eb09fe7
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-parameter-prefix.exp
@@ -0,0 +1,382 @@
+# Copyright (C) 2025 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 <http://www.gnu.org/licenses/>.
+
+# This file is part of the GDB testsuite. It tests
+# gdb.ParameterPrefix. See each of the test procs for a full
+# description of what is being tested.
+
+load_lib gdb-python.exp
+
+require allow_python_tests
+
+clean_restart
+
+# Helper proc to generate the output of 'show PREFIX' commands for the
+# case where the prefix command doesn't handle unknown sub-commands.
+# In this case GDB will list the value of every sub-command under
+# PREFIX.
+proc make_show_prefix_re { prefix } {
+ return "$prefix param-1:\\s+The current value of '$prefix param-1' is \"off\"\\."
+}
+
+# Helper proc to generate the help text that describes all of the sub
+# commands under PREFIX. The MODE is either 'set' or 'show'. This
+# output will appear for 'help MODE PREFIX' and also for 'set PREFIX'.
+proc make_sub_cmd_help_re { mode prefix } {
+ if { $mode == "set" } {
+ set word "Set"
+ } else {
+ set word "Show"
+ }
+
+ return \
+ [multi_line \
+ "List of \"$mode $prefix\" subcommands:" \
+ "" \
+ "$mode $prefix param-1 -- $word the current value of '$prefix param-1'\\." \
+ "" \
+ "Type \"help $mode $prefix\" followed by subcommand name for full documentation\\." \
+ "Type \"apropos word\" to search for commands related to \"word\"\\." \
+ "Type \"apropos -v word\" for full documentation of commands related to \"word\"\\." \
+ "Command name abbreviations are allowed if unambiguous\\."]
+}
+
+# Helper proc to generate the output of 'help MODE PREFIX', where MODE
+# will be either 'set' or 'show'. The HELP_TEXT is the expected help
+# text for this prefix command, this should not be a regexp, as this
+# proc converts the text to a regexp.
+#
+# Return a single regexp which should match the output.
+proc make_help_re { mode prefix help_text } {
+ set help_re [string_to_regexp $help_text]
+
+ return \
+ [multi_line \
+ "$help_re" \
+ "" \
+ [make_sub_cmd_help_re $mode $prefix]]
+}
+
+# Create gdb.ParameterPrefix without using a sub-class, both with, and
+# without a doc string. For the doc string case, test single line,
+# and multi-line doc strings.
+proc_with_prefix test_basic_usage {} {
+ gdb_test_multiline "some basic ParameterPrefix usage" \
+ "python" "" \
+ "gdb.ParameterPrefix('prefix-1', gdb.COMMAND_NONE)" "" \
+ "gdb.Parameter('prefix-1 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ "gdb.Parameter('prefix-1 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ "gdb.ParameterPrefix('prefix-2', gdb.COMMAND_NONE," "" \
+ " \"\"\"This is prefix-2 help string.\"\"\")" "" \
+ "gdb.Parameter('prefix-2 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ "gdb.ParameterPrefix('prefix-3', gdb.COMMAND_NONE," "" \
+ " \"\"\"This is prefix-3 help string." "" \
+ " " "" \
+ " This help text spans multiple lines.\"\"\")" "" \
+ "gdb.Parameter('prefix-3 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ "end"
+
+ foreach mode { "set" "show" } {
+ gdb_test "help $mode prefix-1" \
+ [make_help_re $mode "prefix-1" \
+ "This command is not documented."]
+
+ gdb_test "help $mode prefix-2" \
+ [make_help_re $mode "prefix-2" \
+ "This is prefix-2 help string."]
+
+ gdb_test "help $mode prefix-3" \
+ [make_help_re $mode "prefix-3" \
+ [multi_line \
+ "This is prefix-3 help string." \
+ "" \
+ "This help text spans multiple lines."]]
+
+ foreach prefix { prefix-1 prefix-2 prefix-3 } {
+ gdb_test "$mode $prefix xxx" \
+ "^Undefined $mode $prefix command: \"xxx\"\\. Try \"help $mode $prefix\"\\."
+ }
+ }
+
+ foreach prefix { prefix-1 prefix-2 prefix-3 } {
+ gdb_test "set $prefix" \
+ [make_sub_cmd_help_re "set" $prefix]
+
+ gdb_test "show $prefix" \
+ [make_show_prefix_re $prefix]
+ }
+}
+
+# Create a sub-class of gdb.ParameterPrefix, but don't do anything
+# particularly interesting. Again test the with and without
+# documentation string cases.
+proc_with_prefix test_simple_sub_class {} {
+ gdb_test_multiline "some basic ParameterPrefix usage" \
+ "python" "" \
+ "class BasicParamPrefix(gdb.ParameterPrefix):" "" \
+ " def __init__(self, name):" "" \
+ " super().__init__(name, gdb.COMMAND_NONE)" "" \
+ "BasicParamPrefix('prefix-4')" "" \
+ "gdb.Parameter('prefix-4 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ "class BasicParamPrefixWithSingleLineDoc(gdb.ParameterPrefix):" "" \
+ " \"\"\"This is a single line doc string.\"\"\"" "" \
+ " def __init__(self, name):" "" \
+ " super().__init__(name, gdb.COMMAND_NONE)" "" \
+ "BasicParamPrefixWithSingleLineDoc('prefix-5')" "" \
+ "gdb.Parameter('prefix-5 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ "class BasicParamPrefixWithMultiLineDoc(gdb.ParameterPrefix):" "" \
+ " \"\"\"This is a multi line doc string." "" \
+ " " "" \
+ " The rest of the doc string is here.\"\"\"" "" \
+ " def __init__(self, name):" "" \
+ " super().__init__(name, gdb.COMMAND_NONE)" "" \
+ "BasicParamPrefixWithMultiLineDoc('prefix-6')" "" \
+ "gdb.Parameter('prefix-6 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ "class BasicParamPrefixWithDocParameter(gdb.ParameterPrefix):" "" \
+ " \"\"\"This is an unsused doc string.\"\"\"" "" \
+ " def __init__(self, name, doc):" "" \
+ " super().__init__(name, gdb.COMMAND_NONE, doc)" "" \
+ "BasicParamPrefixWithDocParameter('prefix-7'," "" \
+ " \"\"\"The doc string text is here.\"\"\")" "" \
+ "gdb.Parameter('prefix-7 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ "end"
+
+ foreach mode { "set" "show" } {
+ gdb_test "help $mode prefix-4" \
+ [make_help_re $mode "prefix-4" \
+ "This command is not documented."]
+
+ gdb_test "help $mode prefix-5" \
+ [make_help_re $mode "prefix-5" \
+ "This is a single line doc string."]
+
+ gdb_test "help $mode prefix-6" \
+ [make_help_re $mode "prefix-6" \
+ [multi_line \
+ "This is a multi line doc string." \
+ "" \
+ "The rest of the doc string is here."]]
+
+ gdb_test "help $mode prefix-7" \
+ [make_help_re $mode "prefix-7" \
+ "The doc string text is here."]
+
+ foreach prefix { prefix-4 prefix-5 prefix-6 prefix-7 } {
+ gdb_test "$mode $prefix xxx" \
+ "^Undefined $mode $prefix command: \"xxx\"\\. Try \"help $mode $prefix\"\\."
+ }
+ }
+
+ foreach prefix { prefix-4 prefix-5 prefix-6 prefix-7 } {
+ gdb_test "set $prefix" \
+ [make_sub_cmd_help_re "set" $prefix]
+
+ gdb_test "show $prefix" \
+ [make_show_prefix_re $prefix]
+ }
+}
+
+# Create a sub-class of gdb.ParameterPrefix, and make use of
+# 'invoke_set' and 'invoke_show'. Test that the invoke method is
+# executed when expected, and that, by default, these invoke methods
+# repeat when the user issues an empty command.
+proc_with_prefix test_prefix_with_invoke {} {
+ gdb_test_multiline "ParameterPrefix with invoke_set" \
+ "python" "" \
+ "class PrefixWithInvokeSet(gdb.ParameterPrefix):" "" \
+ " def __init__(self, name):" "" \
+ " super().__init__(name, gdb.COMMAND_NONE)" "" \
+ " def invoke_set(self, args, from_tty):" "" \
+ " print(f\"invoke_set (a): \\\"{args}\\\" {from_tty}\")" "" \
+ "PrefixWithInvokeSet('prefix-8')" "" \
+ "gdb.Parameter('prefix-8 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ "class PrefixWithInvokeShow(gdb.ParameterPrefix):" "" \
+ " def __init__(self, name):" "" \
+ " super().__init__(name, gdb.COMMAND_NONE)" "" \
+ " def invoke_show(self, args, from_tty):" "" \
+ " print(f\"invoke_show (b): \\\"{args}\\\" {from_tty}\")" "" \
+ "PrefixWithInvokeShow('prefix-9')" "" \
+ "gdb.Parameter('prefix-9 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ "class PrefixWithBothInvoke(gdb.ParameterPrefix):" "" \
+ " def __init__(self, name):" "" \
+ " super().__init__(name, gdb.COMMAND_NONE)" "" \
+ " def invoke_set(self, args, from_tty):" "" \
+ " print(f\"invoke_set (c): \\\"{args}\\\" {from_tty}\")" "" \
+ " def invoke_show(self, args, from_tty):" "" \
+ " print(f\"invoke_show (d): \\\"{args}\\\" {from_tty}\")" "" \
+ "PrefixWithBothInvoke('prefix-10')" "" \
+ "gdb.Parameter('prefix-10 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ "end"
+
+ gdb_test "set prefix-8 xxx yyy" \
+ "^invoke_set \\(a\\): \"xxx yyy\" True"
+
+ send_gdb "\n"
+ gdb_test "" "^\r\ninvoke_set \\(a\\): \"xxx yyy\" True" \
+ "repeat set prefix-8 xxx yyy"
+
+ gdb_test "show prefix-8 xxx yyy" \
+ "^Undefined show prefix-8 command: \"xxx yyy\"\\. Try \"help show prefix-8\"\\."
+
+ gdb_test "set prefix-9 xxx yyy" \
+ "^Undefined set prefix-9 command: \"xxx yyy\"\\. Try \"help set prefix-9\"\\."
+
+ gdb_test "show prefix-9 xxx yyy" \
+ "^invoke_show \\(b\\): \"xxx yyy\" True"
+
+ send_gdb "\n"
+ gdb_test "" "^\r\ninvoke_show \\(b\\): \"xxx yyy\" True" \
+ "repeat show prefix-9 xxx yyy"
+
+ gdb_test "set prefix-10 xxx yyy" \
+ "^invoke_set \\(c\\): \"xxx yyy\" True"
+
+ send_gdb "\n"
+ gdb_test "" "^\r\ninvoke_set \\(c\\): \"xxx yyy\" True" \
+ "repeat set prefix-10 xxx yyy"
+
+ gdb_test "show prefix-10 xxx yyy" \
+ "^invoke_show \\(d\\): \"xxx yyy\" True"
+
+ send_gdb "\n"
+ gdb_test "" "^\r\ninvoke_show \\(d\\): \"xxx yyy\" True" \
+ "repeat show prefix-10 xxx yyy"
+
+ gdb_test "set prefix-8" \
+ "^invoke_set \\(a\\): \"\" True"
+
+ gdb_test "show prefix-8" \
+ [make_show_prefix_re "prefix-8"]
+
+ gdb_test "set prefix-9" \
+ [make_sub_cmd_help_re "set" "prefix-9"]
+
+ gdb_test "show prefix-9" \
+ "^invoke_show \\(b\\): \"\" True"
+
+ gdb_test "set prefix-10" \
+ "^invoke_set \\(c\\): \"\" True"
+
+ gdb_test "show prefix-10" \
+ "^invoke_show \\(d\\): \"\" True"
+}
+
+# Create ParameterPrefix sub-classes that make use of the
+# dont_repeat() method. Check that the relevant set/show invoke
+# callback doesn't repeat when an empty command is used.
+proc_with_prefix test_dont_repeat {} {
+ gdb_test_multiline "ParameterPrefix with invoke_set and dont_repeat" \
+ "python" "" \
+ "class PrefixWithInvokeAndDoNotRepeatSet(gdb.ParameterPrefix):" "" \
+ " def __init__(self, name):" "" \
+ " super().__init__(name, gdb.COMMAND_NONE)" "" \
+ " def invoke_set(self, args, from_tty):" "" \
+ " self.dont_repeat()" "" \
+ " print(f\"invoke_set: \\\"{args}\\\" {from_tty}\")" "" \
+ " def invoke_show(self, args, from_tty):" "" \
+ " print(f\"invoke_show: \\\"{args}\\\" {from_tty}\")" "" \
+ "PrefixWithInvokeAndDoNotRepeatSet('prefix-11')" "" \
+ "gdb.Parameter('prefix-11 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ "class PrefixWithInvokeAndDoNotRepeatShow(gdb.ParameterPrefix):" "" \
+ " def __init__(self, name):" "" \
+ " super().__init__(name, gdb.COMMAND_NONE)" "" \
+ " def invoke_set(self, args, from_tty):" "" \
+ " print(f\"invoke_set: \\\"{args}\\\" {from_tty}\")" "" \
+ " def invoke_show(self, args, from_tty):" "" \
+ " self.dont_repeat()" "" \
+ " print(f\"invoke_show: \\\"{args}\\\" {from_tty}\")" "" \
+ "PrefixWithInvokeAndDoNotRepeatShow('prefix-12')" "" \
+ "gdb.Parameter('prefix-12 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ "end"
+
+ gdb_test "set prefix-11 xxx yyy" \
+ "^invoke_set: \"xxx yyy\" True"
+
+ send_gdb "\n"
+ gdb_test "" "^" \
+ "repeat set prefix-11 xxx yyy"
+
+ gdb_test "show prefix-11 xxx yyy" \
+ "^invoke_show: \"xxx yyy\" True"
+
+ send_gdb "\n"
+ gdb_test "" "invoke_show: \"xxx yyy\" True" \
+ "repeat show prefix-11 xxx yyy"
+
+ gdb_test "set prefix-12 xxx yyy" \
+ "^invoke_set: \"xxx yyy\" True"
+
+ send_gdb "\n"
+ gdb_test "" "^\r\ninvoke_set: \"xxx yyy\" True" \
+ "repeat set prefix-12 xxx yyy"
+
+ gdb_test "show prefix-12 xxx yyy" \
+ "^invoke_show: \"xxx yyy\" True"
+
+ send_gdb "\n"
+ gdb_test "" "^" \
+ "repeat show prefix-12 xxx yyy"
+}
+
+# Create a parameter prefixm, and immediately add another prefix under
+# the first. The important thing here is that the second prefix is
+# created into an otherwise empty prefix as this triggered a bug at
+# one point.
+proc_with_prefix test_nested {} {
+ gdb_test_multiline "Create nested parameter prefixes" \
+ "python" "" \
+ "gdb.ParameterPrefix('prefix-13', gdb.COMMAND_NONE)" "" \
+ "gdb.ParameterPrefix('prefix-13 prefix-14', gdb.COMMAND_NONE)" "" \
+ "gdb.Parameter('prefix-13 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ "gdb.Parameter('prefix-13 param-2', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ "gdb.Parameter('prefix-13 prefix-14 param-3', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ "gdb.Parameter('prefix-13 prefix-14 param-4', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ "end" ""
+
+ gdb_test "show prefix-13 prefix-14" \
+ [multi_line \
+ "^prefix-13 prefix-14 param-3: The current value of 'prefix-13 prefix-14 param-3' is \"off\"\\." \
+ "prefix-13 prefix-14 param-4: The current value of 'prefix-13 prefix-14 param-4' is \"off\"\\."]
+
+ gdb_test "show prefix-13" \
+ [multi_line \
+ "^prefix-13 param-1: The current value of 'prefix-13 param-1' is \"off\"\\." \
+ "prefix-13 param-2: The current value of 'prefix-13 param-2' is \"off\"\\." \
+ "prefix-13 prefix-14 param-3: The current value of 'prefix-13 prefix-14 param-3' is \"off\"\\." \
+ "prefix-13 prefix-14 param-4: The current value of 'prefix-13 prefix-14 param-4' is \"off\"\\."]
+
+ gdb_test "set prefix-13 prefix-14" \
+ [multi_line \
+ "" \
+ "set prefix-13 prefix-14 param-3 -- Set the current value of 'prefix-13 prefix-14 param-3'\\." \
+ "set prefix-13 prefix-14 param-4 -- Set the current value of 'prefix-13 prefix-14 param-4'\\." \
+ "" \
+ ".*"]
+
+ gdb_test "set prefix-13" \
+ [multi_line \
+ "" \
+ "set prefix-13 param-1 -- Set the current value of 'prefix-13 param-1'\\." \
+ "set prefix-13 param-2 -- Set the current value of 'prefix-13 param-2'\\." \
+ "set prefix-13 prefix-14 -- This command is not documented\\." \
+ "" \
+ ".*"]
+}
+
+test_basic_usage
+test_simple_sub_class
+test_prefix_with_invoke
+test_dont_repeat
+test_nested
diff --git a/gdb/testsuite/gdb.python/py-parameter.exp b/gdb/testsuite/gdb.python/py-parameter.exp
index c15bef1..214c570 100644
--- a/gdb/testsuite/gdb.python/py-parameter.exp
+++ b/gdb/testsuite/gdb.python/py-parameter.exp
@@ -346,6 +346,91 @@ proc_with_prefix test_really_undocumented_parameter { } {
"test general help"
}
+# Test a parameter in which the __doc__ string is empty or None.
+proc_with_prefix test_empty_doc_parameter {} {
+ gdb_test_multiline "empty __doc__ parameter" \
+ "python" "" \
+ "class EmptyDocParam(gdb.Parameter):" "" \
+ " __doc__ = \"\"" "" \
+ " def __init__(self, name):" "" \
+ " super ().__init__(name, gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ " self.value = True" "" \
+ "test_empty_doc_param = EmptyDocParam('print test-empty-doc-param')" ""\
+ "end"
+
+ # Setting the __doc__ string to empty means GDB will completely
+ # elide it from the output.
+ gdb_test "help set print test-empty-doc-param" \
+ "^Set the current value of 'print test-empty-doc-param'\\."
+
+ gdb_test_multiline "None __doc__ parameter" \
+ "python" "" \
+ "class NoneDocParam(gdb.Parameter):" "" \
+ " __doc__ = None" "" \
+ " def __init__(self, name):" "" \
+ " super ().__init__(name, gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ " self.value = True" "" \
+ "test_none_doc_param = NoneDocParam('print test-none-doc-param')" ""\
+ "end"
+
+ # Setting the __doc__ string to None, or anything else that isn't
+ # a string, causes GDB to use a default string instead.
+ gdb_test "help set print test-none-doc-param" \
+ [multi_line \
+ "^Set the current value of 'print test-none-doc-param'\\." \
+ "This command is not documented\\."]
+}
+
+# Test a parameter in which the set_doc/show_doc strings are either
+# empty, or None.
+proc_with_prefix test_empty_set_show_doc_parameter {} {
+ gdb_test_multiline "empty set/show doc parameter" \
+ "python" "" \
+ "class EmptySetShowParam(gdb.Parameter):" "" \
+ " set_doc = \"\"" "" \
+ " show_doc = \"\"" "" \
+ " def __init__(self, name):" "" \
+ " super ().__init__(name, gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ " self.value = True" "" \
+ "test_empty_set_show_param = EmptySetShowParam('print test-empty-set-show-param')" ""\
+ "end"
+
+ # Setting the set_doc/show_doc string to empty means GDB will use
+ # a suitable default string.
+ gdb_test "help set print test-empty-set-show-param" \
+ [multi_line \
+ "^Set the current value of 'print test-empty-set-show-param'\\." \
+ "This command is not documented\\."]
+
+ gdb_test "help show print test-empty-set-show-param" \
+ [multi_line \
+ "^Show the current value of 'print test-empty-set-show-param'\\." \
+ "This command is not documented\\."]
+
+ gdb_test_multiline "None set/show doc parameter" \
+ "python" "" \
+ "class NoneSetShowParam(gdb.Parameter):" "" \
+ " set_doc = None" "" \
+ " show_doc = None" "" \
+ " def __init__(self, name):" "" \
+ " super ().__init__(name, gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ " self.value = True" "" \
+ "test_none_set_show_param = NoneSetShowParam('print test-none-set-show-param')" ""\
+ "end"
+
+ # Setting the set_doc/show_doc string to None (or any non-string
+ # value) means GDB will use a suitable default string.
+ gdb_test "help set print test-none-set-show-param" \
+ [multi_line \
+ "^Set the current value of 'print test-none-set-show-param'\\." \
+ "This command is not documented\\."]
+
+ gdb_test "help show print test-none-set-show-param" \
+ [multi_line \
+ "^Show the current value of 'print test-none-set-show-param'\\." \
+ "This command is not documented\\."]
+}
+
# Test deprecated API. Do not use in your own implementations.
proc_with_prefix test_deprecated_api_parameter { } {
clean_restart
@@ -669,6 +754,104 @@ proc_with_prefix test_ambiguous_parameter {} {
"Parameter .* is ambiguous.*Error occurred in Python.*"
gdb_test "python print(gdb.parameter('test-ambiguous-value-1a'))" \
"Could not find parameter.*Error occurred in Python.*"
+
+ # Create command prefixs 'set foo1' and 'show foo1'.
+ gdb_test_no_output "python gdb.Command('set foo1', gdb.COMMAND_NONE, prefix=True)"
+ gdb_test_no_output "python gdb.Command('show foo1', gdb.COMMAND_NONE, prefix=True)"
+
+ # Create a parameter under 'foo1', but use a truncated prefix. At
+ # this point though, the prefix is not ambiguous.
+ gdb_test_no_output "python gdb.Parameter('foo bar', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)"
+ gdb_test "python print(gdb.parameter('foo1 bar'))" "False"
+
+ # Create another prefix command, similar in name to the first.
+ gdb_test_no_output "python gdb.Command('set foo2', gdb.COMMAND_NONE, prefix=True)"
+ gdb_test_no_output "python gdb.Command('show foo2', gdb.COMMAND_NONE, prefix=True)"
+
+ # An attempt to create a parameter using an ambiguous prefix will give an error.
+ gdb_test "python gdb.Parameter('foo baz', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" \
+ [multi_line \
+ "Python Exception <class 'RuntimeError'>: Could not find command prefix foo\\." \
+ "Error occurred in Python: Could not find command prefix foo\\."]
+}
+
+# Check that creating a gdb.Parameter with an unknown command prefix results in an error.
+proc_with_prefix test_unknown_prefix {} {
+ gdb_test_multiline "create parameter" \
+ "python" "" \
+ "class UnknownPrefixParam(gdb.Parameter):" "" \
+ " def __init__ (self, name):" "" \
+ " super().__init__ (name, gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ " self.value = True" "" \
+ "end"
+
+ foreach prefix { "unknown-prefix" "style unknown-prefix" "style disassembler unknown-prefix"} {
+ gdb_test "python UnknownPrefixParam('$prefix new-param')" \
+ [multi_line \
+ "Python Exception <class 'RuntimeError'>: Could not find command prefix $prefix\\." \
+ "Error occurred in Python: Could not find command prefix $prefix\\."]
+ }
+}
+
+# Test the default behaviour of a set/show parameter prefix command.
+proc_with_prefix test_set_show_parameters {} {
+ # This first set/show prefix command doesn't have an invoke
+ # method. As such, GDB installs the default invoke behaviour; set
+ # prints the full list of sub-commands, and show prints all the
+ # sub-command values.
+ gdb_test_multiline "Setup set/show parameter prefix with no invoke" \
+ "python" "" \
+ "class TestParamPrefix(gdb.Command):" "" \
+ " \"\"\"TestParamPrefix documentation string.\"\"\"" "" \
+ " def __init__(self, name):" "" \
+ " super().__init__(name, gdb.COMMAND_NONE, prefix = True)" "" \
+ "TestParamPrefix('set test-prefix')" "" \
+ "TestParamPrefix('show test-prefix')" "" \
+ "gdb.Parameter('test-prefix param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ "gdb.Parameter('test-prefix param-2', gdb.COMMAND_NONE, gdb.PARAM_INTEGER)" "" \
+ "gdb.Parameter('test-prefix param-3', gdb.COMMAND_NONE, gdb.PARAM_STRING)" "" \
+ "end"
+
+ gdb_test "set test-prefix" \
+ [multi_line \
+ "List of \"set test-prefix\" subcommands:" \
+ "" \
+ "set test-prefix param-1 -- Set the current value of 'test-prefix param-1'." \
+ "set test-prefix param-2 -- Set the current value of 'test-prefix param-2'." \
+ "set test-prefix param-3 -- Set the current value of 'test-prefix param-3'." \
+ "" \
+ "Type \"help set test-prefix\" followed by subcommand name for full documentation\\." \
+ "Type \"apropos word\" to search for commands related to \"word\"\\." \
+ "Type \"apropos -v word\" for full documentation of commands related to \"word\"\\." \
+ "Command name abbreviations are allowed if unambiguous\\."]
+
+ gdb_test "show test-prefix" \
+ [multi_line \
+ "test-prefix param-1: The current value of 'test-prefix param-1' is \"off\"\\." \
+ "test-prefix param-2: The current value of 'test-prefix param-2' is \"0\"\\." \
+ "test-prefix param-3: The current value of 'test-prefix param-3' is \"\"\\."]
+
+ # This next set/show prefix has an invoke method, which will be
+ # called instead of the default behaviour tested above.
+ gdb_test_multiline "Setup set/show parameter prefix with invoke" \
+ "python" "" \
+ "class TestParamPrefix(gdb.Command):" "" \
+ " \"\"\"TestParamPrefix documentation string.\"\"\"" "" \
+ " def __init__(self, name, mode):" "" \
+ " self._mode = mode" "" \
+ " super().__init__(self._mode + ' ' + name, gdb.COMMAND_NONE, prefix = True)" "" \
+ " def invoke(self, args, from_tty):" "" \
+ " print('invoke -- ' + self._mode)" "" \
+ "TestParamPrefix('test-prefix-2', 'set')" "" \
+ "TestParamPrefix('test-prefix-2', 'show')" "" \
+ "gdb.Parameter('test-prefix-2 param-1', gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)" "" \
+ "gdb.Parameter('test-prefix-2 param-2', gdb.COMMAND_NONE, gdb.PARAM_INTEGER)" "" \
+ "gdb.Parameter('test-prefix-2 param-3', gdb.COMMAND_NONE, gdb.PARAM_STRING)" "" \
+ "end"
+
+ gdb_test "set test-prefix-2" "^invoke -- set"
+
+ gdb_test "show test-prefix-2" "^invoke -- show"
}
test_directories
@@ -679,11 +862,15 @@ test_color_parameter
test_file_parameter
test_undocumented_parameter
test_really_undocumented_parameter
+test_empty_doc_parameter
+test_empty_set_show_doc_parameter
test_deprecated_api_parameter
test_gdb_parameter
test_integer_parameter
test_throwing_parameter
test_language
test_ambiguous_parameter
+test_unknown_prefix
+test_set_show_parameters
rename py_param_test_maybe_no_output ""
diff --git a/gdb/testsuite/gdb.python/py-source-styling-2.exp b/gdb/testsuite/gdb.python/py-source-styling-2.exp
index b13ee1f..ebf7f32 100644
--- a/gdb/testsuite/gdb.python/py-source-styling-2.exp
+++ b/gdb/testsuite/gdb.python/py-source-styling-2.exp
@@ -32,7 +32,9 @@ if { [build_executable "failed to build" $testfile $srcfile $opts] == -1 } {
return
}
-clean_restart
+with_ansi_styling_terminal {
+ clean_restart
+}
gdb_test_no_output "maint set gnu-source-highlight enabled off"
@@ -40,16 +42,14 @@ gdb_load $binfile
require {gdb_py_module_available pygments}
-with_ansi_styling_terminal {
- gdb_test_no_output "set style enabled on"
-
- gdb_test_multiple "list $line_number" "Styling of c++ keyword try" {
- -re -wrap " try\r\n.*" {
- # Unstyled.
- fail $gdb_test_name
- }
- -re -wrap "" {
- pass $gdb_test_name
- }
+gdb_test_no_output "set style enabled on"
+
+gdb_test_multiple "list $line_number" "Styling of c++ keyword try" {
+ -re -wrap " try\r\n.*" {
+ # Unstyled.
+ fail $gdb_test_name
+ }
+ -re -wrap "" {
+ pass $gdb_test_name
}
}
diff --git a/gdb/testsuite/gdb.python/py-warning.exp b/gdb/testsuite/gdb.python/py-warning.exp
new file mode 100644
index 0000000..6b26a4e
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-warning.exp
@@ -0,0 +1,63 @@
+# Copyright (C) 2025 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 <http://www.gnu.org/licenses/>.
+
+# Test the gdb.warning() function.
+
+load_lib gdb-python.exp
+
+require allow_python_tests
+
+clean_restart
+
+# Basic usage.
+gdb_test "python gdb.warning(\"some text\")" \
+ "warning: some text"
+
+# Basic usage with named argument.
+gdb_test "python gdb.warning(text=\"a warning message\")" \
+ "warning: a warning message"
+
+# Make sure GDB prints format specifiers correctly.
+gdb_test "python gdb.warning(\"%s %d %p\")" \
+ "warning: %s %d %p"
+
+# Empty string gives an error.
+gdb_test "python gdb.warning(\"\")" \
+ [multi_line \
+ "Python Exception <class 'ValueError'>: Empty text string passed to gdb\\.warning" \
+ "Error occurred in Python: Empty text string passed to gdb\\.warning"]
+
+# Missing argument gives an error.
+set re1 \
+ [multi_line \
+ [string_to_regexp \
+ [concat \
+ "Python Exception <class 'TypeError'>:" \
+ "function missing required argument 'text' (pos 1)"]] \
+ [string_to_regexp \
+ [concat \
+ "Error occurred in Python:" \
+ "function missing required argument 'text' (pos 1)"]]]
+set re2 \
+ [multi_line \
+ [string_to_regexp \
+ [concat \
+ "Python Exception <class 'TypeError'>:" \
+ "Required argument 'text' (pos 1) not found"]] \
+ [string_to_regexp \
+ [concat \
+ "Error occurred in Python:" \
+ "Required argument 'text' (pos 1) not found"]]]
+gdb_test "python gdb.warning()" $re1|$re2
diff --git a/gdb/testsuite/gdb.replay/connect.exp b/gdb/testsuite/gdb.replay/connect.exp
index 5790d38..26b7aa3 100644
--- a/gdb/testsuite/gdb.replay/connect.exp
+++ b/gdb/testsuite/gdb.replay/connect.exp
@@ -13,7 +13,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
#
-# Starts a communication with gdbsever setting the remotelog file.
+# Starts a communication with gdbserver setting the remotelog file.
# Modifies the remotelog with update_log proc, injects an error message
# instead of the expected replay to the vMustReplyEmpty packet in order
# to test GDB reacts to the error response properly. After the remotelog
diff --git a/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp b/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp
index 0ff56dd..00f58f8 100644
--- a/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp
+++ b/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp
@@ -397,7 +397,7 @@ gdb_test_no_output "set \$ymm15.v2_int128 = {0x0, 0xcafeface}" "set ymm15 for vp
if {[record_full_function "vzeroupper"] == true} {
# Since vzeroupper needs to save 8 or 16 registers, let's check what was
# actually recorded, instead of just undoing an instruction. Only
- # really check the values of egisters 0, 1, 2 and 15 because those are
+ # really check the values of registers 0, 1, 2 and 15 because those are
# the only ones we're setting.
gdb_test "maint print record-instruction" \
[multi_line "Register ymm0h changed: 74565" \
diff --git a/gdb/testsuite/gdb.reverse/solib-precsave.exp b/gdb/testsuite/gdb.reverse/solib-precsave.exp
index 277e33c..82b08cd 100644
--- a/gdb/testsuite/gdb.reverse/solib-precsave.exp
+++ b/gdb/testsuite/gdb.reverse/solib-precsave.exp
@@ -140,7 +140,7 @@ gdb_test_multiple "reverse-step" "reverse-step into solib function one" {
pass $gdb_test_name
}
}
-# Depending on wether the closing } has a line associated, we might have
+# Depending on whether the closing } has a line associated, we might have
# different acceptable results here
gdb_test_multiple "reverse-step" "reverse-step within solib function one" {
-re -wrap "return y;.*" {
diff --git a/gdb/testsuite/gdb.reverse/solib-reverse.exp b/gdb/testsuite/gdb.reverse/solib-reverse.exp
index 1e22e91..b2ef9b0 100644
--- a/gdb/testsuite/gdb.reverse/solib-reverse.exp
+++ b/gdb/testsuite/gdb.reverse/solib-reverse.exp
@@ -116,7 +116,7 @@ gdb_test_multiple "reverse-step" "reverse-step into solib function one" {
pass $gdb_test_name
}
}
-# Depending on wether the closing } has a line associated, we might have
+# Depending on whether the closing } has a line associated, we might have
# different acceptable results here
gdb_test_multiple "reverse-step" "reverse-step within solib function one" {
-re -wrap "return y;.*" {
diff --git a/gdb/testsuite/gdb.rocm/code-object-load-while-breakpoint-hit.cpp b/gdb/testsuite/gdb.rocm/code-object-load-while-breakpoint-hit.cpp
new file mode 100644
index 0000000..d75bc76
--- /dev/null
+++ b/gdb/testsuite/gdb.rocm/code-object-load-while-breakpoint-hit.cpp
@@ -0,0 +1,86 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2025 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 <http://www.gnu.org/licenses/>. */
+
+#ifdef DEVICE
+
+#include <hip/hip_runtime.h>
+
+constexpr unsigned int NUM_BREAKPOINT_HITS = 5;
+
+static __device__ void
+break_here ()
+{
+}
+
+extern "C" __global__ void
+kernel ()
+{
+ for (int n = 0; n < NUM_BREAKPOINT_HITS; ++n)
+ break_here ();
+}
+
+#else
+
+#include <hip/hip_runtime.h>
+#include <unistd.h>
+
+constexpr unsigned int NUM_ITEMS_PER_BLOCK = 256;
+constexpr unsigned int NUM_BLOCKS = 128;
+constexpr unsigned int NUM_ITEMS = NUM_ITEMS_PER_BLOCK * NUM_BLOCKS;
+constexpr unsigned int NUM_LOAD_UNLOADS = 5;
+
+#define CHECK(cmd) \
+ { \
+ hipError_t error = cmd; \
+ if (error != hipSuccess) \
+ { \
+ fprintf (stderr, "error: '%s'(%d) at %s:%d\n", \
+ hipGetErrorString (error), error, __FILE__, __LINE__); \
+ exit (EXIT_FAILURE); \
+ } \
+ }
+
+int
+main (int argc, const char **argv)
+{
+ if (argc != 2)
+ {
+ fprintf (stderr, "Usage: %s <hip_module_path>\n", argv[0]);
+ return 1;
+ }
+
+ const auto module_path = argv[1];
+ hipModule_t module;
+ CHECK (hipModuleLoad (&module, module_path));
+
+ /* Launch the kernel. */
+ hipFunction_t function;
+ CHECK (hipModuleGetFunction (&function, module, "kernel"));
+ CHECK (hipModuleLaunchKernel (function, NUM_BLOCKS, 1, 1,
+ NUM_ITEMS_PER_BLOCK, 1, 1, 0, nullptr, nullptr,
+ nullptr));
+
+ /* Load and unload the module many times. */
+ for (int i = 0; i < NUM_LOAD_UNLOADS; ++i)
+ {
+ hipModule_t dummy_module;
+ CHECK (hipModuleLoad (&dummy_module, module_path));
+ CHECK (hipModuleUnload (dummy_module));
+ }
+}
+
+#endif
diff --git a/gdb/testsuite/gdb.rocm/code-object-load-while-breakpoint-hit.exp b/gdb/testsuite/gdb.rocm/code-object-load-while-breakpoint-hit.exp
new file mode 100644
index 0000000..3fe6a95
--- /dev/null
+++ b/gdb/testsuite/gdb.rocm/code-object-load-while-breakpoint-hit.exp
@@ -0,0 +1,68 @@
+# Copyright 2025 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# This test verifies what happens when a code object list update happens at the
+# same time as some wave stop events are reported. It was added following a
+# performance bug fix, where forward progress requirement disabled when
+# pulling events from amd-dbgapi in amd_dbgapi_target_breakpoint::check_status.
+#
+# The test launches a kernel that hits a breakpoint with an always false
+# condition a certain number of times. Meanwhile, the host loads and unloads
+# a code object in a loop, causing check_status to be called. The hope is that
+# check_status, when calling process_event_queue, will pull many WAVE_STOP
+# events from the kernel hitting the breakpoint.
+#
+# Without the appropriate fix (of disabling forward progress requirement in
+# check_status), GDB would hit the newly-added assert in process_event_queue,
+# which verifies that forward progress requirement is disabled. Even without
+# this assert, the test would likely time out (depending on the actual timeout
+# value).
+
+load_lib rocm.exp
+standard_testfile .cpp
+require allow_hipcc_tests
+
+# Build the host executable.
+if { [build_executable "failed to prepare" \
+ $testfile $srcfile {debug hip}] == -1 } {
+ return -1
+}
+
+set hipmodule_path [standard_output_file ${testfile}.co]
+
+# Build the kernel object file.
+if { [gdb_compile $srcdir/$subdir/$srcfile \
+ $hipmodule_path object \
+ { debug hip additional_flags=--genco additional_flags=-DDEVICE } ] != "" } {
+ return -1
+}
+
+proc do_test { } {
+ with_rocm_gpu_lock {
+ clean_restart $::binfile
+ gdb_test_no_output "set args $::hipmodule_path" "set args"
+
+ if { ![runto_main] } {
+ return
+ }
+
+ gdb_test "with breakpoint pending on -- break break_here if 0"
+ gdb_continue_to_end "continue to end" "continue" 1
+ }
+}
+
+do_test
diff --git a/gdb/testsuite/gdb.rocm/fork-exec-gpu-to-non-gpu.exp b/gdb/testsuite/gdb.rocm/fork-exec-gpu-to-non-gpu.exp
index 7588525..22d4b75 100644
--- a/gdb/testsuite/gdb.rocm/fork-exec-gpu-to-non-gpu.exp
+++ b/gdb/testsuite/gdb.rocm/fork-exec-gpu-to-non-gpu.exp
@@ -21,6 +21,7 @@
load_lib rocm.exp
require allow_hipcc_tests
+require allow_fork_tests
standard_testfile -execer.cpp -execee.cpp
diff --git a/gdb/testsuite/gdb.rocm/fork-exec-non-gpu-to-gpu.exp b/gdb/testsuite/gdb.rocm/fork-exec-non-gpu-to-gpu.exp
index a6bcf69..1386099 100644
--- a/gdb/testsuite/gdb.rocm/fork-exec-non-gpu-to-gpu.exp
+++ b/gdb/testsuite/gdb.rocm/fork-exec-non-gpu-to-gpu.exp
@@ -20,6 +20,7 @@
load_lib rocm.exp
require allow_hipcc_tests
+require allow_fork_tests
standard_testfile -execer.cpp -execee.cpp
diff --git a/gdb/testsuite/gdb.rocm/precise-memory-fork.exp b/gdb/testsuite/gdb.rocm/precise-memory-fork.exp
index d326c2e..23c1ebe 100644
--- a/gdb/testsuite/gdb.rocm/precise-memory-fork.exp
+++ b/gdb/testsuite/gdb.rocm/precise-memory-fork.exp
@@ -21,6 +21,7 @@
load_lib rocm.exp
require allow_hipcc_tests
+require allow_fork_tests
standard_testfile .c
diff --git a/gdb/testsuite/gdb.rocm/precise-memory.exp b/gdb/testsuite/gdb.rocm/precise-memory.exp
index fbcb451..6711d80 100644
--- a/gdb/testsuite/gdb.rocm/precise-memory.exp
+++ b/gdb/testsuite/gdb.rocm/precise-memory.exp
@@ -59,7 +59,7 @@ proc do_test { } {
return
}
- # Get to the begining of the GPU kernel without precise memory enabled.
+ # Get to the beginning of the GPU kernel without precise memory enabled.
with_test_prefix "goto gpu code" {
gdb_test_no_output "set amdgpu precise-memory off"
gdb_breakpoint "kernel" allow-pending
diff --git a/gdb/testsuite/gdb.server/build-id-seqno.exp b/gdb/testsuite/gdb.server/build-id-seqno.exp
index a508a44..8475ccc 100644
--- a/gdb/testsuite/gdb.server/build-id-seqno.exp
+++ b/gdb/testsuite/gdb.server/build-id-seqno.exp
@@ -90,13 +90,13 @@ 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
+ # targets uses the vFile:lstat 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.
+ # vFile:lstat packet.
foreach_with_prefix stat_pkt {auto off} {
clean_restart
@@ -105,7 +105,7 @@ proc load_binfile_check_debug_is_found { debuginfo_file testname } {
gdb_test_no_output "set sysroot target:"
- gdb_test "set remote hostio-stat-packet $stat_pkt"
+ gdb_test "set remote hostio-lstat-packet $stat_pkt"
# Make sure we're disconnected, in case we're testing with an
# extended-remote board, therefore already connected.
diff --git a/gdb/testsuite/gdb.server/fileio-packets.exp b/gdb/testsuite/gdb.server/fileio-packets.exp
new file mode 100644
index 0000000..9435efd
--- /dev/null
+++ b/gdb/testsuite/gdb.server/fileio-packets.exp
@@ -0,0 +1,66 @@
+# Copyright 2025 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 <http://www.gnu.org/licenses/>.
+
+# Test some remote file I/O. The associated Python script uses the
+# Python API to create and send vFile:* packets to gdbserver to
+# perform actions like 'stat'. The same action is then performed
+# directly from Python (e.g. a 'stat' is performed), and the results,
+# from gdbserver, and from the local syscall, are compared.
+
+load_lib gdb-python.exp
+load_lib gdbserver-support.exp
+
+require allow_python_tests
+require allow_gdbserver_tests
+require {!is_remote host}
+require {!is_remote target}
+
+standard_testfile
+
+clean_restart
+
+# Make sure we're disconnected, in case we're testing with an
+# extended-remote board, therefore already connected.
+gdb_test "disconnect" ".*"
+
+set pyfile [gdb_remote_download host ${srcdir}/${subdir}/${testfile}.py]
+gdb_test_no_output "source $pyfile" "source the script"
+
+# Start gdbserver, but always in extended-remote mode, and then
+# connect to it from GDB.
+set res [gdbserver_start "--multi --once" ""]
+set gdbserver_protocol "extended-remote"
+set gdbserver_gdbport [lindex $res 1]
+gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport
+
+gdb_test_no_output "set python print-stack full"
+
+set test_file_1 [standard_output_file "test_file_1"]
+remote_exec host "touch $test_file_1"
+
+set test_file_2 [standard_output_file "test_file_2"]
+remote_exec host "ln -s $test_file_1 $test_file_2"
+
+gdb_test "python check_lstat(\"$test_file_1\")" "PASS" \
+ "check remote lstat works on a normal file"
+
+gdb_test "python check_lstat(\"$test_file_2\")" "PASS" \
+ "check remote lstat works on a symbolic link"
+
+gdb_test "python check_stat(\"$test_file_1\")" "PASS" \
+ "check remote stat works on a normal file"
+
+gdb_test "python check_stat(\"$test_file_2\")" "PASS" \
+ "check remote stat works on a symbolic link"
diff --git a/gdb/testsuite/gdb.server/fileio-packets.py b/gdb/testsuite/gdb.server/fileio-packets.py
new file mode 100644
index 0000000..f132e91
--- /dev/null
+++ b/gdb/testsuite/gdb.server/fileio-packets.py
@@ -0,0 +1,208 @@
+# Copyright (C) 2025 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 <http://www.gnu.org/licenses/>.
+
+import os
+import stat
+
+
+# Hex encode INPUT_STRING in the same way that GDB does. Each
+# character in INPUT_STRING is expanded to its two digit hex
+# representation in the returned string.
+#
+# Only ASCII characters may appear in INPUT_STRING, this is more
+# restrictive than GDB, but is good enough for testing.
+def hex_encode(input_string):
+ byte_string = input_string.encode("ascii")
+ hex_string = byte_string.hex()
+ return hex_string
+
+
+# Binary remote data packets can contain some escaped bytes. Decode
+# the packet now.
+def unescape_remote_data(buf):
+ escaped = False
+ res = bytearray()
+ for b in buf:
+ if escaped:
+ res.append(b ^ 0x20)
+ escaped = False
+ elif b == ord("}"):
+ escaped = True
+ else:
+ res.append(b)
+ res = bytes(res)
+ return res
+
+
+# Decode the results of a remote stat like command from BUF. Returns
+# None if BUF is not a valid stat result (e.g. if it indicates an
+# error, or the buffer is too short). If BUF is valid then the fields
+# are decoded according to the GDB remote protocol and placed into a
+# dictionary, this dictionary is then returned.
+def decode_stat_reply(buf, byteorder="big"):
+
+ buf = unescape_remote_data(buf)
+
+ if (
+ buf[0] != ord("F")
+ or buf[1] != ord("4")
+ or buf[2] != ord("0")
+ or buf[3] != ord(";")
+ or len(buf) != 68
+ ):
+ l = len(buf)
+ print(f"decode_stat_reply failed: {buf}\t(length = {l})")
+ return None
+
+ # Discard the 'F40;' prefix. The rest is the 64 bytes of data to
+ # be decoded.
+ buf = buf[4:]
+
+ st_dev = int.from_bytes(buf[0:4], byteorder=byteorder)
+ st_ino = int.from_bytes(buf[4:8], byteorder=byteorder)
+ st_mode = int.from_bytes(buf[8:12], byteorder=byteorder)
+ st_nlink = int.from_bytes(buf[12:16], byteorder=byteorder)
+ st_uid = int.from_bytes(buf[16:20], byteorder=byteorder)
+ st_gid = int.from_bytes(buf[20:24], byteorder=byteorder)
+ st_rdev = int.from_bytes(buf[24:28], byteorder=byteorder)
+ st_size = int.from_bytes(buf[28:36], byteorder=byteorder)
+ st_blksize = int.from_bytes(buf[36:44], byteorder=byteorder)
+ st_blocks = int.from_bytes(buf[44:52], byteorder=byteorder)
+ st_atime = int.from_bytes(buf[52:56], byteorder=byteorder)
+ st_mtime = int.from_bytes(buf[56:60], byteorder=byteorder)
+ st_ctime = int.from_bytes(buf[60:64], byteorder=byteorder)
+
+ return {
+ "st_dev": st_dev,
+ "st_ino": st_ino,
+ "st_mode": st_mode,
+ "st_nlink": st_nlink,
+ "st_uid": st_uid,
+ "st_gid": st_gid,
+ "st_rdev": st_rdev,
+ "st_size": st_size,
+ "st_blksize": st_blksize,
+ "st_blocks": st_blocks,
+ "st_atime": st_atime,
+ "st_mtime": st_mtime,
+ "st_ctime": st_ctime,
+ }
+
+
+# Perform an lstat of remote file FILENAME, and create a dictionary of
+# the results, the keys are the fields of the stat structure.
+def remote_lstat(filename):
+ conn = gdb.selected_inferior().connection
+ if not isinstance(conn, gdb.RemoteTargetConnection):
+ raise gdb.GdbError("connection is the wrong type")
+
+ filename_hex = hex_encode(filename)
+ reply = conn.send_packet("vFile:lstat:%s" % filename_hex)
+
+ stat = decode_stat_reply(reply)
+ return stat
+
+
+# Perform a stat of remote file FILENAME, and create a dictionary of
+# the results, the keys are the fields of the stat structure.
+def remote_stat(filename):
+ conn = gdb.selected_inferior().connection
+ if not isinstance(conn, gdb.RemoteTargetConnection):
+ raise gdb.GdbError("connection is the wrong type")
+
+ filename_hex = hex_encode(filename)
+ reply = conn.send_packet("vFile:stat:%s" % filename_hex)
+
+ stat = decode_stat_reply(reply)
+ return stat
+
+
+# Convert a stat_result object to a dictionary that should match the
+# dictionary built from the remote protocol reply.
+def stat_result_to_dict(res):
+ # GDB doesn't support the S_IFLNK flag for the remote protocol, so
+ # clear that flag in the local results.
+ if stat.S_ISLNK(res.st_mode):
+ st_mode = stat.S_IMODE(res.st_mode)
+ else:
+ st_mode = res.st_mode
+
+ # GDB returns an integer for these fields, while Python returns a
+ # floating point value. Convert back to an integer to match GDB.
+ st_atime = int(res.st_atime)
+ st_mtime = int(res.st_mtime)
+ st_ctime = int(res.st_ctime)
+
+ return {
+ "st_dev": res.st_dev,
+ "st_ino": res.st_ino,
+ "st_mode": st_mode,
+ "st_nlink": res.st_nlink,
+ "st_uid": res.st_uid,
+ "st_gid": res.st_gid,
+ "st_rdev": res.st_rdev,
+ "st_size": res.st_size,
+ "st_blksize": res.st_blksize,
+ "st_blocks": res.st_blocks,
+ "st_atime": st_atime,
+ "st_mtime": st_mtime,
+ "st_ctime": st_ctime,
+ }
+
+
+# Perform an lstat of local file FILENAME, and create a dictionary of
+# the results, the keys are the fields of the stat structure.
+def local_lstat(filename):
+ res = os.lstat(filename)
+ return stat_result_to_dict(res)
+
+
+# Perform an lstat of local file FILENAME, and create a dictionary of
+# the results, the keys are the fields of the stat structure.
+def local_stat(filename):
+ res = os.stat(filename)
+ return stat_result_to_dict(res)
+
+
+# Perform a remote lstat using GDB, and a local lstat using os.lstat.
+# Compare the results to check they are the same.
+#
+# For this test to work correctly, gdbserver, and GDB (where this
+# Python script is running), must see the same filesystem.
+def check_lstat(filename):
+ s1 = remote_lstat(filename)
+ s2 = local_lstat(filename)
+
+ print(f"remote = {s1}")
+ print(f"local = {s2}")
+
+ assert s1 == s2
+ print("PASS")
+
+
+# Perform a remote stat using GDB, and a local stat using os.stat.
+# Compare the results to check they are the same.
+#
+# For this test to work correctly, gdbserver, and GDB (where this
+# Python script is running), must see the same filesystem.
+def check_stat(filename):
+ s1 = remote_stat(filename)
+ s2 = local_stat(filename)
+
+ print(f"remote = {s1}")
+ print(f"local = {s2}")
+
+ assert s1 == s2
+ print("PASS")
diff --git a/gdb/testsuite/gdb.server/pread-offset-size.S b/gdb/testsuite/gdb.server/pread-offset-size.S
new file mode 100644
index 0000000..6ca8cf0
--- /dev/null
+++ b/gdb/testsuite/gdb.server/pread-offset-size.S
@@ -0,0 +1,29 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2025 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 <http://www.gnu.org/licenses/>. */
+
+/* Here we are trying to create a large binary (> 2 GB),
+ 3742415472 bytes is about 3.5 gigabytes. */
+
+ .text
+ .globl _start
+_start:
+ .skip 3742415472
+ ret
+ .globl f
+ .type f, @function
+f:
+ ret
diff --git a/gdb/testsuite/gdb.server/pread-offset-size.exp b/gdb/testsuite/gdb.server/pread-offset-size.exp
new file mode 100644
index 0000000..54e67c5
--- /dev/null
+++ b/gdb/testsuite/gdb.server/pread-offset-size.exp
@@ -0,0 +1,49 @@
+# Copyright (C) 2025 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 <http://www.gnu.org/licenses/>.
+#
+# Check that GDBserver's vFile::pread implementation is able to access
+# large files (> 2GB).
+
+load_lib gdbserver-support.exp
+
+require allow_gdbserver_tests
+
+standard_testfile .S
+
+if { [prepare_for_testing ${testfile}.exp $testfile \
+ $srcfile {debug additional_flags=-nostdlib} ] } {
+ return -1
+}
+
+clean_restart
+
+gdb_test_no_output "set remote exec-file $binfile" \
+ "set remote exec-file"
+
+# Make sure we're disconnected, in case we're testing with an
+# extended-remote board, therefore already connected.
+gdb_test "disconnect" ".*"
+
+set res [gdbserver_spawn ""]
+set gdbserver_protocol [lindex $res 0]
+set gdbserver_gdbport [lindex $res 1]
+
+gdb_test "target $gdbserver_protocol $gdbserver_gdbport" \
+ "Remote debugging using .*" \
+ "target $gdbserver_protocol"
+
+# If loading the large binary was successful, we should be able to
+# place a breakpoint on f.
+gdb_test "break f" "Breakpoint 1.*"
diff --git a/gdb/testsuite/gdb.stabs/weird.def b/gdb/testsuite/gdb.stabs/weird.def
index 179b126..f809963 100644
--- a/gdb/testsuite/gdb.stabs/weird.def
+++ b/gdb/testsuite/gdb.stabs/weird.def
@@ -294,7 +294,7 @@ attr69:
# Using double quotes requires an escaping, as the stabs string
# is a double quote delimited string.
.stabs "constString2:c=s\"Double quote String2\"", N_LSYM,0,0, 0
-# Escaping sinlge quote with is easy
+# Escaping single quote with is easy
.stabs "constString3:c=s'String3 with embedded quote \' in the middle'", N_LSYM,0,0, 0
# Esaping double quotes is less clear...
.stabs "constString4:c=s\"String4 with embedded quote \\" in the middle\"", N_LSYM,0,0, 0
diff --git a/gdb/testsuite/gdb.testsuite/gdb_test_multiple-lbl.exp b/gdb/testsuite/gdb.testsuite/gdb_test_multiple-lbl.exp
new file mode 100644
index 0000000..a05ce61
--- /dev/null
+++ b/gdb/testsuite/gdb.testsuite/gdb_test_multiple-lbl.exp
@@ -0,0 +1,84 @@
+# Copyright 2025 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 <http://www.gnu.org/licenses/>.
+
+# Test gdb_test_multiple -lbl, particularly with patterns that share a
+# common prefix.
+
+standard_testfile
+
+clean_restart
+
+gdb_test_no_output "source ${srcdir}/${subdir}/$testfile.gdb" \
+ "source gdb test script"
+
+set saw_prompt 0
+set saw_prefix 0
+set saw_command 0
+set saw_prefix_foo 0
+set saw_prefix_bar 0
+
+# #1 - We need anchors so that the "prefix foo" pattern below does not
+# match when the expect output buffer contains:
+#
+# "\r\nprefix xxx\r\n\prefix foo\r\n"
+#
+# #2 - We need an anchor on the prompt match as otherwise the prompt
+# regexp would match:
+#
+# "\r\nmeant-to-be-matched-by-lbl-2\r\nprefix xxx\r\n(gdb) "
+#
+# This test would fail if -lbl did not force the built-in prompt match
+# regexp to have an anchor as well, as without it, the built-in prompt
+# regexp would have the exact same issue as #2 above.
+
+gdb_test_multiple "command" "" -lbl {
+ -re "^command(?=\r\n)" {
+ verbose -log <COMMAND>
+ incr saw_command
+ exp_continue
+ }
+ -re "^\r\nprefix foo(?=\r\n)" {
+ verbose -log <PREFIX-FOO>
+ incr saw_prefix_foo
+ exp_continue
+ }
+ -re "^\r\nprefix bar(?=\r\n)" {
+ verbose -log <PREFIX-BAR>
+ incr saw_prefix_bar
+ exp_continue
+ }
+ -re "^\r\nprefix \[^\r\n\]*(?=\r\n)" {
+ verbose -log <PREFIX>
+ incr saw_prefix
+ exp_continue
+ }
+ -re "^\r\n$gdb_prompt $" {
+ verbose -log <PROMPT>
+ incr saw_prompt
+ pass $gdb_test_name
+ }
+}
+
+verbose -log "saw_command: $saw_command"
+verbose -log "saw_prefix_foo: $saw_prefix_foo"
+verbose -log "saw_prefix_bar: $saw_prefix_bar"
+verbose -log "saw_prefix: $saw_prefix"
+verbose -log "saw_prompt: $saw_prompt"
+
+gdb_assert {$saw_command == 1}
+gdb_assert {$saw_prefix_foo == 1}
+gdb_assert {$saw_prefix_bar == 1}
+gdb_assert {$saw_prefix == 3}
+gdb_assert {$saw_prompt == 1}
diff --git a/gdb/testsuite/gdb.testsuite/gdb_test_multiple-lbl.gdb b/gdb/testsuite/gdb.testsuite/gdb_test_multiple-lbl.gdb
new file mode 100755
index 0000000..8c94dfa
--- /dev/null
+++ b/gdb/testsuite/gdb.testsuite/gdb_test_multiple-lbl.gdb
@@ -0,0 +1,25 @@
+# Copyright 2025 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 <http://www.gnu.org/licenses/>.
+
+define command
+ echo prefix xxx\n
+ echo meant-to-be-matched-by-lbl-1\n
+ echo prefix foo\n
+ echo prefix bar\n
+ echo meant-to-be-matched-by-lbl-2\n
+ echo prefix xxx\n
+ echo prefix xxx\n
+ echo meant-to-be-matched-by-lbl-3\n
+end
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 b41e3b2..fec31c3 100644
--- a/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.exp
+++ b/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.exp
@@ -74,42 +74,45 @@ proc test { non_stop } {
delete_breakpoints
# 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 would
- # fail because GDB is already connected to something, like
- # e.g. with --target_board=native-gdbserver:
- #
- # (gdb) kill
- # ...
- # (gdb) target remote localhost:2348
- # Already connected to a remote target. Disconnect? (y or n)
- #
- # Instead, start the inferior with no connection, and let
- # 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 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
- # the native-extended-gdbserver board enforces, or it would
- # run the inferior on the native target, which isn't what is
- # being tested.
- #
- # Since it's reload_on_run targets that need special care, we
- # default to reusing the connection on most targets.
- if [target_info exists gdb,do_reload_on_run] {
- gdb_test "add-inferior -no-connection" "New inferior 2.*"
- } else {
- gdb_test "add-inferior" "New inferior 2.*"
- }
- gdb_test "inferior 2" "Switching to inferior 2 .*"
-
- gdb_load $binfile
-
- if ![runto setup_done] {
- return -1
+ if {[allow_multi_inferior_tests]} {
+ 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 would
+ # fail because GDB is already connected to something, like
+ # e.g. with --target_board=native-gdbserver:
+ #
+ # (gdb) kill
+ # ...
+ # (gdb) target remote localhost:2348
+ # Already connected to a remote target. Disconnect? (y or n)
+ #
+ # Instead, start the inferior with no connection, and let
+ # 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 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 the
+ # native-extended-gdbserver board enforces, or it would
+ # run the inferior on the native target, which isn't what
+ # is being tested.
+ #
+ # Since it's reload_on_run targets that need special care,
+ # we default to reusing the connection on most targets.
+ if [target_info exists gdb,do_reload_on_run] {
+ gdb_test "add-inferior -no-connection" "New inferior 2.*"
+ } else {
+ gdb_test "add-inferior" "New inferior 2.*"
+ }
+ gdb_test "inferior 2" "Switching to inferior 2 .*"
+
+ gdb_load $binfile
+
+ if ![runto setup_done] {
+ return -1
+ }
}
}
@@ -158,13 +161,15 @@ proc test { non_stop } {
verbose -log "xxxxx: iteration $iter"
gdb_test -nopass "info threads"
- if {$inf == 1} {
- set inf 2
- } else {
- set inf 1
- }
+ if {[allow_multi_inferior_tests]} {
+ if {$inf == 1} {
+ set inf 2
+ } else {
+ set inf 1
+ }
- my_gdb_test "inferior $inf" ".*" "inferior $inf"
+ my_gdb_test "inferior $inf" ".*" "inferior $inf"
+ }
my_gdb_test "print global_var = 555" " = 555" \
"write to global_var"
diff --git a/gdb/testsuite/gdb.threads/current-lwp-dead.exp b/gdb/testsuite/gdb.threads/current-lwp-dead.exp
index 7aa7ab9..c8364df 100644
--- a/gdb/testsuite/gdb.threads/current-lwp-dead.exp
+++ b/gdb/testsuite/gdb.threads/current-lwp-dead.exp
@@ -47,6 +47,6 @@ gdb_breakpoint $line
gdb_continue_to_breakpoint "fn_return" ".*at-fn_return.*"
# Confirm thread 2 is really gone.
-gdb_test "info threads 2" "No threads match '2'\\."
+gdb_test "info threads 2" "No threads matched\\."
gdb_continue_to_end "" continue 1
diff --git a/gdb/testsuite/gdb.threads/detach-step-over.exp b/gdb/testsuite/gdb.threads/detach-step-over.exp
index e48b83c..8a1cb29 100644
--- a/gdb/testsuite/gdb.threads/detach-step-over.exp
+++ b/gdb/testsuite/gdb.threads/detach-step-over.exp
@@ -50,6 +50,8 @@
require can_spawn_for_attach
+require allow_multi_inferior_tests
+
standard_testfile
set bp_lineno [gdb_get_line_number "Set breakpoint here"]
diff --git a/gdb/testsuite/gdb.threads/foll-fork-other-thread.exp b/gdb/testsuite/gdb.threads/foll-fork-other-thread.exp
index 5245988..8ab540c 100644
--- a/gdb/testsuite/gdb.threads/foll-fork-other-thread.exp
+++ b/gdb/testsuite/gdb.threads/foll-fork-other-thread.exp
@@ -17,6 +17,8 @@
# another thread, in different combinations of "set follow-fork
# parent/child", and other execution modes.
+require allow_fork_tests
+
standard_testfile
# Line where to stop the main thread.
diff --git a/gdb/testsuite/gdb.threads/fork-child-threads.exp b/gdb/testsuite/gdb.threads/fork-child-threads.exp
index abe9769..ba9dfc2 100644
--- a/gdb/testsuite/gdb.threads/fork-child-threads.exp
+++ b/gdb/testsuite/gdb.threads/fork-child-threads.exp
@@ -13,10 +13,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-# Only GNU/Linux is known to support `set follow-fork-mode child'.
-if { ! [istarget "*-*-linux*"] } {
- return 0
-}
+require allow_fork_tests
standard_testfile
diff --git a/gdb/testsuite/gdb.threads/fork-plus-threads.exp b/gdb/testsuite/gdb.threads/fork-plus-threads.exp
index 3a5e66a..4ce88d3 100644
--- a/gdb/testsuite/gdb.threads/fork-plus-threads.exp
+++ b/gdb/testsuite/gdb.threads/fork-plus-threads.exp
@@ -20,6 +20,8 @@
#
# See https://sourceware.org/bugzilla/show_bug.cgi?id=18600
+require allow_fork_tests
+
# In remote mode, we cannot continue debugging after all
# inferiors have terminated, and this test requires that.
if { [target_info exists gdb_protocol]
diff --git a/gdb/testsuite/gdb.threads/fork-thread-pending.exp b/gdb/testsuite/gdb.threads/fork-thread-pending.exp
index d0a1ca1..538e1ca 100644
--- a/gdb/testsuite/gdb.threads/fork-thread-pending.exp
+++ b/gdb/testsuite/gdb.threads/fork-thread-pending.exp
@@ -13,11 +13,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-# Only GNU/Linux is known to support `set follow-fork-mode child'.
-#
-if { ! [istarget "*-*-linux*"] } {
- return 0
-}
+require allow_fork_tests
standard_testfile
diff --git a/gdb/testsuite/gdb.threads/forking-threads-plus-breakpoint.exp b/gdb/testsuite/gdb.threads/forking-threads-plus-breakpoint.exp
index 1f76898..c668a65 100644
--- a/gdb/testsuite/gdb.threads/forking-threads-plus-breakpoint.exp
+++ b/gdb/testsuite/gdb.threads/forking-threads-plus-breakpoint.exp
@@ -16,6 +16,8 @@
# This test verifies that several threads forking while another thread
# is constantly stepping over a breakpoint is properly handled.
+require allow_fork_tests
+
standard_testfile
set linenum [gdb_get_line_number "set break here"]
diff --git a/gdb/testsuite/gdb.threads/info-threads-options.c b/gdb/testsuite/gdb.threads/info-threads-options.c
new file mode 100644
index 0000000..2c4cd85
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/info-threads-options.c
@@ -0,0 +1,77 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2022-2025 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 <http://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+#define NUM 4
+
+static pthread_barrier_t threads_started_barrier;
+
+static void
+stop_here ()
+{
+}
+
+static void
+spin ()
+{
+ while (1)
+ usleep (1);
+}
+
+static void *
+work (void *arg)
+{
+ int id = *(int *) arg;
+
+ pthread_barrier_wait (&threads_started_barrier);
+
+ if (id % 2 == 0)
+ stop_here ();
+ else
+ spin ();
+
+ pthread_exit (NULL);
+}
+
+int
+main ()
+{
+ /* Ensure we stop if GDB crashes and DejaGNU fails to kill us. */
+ alarm (10);
+
+ pthread_t threads[NUM];
+ int ids[NUM];
+
+ pthread_barrier_init (&threads_started_barrier, NULL, NUM + 1);
+
+ for (int i = 0; i < NUM; i++)
+ {
+ ids[i] = i;
+ pthread_create (&threads[i], NULL, work, &ids[i]);
+ }
+
+ /* Wait until all threads are seen running. */
+ pthread_barrier_wait (&threads_started_barrier);
+
+ stop_here ();
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.threads/info-threads-options.exp b/gdb/testsuite/gdb.threads/info-threads-options.exp
new file mode 100644
index 0000000..38e4e67
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/info-threads-options.exp
@@ -0,0 +1,131 @@
+# Copyright (C) 2022-2025 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 <http://www.gnu.org/licenses/>.
+
+# Test the filter flags of the "info threads" command.
+
+standard_testfile
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
+ executable debug] != "" } {
+ return -1
+}
+
+save_vars { GDBFLAGS } {
+ append GDBFLAGS " -ex \"set non-stop on\""
+ clean_restart $binfile
+}
+
+if ![runto_main] {
+ return -1
+}
+
+gdb_breakpoint "stop_here"
+gdb_test_multiple "continue -a&" "" {
+ -re "Continuing.\r\n$gdb_prompt " {
+ pass $gdb_test_name
+ }
+}
+
+set expected_hits 3
+set fill "\[^\r\n\]+"
+set num_hits 0
+gdb_test_multiple "" "hit the breakpoint" -lbl {
+ -re "\r\nThread ${fill} hit Breakpoint ${decimal}," {
+ incr num_hits
+ if {$num_hits < $expected_hits} {
+ exp_continue
+ }
+ }
+}
+gdb_assert {$num_hits == $expected_hits} "expected threads hit the bp"
+
+# Count the number of running/stopped threads reported
+# by the "info threads" command. We also capture thread ids
+# for additional tests.
+set running_tid "invalid"
+set stopped_tid "invalid"
+
+set eol "(?=\r\n)"
+
+foreach_with_prefix flag {"" "-running" "-stopped" "-running -stopped"} {
+ set num_running 0
+ set num_stopped 0
+ gdb_test_multiple "info threads $flag" "info threads $flag" -lbl {
+ -re "Id${fill}Target Id${fill}Frame${fill}${eol}" {
+ exp_continue
+ }
+ -re "^\r\n. (${decimal})${fill}Thread ${fill}.running.${eol}" {
+ incr num_running
+ set running_tid $expect_out(1,string)
+ exp_continue
+ }
+ -re "^\r\n. (${decimal})${fill}Thread ${fill}stop_here ${fill}${eol}" {
+ incr num_stopped
+ set stopped_tid $expect_out(1,string)
+ exp_continue
+ }
+ -re "^\r\n$gdb_prompt $" {
+ pass $gdb_test_name
+ }
+ }
+
+ if {$flag eq "-running"} {
+ gdb_assert {$num_running == 2} "num running"
+ gdb_assert {$num_stopped == 0} "num stopped"
+ } elseif {$flag eq "-stopped"} {
+ gdb_assert {$num_running == 0} "num running"
+ gdb_assert {$num_stopped == 3} "num stopped"
+ } else {
+ gdb_assert {$num_running == 2} "num running"
+ gdb_assert {$num_stopped == 3} "num stopped"
+ }
+}
+
+verbose -log "running_tid=$running_tid, stopped_tid=$stopped_tid"
+
+# Test specifying thread ids.
+gdb_test "info threads -running $stopped_tid" \
+ "No threads matched\\." \
+ "info thread -running for a stopped thread"
+gdb_test "info threads -stopped $running_tid" \
+ "No threads matched\\." \
+ "info thread -stopped for a running thread"
+
+set ws "\[ \t\]+"
+foreach tid "\"$running_tid\" \"$running_tid $stopped_tid\"" {
+ gdb_test "info threads -running $tid" \
+ [multi_line \
+ "${ws}Id${ws}Target Id${ws}Frame${ws}" \
+ "${ws}${running_tid}${ws}Thread ${fill}.running."] \
+ "info thread -running with [llength $tid] thread ids"
+}
+
+foreach tid "\"$stopped_tid\" \"$stopped_tid $running_tid\"" {
+ gdb_test "info threads -stopped $tid" \
+ [multi_line \
+ "${ws}Id${ws}Target Id${ws}Frame${ws}" \
+ "${ws}${stopped_tid}${ws}Thread ${fill} stop_here ${fill}"] \
+ "info thread -stopped with [llength $tid] thread ids"
+}
+
+gdb_test_multiple "info threads -stopped -running $stopped_tid $running_tid" \
+ "filter flags and tids combined" {
+ -re -wrap ".*stop_here.*running.*" {
+ pass $gdb_test_name
+ }
+ -re -wrap ".*running.*stop_here.*" {
+ pass $gdb_test_name
+ }
+}
diff --git a/gdb/testsuite/gdb.threads/next-fork-exec-other-thread.exp b/gdb/testsuite/gdb.threads/next-fork-exec-other-thread.exp
index bd81438..3a97127 100644
--- a/gdb/testsuite/gdb.threads/next-fork-exec-other-thread.exp
+++ b/gdb/testsuite/gdb.threads/next-fork-exec-other-thread.exp
@@ -25,6 +25,8 @@
# 20.04.5 LTS with 32-bit kernel + 32-bit userland. It was NOT reproducible
# using a circa 2023 Raspberry Pi OS w/ 64-bit kernel and 32-bit userland.
+require allow_fork_tests
+
standard_testfile
# Line where to stop the main thread.
diff --git a/gdb/testsuite/gdb.threads/next-fork-other-thread.exp b/gdb/testsuite/gdb.threads/next-fork-other-thread.exp
index 183fda6..1cd6685 100644
--- a/gdb/testsuite/gdb.threads/next-fork-other-thread.exp
+++ b/gdb/testsuite/gdb.threads/next-fork-other-thread.exp
@@ -16,6 +16,8 @@
# Test doing a "next" on a thread during which forks or vforks happen in other
# threads.
+require allow_fork_tests
+
standard_testfile
# Line where to stop the main thread.
diff --git a/gdb/testsuite/gdb.threads/pending-fork-event-detach-ns.exp b/gdb/testsuite/gdb.threads/pending-fork-event-detach-ns.exp
index e6e311e..29a011e 100644
--- a/gdb/testsuite/gdb.threads/pending-fork-event-detach-ns.exp
+++ b/gdb/testsuite/gdb.threads/pending-fork-event-detach-ns.exp
@@ -29,6 +29,8 @@
# parent thread from waitpid'ing it, preventing the main thread from joining
# it, prevent it from writing the flag file, failing the test.
+require allow_fork_tests
+
standard_testfile
if { [is_remote target] } {
diff --git a/gdb/testsuite/gdb.threads/pending-fork-event-detach.exp b/gdb/testsuite/gdb.threads/pending-fork-event-detach.exp
index 8e77ab0..e627241 100644
--- a/gdb/testsuite/gdb.threads/pending-fork-event-detach.exp
+++ b/gdb/testsuite/gdb.threads/pending-fork-event-detach.exp
@@ -34,6 +34,8 @@
# event, and erroneously create a new inferior for it. Once fixed, the child
# process' thread is hidden by whoever holds the pending fork event.
+require allow_fork_tests
+
standard_testfile .c -touch-file.c
set touch_file_bin $binfile-touch-file
diff --git a/gdb/testsuite/gdb.threads/thread-bp-deleted.exp b/gdb/testsuite/gdb.threads/thread-bp-deleted.exp
index 2eadd38..8cabb70 100644
--- a/gdb/testsuite/gdb.threads/thread-bp-deleted.exp
+++ b/gdb/testsuite/gdb.threads/thread-bp-deleted.exp
@@ -147,7 +147,7 @@ if {$is_remote} {
exp_continue
}
- -re "No threads match '99'\\.\r\n$gdb_prompt $" {
+ -re "No threads matched\\.\r\n$gdb_prompt $" {
if {!$saw_thread_exited && !$saw_bp_deleted && $attempt_count > 0} {
sleep 1
incr attempt_count -1
diff --git a/gdb/testsuite/gdb.threads/thread-execl.c b/gdb/testsuite/gdb.threads/thread-execl.c
index 403aa31..2d312d4 100644
--- a/gdb/testsuite/gdb.threads/thread-execl.c
+++ b/gdb/testsuite/gdb.threads/thread-execl.c
@@ -25,8 +25,9 @@ static const char *image;
void *
thread_execler (void *arg)
{
- /* Exec ourselves again. */
- if (execl (image, image, NULL) == -1)
+ /* Exec ourselves again. Pass an extra argument so that the
+ post-exec image knows to not re-exec yet again. */
+ if (execl (image, image, "1", NULL) == -1)
{
perror ("execl");
abort ();
@@ -40,6 +41,11 @@ main (int argc, char **argv)
{
pthread_t thread;
+ /* An extra argument means we're in the post-exec image, so we're
+ done. Don't re-exec again. */
+ if (argc > 1)
+ exit (0);
+
image = argv[0];
pthread_create (&thread, NULL, thread_execler, NULL);
diff --git a/gdb/testsuite/gdb.threads/threadapply.exp b/gdb/testsuite/gdb.threads/threadapply.exp
index c53db79..9110617 100644
--- a/gdb/testsuite/gdb.threads/threadapply.exp
+++ b/gdb/testsuite/gdb.threads/threadapply.exp
@@ -224,6 +224,8 @@ proc kill_and_remove_inferior {thread_set} {
# Test both "all" and a thread list, because those are implemented as
# different commands in GDB.
-foreach_with_prefix thread_set {"all" "1.1"} {
- kill_and_remove_inferior $thread_set
+if {[allow_multi_inferior_tests]} {
+ foreach_with_prefix thread_set {"all" "1.1"} {
+ kill_and_remove_inferior $thread_set
+ }
}
diff --git a/gdb/testsuite/gdb.threads/vfork-follow-child-exec.exp b/gdb/testsuite/gdb.threads/vfork-follow-child-exec.exp
index e23db0a..0b95a75 100644
--- a/gdb/testsuite/gdb.threads/vfork-follow-child-exec.exp
+++ b/gdb/testsuite/gdb.threads/vfork-follow-child-exec.exp
@@ -16,6 +16,8 @@
# Test following a vfork child that execs, when the vfork parent is a
# threaded program, and it's a non-main thread that vforks.
+require allow_fork_tests
+
standard_testfile
if {[build_executable "failed to prepare" $testfile $srcfile {debug pthreads}]} {
diff --git a/gdb/testsuite/gdb.threads/vfork-follow-child-exit.exp b/gdb/testsuite/gdb.threads/vfork-follow-child-exit.exp
index a6b7f49..ced52df 100644
--- a/gdb/testsuite/gdb.threads/vfork-follow-child-exit.exp
+++ b/gdb/testsuite/gdb.threads/vfork-follow-child-exit.exp
@@ -16,6 +16,8 @@
# Test following a vfork child that exits, when the vfork parent is a
# threaded program, and it's a non-main thread that vforks.
+require allow_fork_tests
+
standard_testfile
if {[build_executable "failed to prepare" $testfile $srcfile {debug pthreads}]} {
diff --git a/gdb/testsuite/gdb.threads/vfork-multi-inferior.exp b/gdb/testsuite/gdb.threads/vfork-multi-inferior.exp
index fd081b3..1f87427 100644
--- a/gdb/testsuite/gdb.threads/vfork-multi-inferior.exp
+++ b/gdb/testsuite/gdb.threads/vfork-multi-inferior.exp
@@ -25,6 +25,10 @@
# To catch the bug, this test verifies that we can hit a breakpoint after a
# vfork call, while a second inferior runs in the background.
+require allow_fork_tests
+
+require allow_multi_inferior_tests
+
require !use_gdb_stub
standard_testfile .c -sleep.c
diff --git a/gdb/testsuite/gdb.threads/vfork-multi-thread.exp b/gdb/testsuite/gdb.threads/vfork-multi-thread.exp
index 2b9294d..61811ae 100644
--- a/gdb/testsuite/gdb.threads/vfork-multi-thread.exp
+++ b/gdb/testsuite/gdb.threads/vfork-multi-thread.exp
@@ -30,6 +30,8 @@
# breakpoints are removed, so the main thread would miss the breakpoint and run
# until exit.
+require allow_fork_tests
+
standard_testfile
if { [build_executable "failed to prepare" ${testfile} ${srcfile} {debug pthreads}] } {
diff --git a/gdb/testsuite/gdb.threads/watchpoint-fork.exp b/gdb/testsuite/gdb.threads/watchpoint-fork.exp
index 376ca2a..8e9b1c3 100644
--- a/gdb/testsuite/gdb.threads/watchpoint-fork.exp
+++ b/gdb/testsuite/gdb.threads/watchpoint-fork.exp
@@ -21,6 +21,8 @@
# must be done before starting the test so as to not disrupt the execution
# of the actual test.
+require allow_fork_tests
+
set allow_hw_watchpoint_tests_p [allow_hw_watchpoint_tests]
set testfile watchpoint-fork
diff --git a/gdb/testsuite/gdb.trace/tspeed.exp b/gdb/testsuite/gdb.trace/tspeed.exp
index 25862bf..be7f37e 100644
--- a/gdb/testsuite/gdb.trace/tspeed.exp
+++ b/gdb/testsuite/gdb.trace/tspeed.exp
@@ -17,7 +17,7 @@ load_lib "trace-support.exp"
require allow_shlib_tests
-# Do not run if gdbsever debug is enabled - the output file is many Gb.
+# Do not run if gdbserver debug is enabled - the output file is many Gb.
if [gdbserver_debug_enabled] {
return 0
}
diff --git a/gdb/testsuite/gdb.tui/pr30056.exp b/gdb/testsuite/gdb.tui/pr30056.exp
index 1123593..3403033 100644
--- a/gdb/testsuite/gdb.tui/pr30056.exp
+++ b/gdb/testsuite/gdb.tui/pr30056.exp
@@ -76,12 +76,12 @@ save_vars { env(LC_ALL) } {
# open about this.
kfail cli/30498 $test
- # At this point we don't have a reponsive prompt. Send ^G to abort
+ # At this point we don't have a responsive prompt. Send ^G to abort
# the i-search.
send_gdb "\007"
}
- # We need a reponsive prompt here, to deal with the "monitor exit"
+ # We need a responsive prompt here, to deal with the "monitor exit"
# that native-extended-gdbserver will send. Check that we have a
# responsive prompt.
Term::command "echo \\n"
diff --git a/gdb/testsuite/gdb.tui/tui-focus.exp b/gdb/testsuite/gdb.tui/tui-focus.exp
index 4c9d2a0..26e5060 100644
--- a/gdb/testsuite/gdb.tui/tui-focus.exp
+++ b/gdb/testsuite/gdb.tui/tui-focus.exp
@@ -73,7 +73,7 @@ foreach spec {{src true} {cmd true} {status true} {regs false} \
}
}
-# Use the Python TUI API to exercise some of the ambigous window name
+# Use the Python TUI API to exercise some of the ambiguous window name
# handling parts of the 'focus' command.
Term::clean_restart 24 80 $binfile
if {[allow_python_tests]} {
diff --git a/gdb/testsuite/gdb.xml/bad-include.xml b/gdb/testsuite/gdb.xml/bad-include.xml
index f7a2b72..cd9cce3 100644
--- a/gdb/testsuite/gdb.xml/bad-include.xml
+++ b/gdb/testsuite/gdb.xml/bad-include.xml
@@ -1 +1 @@
-<xi:include href="nonexistant.xml"/>
+<xi:include href="nonexistent.xml"/>
diff --git a/gdb/testsuite/gdb.xml/tdesc-xinclude.exp b/gdb/testsuite/gdb.xml/tdesc-xinclude.exp
index 885d217..b934c80 100644
--- a/gdb/testsuite/gdb.xml/tdesc-xinclude.exp
+++ b/gdb/testsuite/gdb.xml/tdesc-xinclude.exp
@@ -43,7 +43,7 @@ set_arch "includes.xml" \
# This file contains a missing include. We should warn the user about
# it.
set_arch "bad-include.xml" \
- "warning:.*Could not load XML document \"nonexistant.xml\"$common_warn"
+ "warning:.*Could not load XML document \"nonexistent.xml\"$common_warn"
# Make sure we detect infinite loops, eventually.
set_arch "loop.xml" \
diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp
index b347437..3a182c2 100644
--- a/gdb/testsuite/lib/dwarf.exp
+++ b/gdb/testsuite/lib/dwarf.exp
@@ -1072,7 +1072,10 @@ namespace eval Dwarf {
}
proc _section {name {flags ""} {type ""}} {
- if {$flags == "" && $type == ""} {
+ if {$name == ".debug_str"} {
+ # Hard-code this because it's always desirable.
+ _emit " .section $name, \"MS\", %progbits, 1"
+ } elseif {$flags == "" && $type == ""} {
_emit " .section $name"
} elseif {$type == ""} {
_emit " .section $name, \"$flags\""
@@ -3398,9 +3401,24 @@ namespace eval Dwarf {
# Add the strings in ARGS to the .debug_str section, and create a
# .debug_str_offsets section pointing to those strings.
- # BASE_OFFSET is the label for DW_AT_str_offsets_base.
- proc debug_str_offsets { base_offset args } {
- _section .debug_str
+ # Current options are:
+ # dwo 0|1 - boolean indicating if the sections have the dwo suffix.
+ # default = 0 (no .dwo suffix)
+ # base_offset label
+ # - generate label, to be used in DW_AT_str_offsets_base.
+ # default = "" (don't generate a label).
+ proc debug_str_offsets { options args } {
+ parse_options {
+ { dwo 0 }
+ { base_offset "" }
+ }
+
+ if { $dwo } {
+ _section .debug_str.dwo
+ } else {
+ _section .debug_str
+ }
+
set num 0
foreach arg $args {
set str_label [_compute_label "str_${num}"]
@@ -3412,12 +3430,18 @@ namespace eval Dwarf {
declare_labels debug_str_offsets_start debug_str_offsets_end
set initial_length "$debug_str_offsets_end - $debug_str_offsets_start"
- _section .debug_str_offsets
+ if { $dwo } {
+ _section .debug_str_offsets.dwo
+ } else {
+ _section .debug_str_offsets
+ }
_op .4byte $initial_length "Initial_length"
debug_str_offsets_start:
_op .2byte 0x5 "version"
_op .2byte 0x0 "padding"
- $base_offset:
+ if { $base_offset != "" } {
+ $base_offset:
+ }
set num 0
foreach arg $args {
set str_label [_compute_label "str_${num}"]
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 2a5d37c..777d64d 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -269,6 +269,13 @@ if ![info exists INTERNAL_GDBFLAGS] {
}
set INTERNAL_GDBFLAGS [append_gdb_data_directory_option $INTERNAL_GDBFLAGS]
+
+ # Handle the case that "interactive-mode auto" reports off.
+ append INTERNAL_GDBFLAGS { -iex "set interactive-mode on"}
+
+ if { [ishost "*-*-mingw*"] } {
+ append INTERNAL_GDBFLAGS { -iex "maint set console-translation-mode binary"}
+ }
}
# The variable gdb_prompt is a regexp which matches the gdb prompt.
@@ -1026,7 +1033,10 @@ proc command_to_message { command } {
# 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.
+# -lbl specifies that line-by-line matching will be used. This means
+# that lines from GDB not matched by any pattern will be consumed from
+# the output buffer. This helps avoid buffer overflows and timeouts
+# when testing verbose commands.
# EXPECT_ARGUMENTS will be fed to expect in addition to the standard
# patterns. Pattern elements will be evaluated in the caller's
# context; action elements will be executed in the caller's context.
@@ -1124,6 +1134,7 @@ proc gdb_test_multiple { command message args } {
global any_spawn_id
set line_by_line 0
+ set lbl_anchor_re ""
set prompt_regexp ""
set prompt_anchor 1
for {set i 0} {$i < [llength $args]} {incr i} {
@@ -1133,6 +1144,7 @@ proc gdb_test_multiple { command message args } {
set prompt_regexp [lindex $args $i]
} elseif { $arg == "-lbl" } {
set line_by_line 1
+ set lbl_anchor_re "^"
} elseif { $arg == "-no-prompt-anchor" } {
set prompt_anchor 0
} else {
@@ -1391,7 +1403,7 @@ proc gdb_test_multiple { command message args } {
fail "$errmsg"
set result -1
}
- -re "\r\n$prompt_regexp" {
+ -re "${lbl_anchor_re}\r\n$prompt_regexp" {
if {![string match "" $message]} {
fail "$message"
}
@@ -2301,7 +2313,8 @@ proc default_gdb_exit {} {
}
}
- if { [is_remote host] && [board_info host exists fileid] } {
+ if { ([is_remote host] && [board_info host exists fileid])
+ || [istarget *-*-mingw*] } {
send_gdb "quit\n"
gdb_expect 10 {
-re "y or n" {
@@ -2314,7 +2327,9 @@ proc default_gdb_exit {} {
}
if ![is_remote host] {
- remote_close host
+ if {[catch { remote_close host } message]} {
+ warning "closing gdb failed with: $message"
+ }
}
unset gdb_spawn_id
unset ::gdb_tty_name
@@ -2577,6 +2592,17 @@ proc default_gdb_start { } {
# Output with -q, and bracketed paste mode enabled, see above.
verbose "GDB initialized."
}
+ -re "^\033\\\[6n$gdb_prompt $" {
+ # With MSYS2 and TERM={xterm,ansi}, I get:
+ #
+ # builtin_spawn gdb -q ...
+ # ^[[6n(gdb)
+ #
+ # We set TERM to dumb by default to avoid this, but some
+ # test-cases set TERM to xterm or ansi, in which case we get this
+ # output.
+ verbose "GDB initialized."
+ }
-re "$gdb_prompt $" {
perror "GDB never initialized."
unset gdb_spawn_id
@@ -5087,6 +5113,40 @@ proc skip_inline_var_tests {} {
return 0
}
+# Return whether we allow running fork-related testcases. Targets
+# that don't even have any concept of fork will just fail to compile
+# the testcases and skip the tests that way if this returns true for
+# them. Unix targets that do have a fork system call, but don't
+# support intercepting forks will want to return false here, otherwise
+# the testcases that exercise fork may hit a number of long cascading
+# time out sequences.
+
+proc allow_fork_tests {} {
+ if {[istarget "*-*-cygwin*"] || [istarget "*-*-mingw*"]} {
+ return 0
+ }
+
+ return 1
+}
+
+# Return whether we allow running testcases that want to debug
+# multiple inferiors with the same target. Not all targets support
+# this. Note that some tests add a second inferior but never start
+# it. Those tests should not be skipped due to this proc returning
+# false.
+
+proc allow_multi_inferior_tests {} {
+ if {[istarget "*-*-cygwin*"] || [istarget "*-*-mingw*"]} {
+ return 0
+ }
+
+ if {[use_gdb_stub]} {
+ return 0
+ }
+
+ return 1
+}
+
# Return a 1 if we should run tests that require hardware breakpoints
proc allow_hw_breakpoint_tests {} {
@@ -6920,7 +6980,7 @@ proc kill_wait_spawned_process { proc_spawn_id } {
proc spawn_id_get_pid { spawn_id } {
set testpid [exp_pid -i $spawn_id]
- if { [istarget "*-*-cygwin*"] } {
+ if { [istarget "*-*-cygwin*"] || [istarget "*-*-mingw*"] } {
# testpid is the Cygwin PID, GDB uses the Windows PID, which
# might be different due to the way fork/exec works.
set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
@@ -7489,6 +7549,22 @@ proc default_gdb_init { test_file_name } {
setenv LC_CTYPE C
setenv LANG C
+ # With MSYS2 and TERM={xterm,ansi}, I get:
+ #
+ # builtin_spawn gdb -q ...
+ # ^[[6n(gdb)
+ #
+ # While we're addressing this in default_gdb_start, this is not specific
+ # to gdb, other tools produce the same CSI sequence, and consequently we
+ # run into trouble in other places (like get_compiler_info).
+ #
+ # Set TERM to dumb to prevent the '^[[6n' from occurring.
+ #
+ # We could do this only for ishost *-*-mingw*, but that introduces
+ # inconsistency between platforms, with test-cases passing on one platform
+ # but failing on the other. So, we do this for all platforms.
+ setenv TERM dumb
+
# Don't let a .inputrc file or an existing setting of INPUTRC mess
# up the test results. Certain tests (style tests and TUI tests)
# want to set the terminal to a non-"dumb" value, and for those we
@@ -9304,7 +9380,12 @@ proc core_find {binfile {deletefiles {}} {arg ""}} {
file mkdir $coredir
catch "system \"(cd ${coredir}; ulimit -c unlimited; ${binfile} ${arg}; true) >/dev/null 2>&1\""
# remote_exec host "${binfile}"
- foreach i "${coredir}/core ${coredir}/core.coremaker.c ${binfile}.core" {
+ set binfile_basename [file tail $binfile]
+ foreach i [list \
+ ${coredir}/core \
+ ${coredir}/core.coremaker.c \
+ ${coredir}/${binfile_basename}.core \
+ ${coredir}/${binfile_basename}.exe.core] {
if [remote_file build exists $i] {
remote_exec build "mv $i $destcore"
set found 1
diff --git a/gdb/testsuite/lib/gdbserver-support.exp b/gdb/testsuite/lib/gdbserver-support.exp
index c285072..2389206 100644
--- a/gdb/testsuite/lib/gdbserver-support.exp
+++ b/gdb/testsuite/lib/gdbserver-support.exp
@@ -69,7 +69,7 @@ proc gdb_target_cmd_ext { targetname serialport {additional_text ""} } {
}
-re "Non-stop mode requested, but remote does not support non-stop.*$gdb_prompt $" {
verbose "remote does not support non-stop"
- return 1
+ return 2
}
-re "Remote MIPS debugging.*$additional_text.*$gdb_prompt" {
verbose "Set target to $targetname"
diff --git a/gdb/testsuite/make-check-all.sh b/gdb/testsuite/make-check-all.sh
index c2fbadb..ab72574 100755
--- a/gdb/testsuite/make-check-all.sh
+++ b/gdb/testsuite/make-check-all.sh
@@ -192,7 +192,7 @@ do_tests ()
# Run make check.
make $maketarget \
- RUNTESTFLAGS="${rtf[*]} ${tests[*]}" \
+ RUNTESTFLAGS="${rtf[*]}" TESTS="${tests[*]}" \
2>&1 \
| summary
@@ -216,7 +216,7 @@ do_tests ()
cp gdb.sum gdb.log "$dir"
# Record the 'make check' command to enable easy re-running.
- echo "make $maketarget RUNTESTFLAGS=\"${rtf[*]} ${tests[*]}\"" \
+ echo "make $maketarget RUNTESTFLAGS=\"${rtf[*]}\" TESTS=\"${tests[*]}\"" \
> "$dir/make-check.sh"
fi
}
diff --git a/gdb/thread.c b/gdb/thread.c
index b659463..920d8dc 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -1038,6 +1038,37 @@ pc_in_thread_step_range (CORE_ADDR pc, struct thread_info *thread)
&& pc < thread->control.step_range_end);
}
+/* The options for the "info threads" command. */
+
+struct info_threads_opts
+{
+ /* For "-gid". */
+ bool show_global_ids = false;
+ /* For "-running". */
+ bool show_running_threads = false;
+ /* For "-stopped". */
+ bool show_stopped_threads = false;
+};
+
+static const gdb::option::option_def info_threads_option_defs[] = {
+
+ gdb::option::flag_option_def<info_threads_opts> {
+ "gid",
+ [] (info_threads_opts *opts) { return &opts->show_global_ids; },
+ N_("Show global thread IDs."),
+ },
+ gdb::option::flag_option_def<info_threads_opts> {
+ "running",
+ [] (info_threads_opts *opts) { return &opts->show_running_threads; },
+ N_("Show running threads only."),
+ },
+ gdb::option::flag_option_def<info_threads_opts> {
+ "stopped",
+ [] (info_threads_opts *opts) { return &opts->show_stopped_threads; },
+ N_("Show stopped threads only."),
+ },
+};
+
/* Helper for print_thread_info. Returns true if THR should be
printed. If REQUESTED_THREADS, a list of GDB ids/ranges, is not
NULL, only print THR if its ID is included in the list. GLOBAL_IDS
@@ -1046,11 +1077,13 @@ pc_in_thread_step_range (CORE_ADDR pc, struct thread_info *thread)
is a thread from the process PID. Otherwise, threads from all
attached PIDs are printed. If both REQUESTED_THREADS is not NULL
and PID is not -1, then the thread is printed if it belongs to the
- specified process. Otherwise, an error is raised. */
+ specified process. Otherwise, an error is raised. OPTS is the
+ options of the "info threads" command. */
static bool
-should_print_thread (const char *requested_threads, int default_inf_num,
- int global_ids, int pid, struct thread_info *thr)
+should_print_thread (const char *requested_threads,
+ const info_threads_opts &opts, int default_inf_num,
+ int global_ids, int pid, thread_info *thr)
{
if (requested_threads != NULL && *requested_threads != '\0')
{
@@ -1075,7 +1108,17 @@ should_print_thread (const char *requested_threads, int default_inf_num,
if (thr->state == THREAD_EXITED)
return false;
- return true;
+ bool is_stopped = (thr->state == THREAD_STOPPED);
+ if (opts.show_stopped_threads && is_stopped)
+ return true;
+
+ bool is_running = (thr->state == THREAD_RUNNING);
+ if (opts.show_running_threads && is_running)
+ return true;
+
+ /* If the user did not pass a filter flag, show the thread. */
+ return (!opts.show_stopped_threads
+ && !opts.show_running_threads);
}
/* Return the string to display in "info threads"'s "Target Id"
@@ -1104,8 +1147,8 @@ thread_target_id_str (thread_info *tp)
static void
do_print_thread (ui_out *uiout, const char *requested_threads,
- int global_ids, int pid, int show_global_ids,
- int default_inf_num, thread_info *tp,
+ const info_threads_opts &opts, int global_ids,
+ int pid, int default_inf_num, thread_info *tp,
thread_info *current_thread)
{
int core;
@@ -1114,7 +1157,7 @@ do_print_thread (ui_out *uiout, const char *requested_threads,
if (current_thread != nullptr)
switch_to_thread (current_thread);
- if (!should_print_thread (requested_threads, default_inf_num,
+ if (!should_print_thread (requested_threads, opts, default_inf_num,
global_ids, pid, tp))
return;
@@ -1130,7 +1173,7 @@ do_print_thread (ui_out *uiout, const char *requested_threads,
uiout->field_string ("id-in-tg", print_thread_id (tp));
}
- if (show_global_ids || uiout->is_mi_like_p ())
+ if (opts.show_global_ids || uiout->is_mi_like_p ())
uiout->field_signed ("id", tp->global_num);
/* Switch to the thread (and inferior / target). */
@@ -1191,23 +1234,22 @@ do_print_thread (ui_out *uiout, const char *requested_threads,
static void
print_thread (ui_out *uiout, const char *requested_threads,
- int global_ids, int pid, int show_global_ids,
+ const info_threads_opts &opts, int global_ids, int pid,
int default_inf_num, thread_info *tp, thread_info *current_thread)
{
do_with_buffered_output (do_print_thread, uiout, requested_threads,
- global_ids, pid, show_global_ids,
- default_inf_num, tp, current_thread);
+ opts, global_ids, pid, default_inf_num, tp,
+ current_thread);
}
/* Like print_thread_info, but in addition, GLOBAL_IDS indicates
whether REQUESTED_THREADS is a list of global or per-inferior
- thread ids. */
+ thread ids. OPTS is the options of the "info threads" command. */
static void
print_thread_info_1 (struct ui_out *uiout, const char *requested_threads,
- int global_ids, int pid,
- int show_global_ids)
+ const info_threads_opts &opts, int global_ids, int pid)
{
int default_inf_num = current_inferior ()->num;
@@ -1235,19 +1277,21 @@ print_thread_info_1 (struct ui_out *uiout, const char *requested_threads,
list_emitter.emplace (uiout, "threads");
else
{
- int n_threads = 0;
+ int n_matching_threads = 0;
/* The width of the "Target Id" column. Grown below to
accommodate the largest entry. */
size_t target_id_col_width = 17;
for (thread_info *tp : all_threads ())
{
+ any_thread = true;
+
/* In case REQUESTED_THREADS contains $_thread. */
if (current_thread != nullptr)
switch_to_thread (current_thread);
- if (!should_print_thread (requested_threads, default_inf_num,
- global_ids, pid, tp))
+ if (!should_print_thread (requested_threads, opts,
+ default_inf_num, global_ids, pid, tp))
continue;
/* Switch inferiors so we're looking at the right
@@ -1258,25 +1302,24 @@ print_thread_info_1 (struct ui_out *uiout, const char *requested_threads,
= std::max (target_id_col_width,
thread_target_id_str (tp).size ());
- ++n_threads;
+ ++n_matching_threads;
}
- if (n_threads == 0)
+ if (n_matching_threads == 0)
{
- if (requested_threads == NULL || *requested_threads == '\0')
+ if (!any_thread)
uiout->message (_("No threads.\n"));
else
- uiout->message (_("No threads match '%s'.\n"),
- requested_threads);
+ uiout->message (_("No threads matched.\n"));
return;
}
- table_emitter.emplace (uiout, show_global_ids ? 5 : 4,
- n_threads, "threads");
+ table_emitter.emplace (uiout, opts.show_global_ids ? 5 : 4,
+ n_matching_threads, "threads");
uiout->table_header (1, ui_left, "current", "");
uiout->table_header (4, ui_left, "id-in-tg", "Id");
- if (show_global_ids)
+ if (opts.show_global_ids)
uiout->table_header (4, ui_left, "id", "GId");
uiout->table_header (target_id_col_width, ui_left,
"target-id", "Target Id");
@@ -1287,13 +1330,11 @@ print_thread_info_1 (struct ui_out *uiout, const char *requested_threads,
for (inferior *inf : all_inferiors ())
for (thread_info *tp : inf->threads ())
{
- any_thread = true;
-
if (tp == current_thread && tp->state == THREAD_EXITED)
current_exited = true;
- print_thread (uiout, requested_threads, global_ids, pid,
- show_global_ids, default_inf_num, tp, current_thread);
+ print_thread (uiout, requested_threads, opts, global_ids, pid,
+ default_inf_num, tp, current_thread);
}
/* This end scope restores the current thread and the frame
@@ -1322,27 +1363,10 @@ void
print_thread_info (struct ui_out *uiout, const char *requested_threads,
int pid)
{
- print_thread_info_1 (uiout, requested_threads, 1, pid, 0);
+ info_threads_opts opts;
+ print_thread_info_1 (uiout, requested_threads, opts, 1, pid);
}
-/* The options for the "info threads" command. */
-
-struct info_threads_opts
-{
- /* For "-gid". */
- bool show_global_ids = false;
-};
-
-static const gdb::option::option_def info_threads_option_defs[] = {
-
- gdb::option::flag_option_def<info_threads_opts> {
- "gid",
- [] (info_threads_opts *opts) { return &opts->show_global_ids; },
- N_("Show global thread IDs."),
- },
-
-};
-
/* Create an option_def_group for the "info threads" options, with
IT_OPTS as context. */
@@ -1367,7 +1391,7 @@ info_threads_command (const char *arg, int from_tty)
gdb::option::process_options
(&arg, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, grp);
- print_thread_info_1 (current_uiout, arg, 0, -1, it_opts.show_global_ids);
+ print_thread_info_1 (current_uiout, arg, it_opts, 0, -1);
}
/* Completer for the "info threads" command. */
@@ -2287,9 +2311,7 @@ static const struct internalvar_funcs inferior_thread_count_funcs =
NULL,
};
-void _initialize_thread ();
-void
-_initialize_thread ()
+INIT_GDB_FILE (thread)
{
static struct cmd_list_element *thread_apply_list = NULL;
cmd_list_element *c;
diff --git a/gdb/tic6x-linux-tdep.c b/gdb/tic6x-linux-tdep.c
index 280d46d..5b3d402 100644
--- a/gdb/tic6x-linux-tdep.c
+++ b/gdb/tic6x-linux-tdep.c
@@ -169,7 +169,7 @@ tic6x_uclinux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
linux_init_abi (info, gdbarch, 0);
/* Shared library handling. */
- set_gdbarch_so_ops (gdbarch, &dsbt_so_ops);
+ set_gdbarch_make_solib_ops (gdbarch, make_dsbt_solib_ops);
tdep->syscall_next_pc = tic6x_linux_syscall_next_pc;
@@ -203,9 +203,7 @@ tic6x_uclinux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
&tic6x_linux_rt_sigreturn_tramp_frame);
}
-void _initialize_tic6x_linux_tdep ();
-void
-_initialize_tic6x_linux_tdep ()
+INIT_GDB_FILE (tic6x_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_tic6x, 0, GDB_OSABI_LINUX,
tic6x_uclinux_init_abi);
diff --git a/gdb/tic6x-tdep.c b/gdb/tic6x-tdep.c
index 062a974..2ab8dac 100644
--- a/gdb/tic6x-tdep.c
+++ b/gdb/tic6x-tdep.c
@@ -1293,9 +1293,7 @@ tic6x_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
return gdbarch;
}
-void _initialize_tic6x_tdep ();
-void
-_initialize_tic6x_tdep ()
+INIT_GDB_FILE (tic6x_tdep)
{
gdbarch_register (bfd_arch_tic6x, tic6x_gdbarch_init);
}
diff --git a/gdb/tilegx-linux-nat.c b/gdb/tilegx-linux-nat.c
index bd077b2..99f2cc4 100644
--- a/gdb/tilegx-linux-nat.c
+++ b/gdb/tilegx-linux-nat.c
@@ -163,9 +163,7 @@ tilegx_linux_nat_target::store_registers (struct regcache *regcache,
perror_with_name (_("Couldn't write registers"));
}
-void _initialize_tile_linux_nat ();
-void
-_initialize_tile_linux_nat ()
+INIT_GDB_FILE (tile_linux_nat)
{
linux_target = &the_tilegx_linux_nat_target;
add_inf_child_target (&the_tilegx_linux_nat_target);
diff --git a/gdb/tilegx-linux-tdep.c b/gdb/tilegx-linux-tdep.c
index a0e6954..f54e280 100644
--- a/gdb/tilegx-linux-tdep.c
+++ b/gdb/tilegx-linux-tdep.c
@@ -19,6 +19,7 @@
#include "osabi.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "glibc-tdep.h"
#include "solib-svr4.h"
#include "symtab.h"
@@ -119,11 +120,9 @@ tilegx_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* GNU/Linux uses SVR4-style shared libraries. */
if (arch_size == 32)
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
else
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_lp64_svr4_solib_ops);
/* Enable TLS support. */
set_gdbarch_fetch_tls_load_module_address (gdbarch,
@@ -134,9 +133,7 @@ tilegx_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
}
-void _initialize_tilegx_linux_tdep ();
-void
-_initialize_tilegx_linux_tdep ()
+INIT_GDB_FILE (tilegx_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_tilegx, bfd_mach_tilegx, GDB_OSABI_LINUX,
tilegx_linux_init_abi);
diff --git a/gdb/tilegx-tdep.c b/gdb/tilegx-tdep.c
index 4922fff..a153f65 100644
--- a/gdb/tilegx-tdep.c
+++ b/gdb/tilegx-tdep.c
@@ -1021,9 +1021,7 @@ tilegx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
return gdbarch;
}
-void _initialize_tilegx_tdep ();
-void
-_initialize_tilegx_tdep ()
+INIT_GDB_FILE (tilegx_tdep)
{
gdbarch_register (bfd_arch_tilegx, tilegx_gdbarch_init);
}
diff --git a/gdb/top.c b/gdb/top.c
index 6adef46..72d1953 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -415,7 +415,7 @@ wait_sync_command_done (void)
point. */
scoped_enable_commit_resumed enable ("sync wait");
- while (gdb_do_one_event () >= 0)
+ while (current_interpreter ()->do_one_event () >= 0)
if (ui->prompt_state != PROMPT_BLOCKED)
break;
}
@@ -1031,7 +1031,7 @@ gdb_readline_wrapper (const char *prompt)
(*after_char_processing_hook) ();
gdb_assert (after_char_processing_hook == NULL);
- while (gdb_do_one_event () >= 0)
+ while (current_interpreter ()->do_one_event () >= 0)
if (gdb_readline_wrapper_done)
break;
@@ -2347,9 +2347,7 @@ gdb_init ()
init_colorsupport_var ();
}
-void _initialize_top ();
-void
-_initialize_top ()
+INIT_GDB_FILE (top)
{
/* Determine a default value for the history filename. */
const char *tmpenv = getenv ("GDBHISTFILE");
diff --git a/gdb/tracectf.c b/gdb/tracectf.c
index 1650e67..0f80d08 100644
--- a/gdb/tracectf.c
+++ b/gdb/tracectf.c
@@ -1174,7 +1174,7 @@ ctf_target_open (const char *args, int from_tty)
merge_uploaded_trace_state_variables (&uploaded_tsvs);
merge_uploaded_tracepoints (&uploaded_tps);
- post_create_inferior (from_tty);
+ post_create_inferior (from_tty, true);
}
/* This is the implementation of target_ops method to_close. Destroy
@@ -1717,9 +1717,7 @@ ctf_target::traceframe_info ()
/* module initialization */
-void _initialize_ctf ();
-void
-_initialize_ctf ()
+INIT_GDB_FILE (ctf)
{
#if HAVE_LIBBABELTRACE
add_target (ctf_target_info, ctf_target_open,
diff --git a/gdb/tracefile-tfile.c b/gdb/tracefile-tfile.c
index 5f8b338..a45001c 100644
--- a/gdb/tracefile-tfile.c
+++ b/gdb/tracefile-tfile.c
@@ -567,7 +567,7 @@ tfile_target_open (const char *arg, int from_tty)
merge_uploaded_tracepoints (&uploaded_tps);
- post_create_inferior (from_tty);
+ post_create_inferior (from_tty, true);
}
/* Interpret the given line from the definitions part of the trace
@@ -1116,9 +1116,7 @@ tfile_append_tdesc_line (const char *line)
trace_tdesc += "\n";
}
-void _initialize_tracefile_tfile ();
-void
-_initialize_tracefile_tfile ()
+INIT_GDB_FILE (tracefile_tfile)
{
add_target (tfile_target_info, tfile_target_open,
filename_maybe_quoted_completer);
diff --git a/gdb/tracefile.c b/gdb/tracefile.c
index dac2eb7..19b4d1e 100644
--- a/gdb/tracefile.c
+++ b/gdb/tracefile.c
@@ -473,9 +473,7 @@ tracefile_target::get_trace_status (struct trace_status *ts)
return -1;
}
-void _initialize_tracefile ();
-void
-_initialize_tracefile ()
+INIT_GDB_FILE (tracefile)
{
add_com ("tsave", class_trace, tsave_command, _("\
Save the trace data to a file.\n\
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index b431468..c0f1eae 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -3919,9 +3919,7 @@ static const struct internalvar_funcs sdata_funcs =
cmd_list_element *while_stepping_cmd_element = nullptr;
/* module initialization */
-void _initialize_tracepoint ();
-void
-_initialize_tracepoint ()
+INIT_GDB_FILE (tracepoint)
{
struct cmd_list_element *c;
diff --git a/gdb/tui/tui-disasm.c b/gdb/tui/tui-disasm.c
index 5488760..627f71c 100644
--- a/gdb/tui/tui-disasm.c
+++ b/gdb/tui/tui-disasm.c
@@ -546,9 +546,7 @@ run_tests ()
} /* namespace selftests */
#endif /* GDB_SELF_TEST */
-void _initialize_tui_disasm ();
-void
-_initialize_tui_disasm ()
+INIT_GDB_FILE (tui_disasm)
{
#if GDB_SELF_TEST
selftests::register_test ("tui-disasm", selftests::tui::disasm::run_tests);
diff --git a/gdb/tui/tui-hooks.c b/gdb/tui/tui-hooks.c
index 814ddac..024fedd 100644
--- a/gdb/tui/tui-hooks.c
+++ b/gdb/tui/tui-hooks.c
@@ -262,9 +262,7 @@ tui_remove_hooks (void)
tui_attach_detach_observers (false);
}
-void _initialize_tui_hooks ();
-void
-_initialize_tui_hooks ()
+INIT_GDB_FILE (tui_hooks)
{
/* Install the permanent hooks. */
gdb::observers::new_objfile.attach (tui_new_objfile_hook, "tui-hooks");
diff --git a/gdb/tui/tui-interp.c b/gdb/tui/tui-interp.c
index 53acf82..3d0e152 100644
--- a/gdb/tui/tui-interp.c
+++ b/gdb/tui/tui-interp.c
@@ -161,9 +161,7 @@ tui_interp_factory (const char *name)
return new tui_interp (name);
}
-void _initialize_tui_interp ();
-void
-_initialize_tui_interp ()
+INIT_GDB_FILE (tui_interp)
{
interp_factory_register (INTERP_TUI, tui_interp_factory);
diff --git a/gdb/tui/tui-layout.c b/gdb/tui/tui-layout.c
index 73ba0c6..558055d 100644
--- a/gdb/tui/tui-layout.c
+++ b/gdb/tui/tui-layout.c
@@ -1294,9 +1294,7 @@ tui_new_layout_command (const char *spec, int from_tty)
/* Function to initialize gdb commands, for tui window layout
manipulation. */
-void _initialize_tui_layout ();
-void
-_initialize_tui_layout ()
+INIT_GDB_FILE (tui_layout)
{
struct cmd_list_element *layout_cmd
= add_basic_prefix_cmd ("layout", class_tui, _("\
diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c
index 0b8cb85..ac2757a 100644
--- a/gdb/tui/tui-regs.c
+++ b/gdb/tui/tui-regs.c
@@ -566,9 +566,7 @@ tui_reggroup_completer (struct cmd_list_element *ignore,
complete_on_enum (tracker, extra, text, word);
}
-void _initialize_tui_regs ();
-void
-_initialize_tui_regs ()
+INIT_GDB_FILE (tui_regs)
{
struct cmd_list_element **tuicmd, *cmd;
diff --git a/gdb/tui/tui-status.c b/gdb/tui/tui-status.c
index 484f4e5..c2d3873 100644
--- a/gdb/tui/tui-status.c
+++ b/gdb/tui/tui-status.c
@@ -325,9 +325,7 @@ tui_update_command (const char *arg, int from_tty)
/* Function to initialize gdb commands, for tui window stack
manipulation. */
-void _initialize_tui_stack ();
-void
-_initialize_tui_stack ()
+INIT_GDB_FILE (tui_stack)
{
add_com ("update", class_tui, tui_update_command,
_("\
diff --git a/gdb/tui/tui-win.c b/gdb/tui/tui-win.c
index f44600d..d4fbbf1 100644
--- a/gdb/tui/tui-win.c
+++ b/gdb/tui/tui-win.c
@@ -1091,9 +1091,7 @@ bool tui_left_margin_verbose = false;
/* Function to initialize gdb commands, for tui window
manipulation. */
-void _initialize_tui_win ();
-void
-_initialize_tui_win ()
+INIT_GDB_FILE (tui_win)
{
static struct cmd_list_element *tui_setlist;
static struct cmd_list_element *tui_showlist;
diff --git a/gdb/tui/tui.c b/gdb/tui/tui.c
index 2c7a6a0..5883d6c 100644
--- a/gdb/tui/tui.c
+++ b/gdb/tui/tui.c
@@ -618,9 +618,7 @@ tui_get_command_dimension (unsigned int *width,
return true;
}
-void _initialize_tui ();
-void
-_initialize_tui ()
+INIT_GDB_FILE (tui)
{
struct cmd_list_element **tuicmd;
diff --git a/gdb/typeprint.c b/gdb/typeprint.c
index 4bc5947..ef0c5aa 100644
--- a/gdb/typeprint.c
+++ b/gdb/typeprint.c
@@ -735,9 +735,7 @@ Display of struct members offsets and sizes in hexadecimal is %s\n"),
value);
}
-void _initialize_typeprint ();
-void
-_initialize_typeprint ()
+INIT_GDB_FILE (typeprint)
{
struct cmd_list_element *c;
diff --git a/gdb/ui.c b/gdb/ui.c
index d67ab2c..cd23399 100644
--- a/gdb/ui.c
+++ b/gdb/ui.c
@@ -237,9 +237,7 @@ new_ui_command (const char *args, int from_tty)
gdb_printf ("New UI allocated\n");
}
-void _initialize_ui ();
-void
-_initialize_ui ()
+INIT_GDB_FILE (ui)
{
cmd_list_element *c = add_cmd ("new-ui", class_support, new_ui_command, _("\
Create a new UI.\n\
diff --git a/gdb/unittests/array-view-selftests.c b/gdb/unittests/array-view-selftests.c
index fa96d3b..914800a 100644
--- a/gdb/unittests/array-view-selftests.c
+++ b/gdb/unittests/array-view-selftests.c
@@ -695,9 +695,7 @@ run_copy_tests ()
} /* namespace array_view_tests */
} /* namespace selftests */
-void _initialize_array_view_selftests ();
-void
-_initialize_array_view_selftests ()
+INIT_GDB_FILE (array_view_selftests)
{
selftests::register_test ("array_view",
selftests::array_view_tests::run_tests);
diff --git a/gdb/unittests/child-path-selftests.c b/gdb/unittests/child-path-selftests.c
index 0f29f7d..95b2c34 100644
--- a/gdb/unittests/child-path-selftests.c
+++ b/gdb/unittests/child-path-selftests.c
@@ -58,9 +58,7 @@ test ()
}
}
-void _initialize_child_path_selftests ();
-void
-_initialize_child_path_selftests ()
+INIT_GDB_FILE (child_path_selftests)
{
selftests::register_test ("child_path",
selftests::child_path::test);
diff --git a/gdb/unittests/cli-utils-selftests.c b/gdb/unittests/cli-utils-selftests.c
index e6c64a9..1382ca6 100644
--- a/gdb/unittests/cli-utils-selftests.c
+++ b/gdb/unittests/cli-utils-selftests.c
@@ -109,9 +109,7 @@ test_cli_utils ()
}
}
-void _initialize_cli_utils_selftests ();
-void
-_initialize_cli_utils_selftests ()
+INIT_GDB_FILE (cli_utils_selftests)
{
selftests::register_test ("cli_utils",
selftests::cli_utils::test_cli_utils);
diff --git a/gdb/unittests/command-def-selftests.c b/gdb/unittests/command-def-selftests.c
index 6f169f5..0a54d31 100644
--- a/gdb/unittests/command-def-selftests.c
+++ b/gdb/unittests/command-def-selftests.c
@@ -219,9 +219,7 @@ command_structure_invariants_tests ()
} /* namespace selftests */
-void _initialize_command_def_selftests ();
-void
-_initialize_command_def_selftests ()
+INIT_GDB_FILE (command_def_selftests)
{
selftests::register_test
("help_doc_invariants",
diff --git a/gdb/unittests/common-utils-selftests.c b/gdb/unittests/common-utils-selftests.c
index fab9cd1..ecc4769 100644
--- a/gdb/unittests/common-utils-selftests.c
+++ b/gdb/unittests/common-utils-selftests.c
@@ -127,9 +127,7 @@ string_vappendf_tests ()
} /* namespace selftests */
-void _initialize_common_utils_selftests ();
-void
-_initialize_common_utils_selftests ()
+INIT_GDB_FILE (common_utils_selftests)
{
selftests::register_test ("string_printf", selftests::string_printf_tests);
selftests::register_test ("string_vprintf", selftests::string_vprintf_tests);
diff --git a/gdb/unittests/copy_bitwise-selftests.c b/gdb/unittests/copy_bitwise-selftests.c
index 8798cbd..6fcdcd7 100644
--- a/gdb/unittests/copy_bitwise-selftests.c
+++ b/gdb/unittests/copy_bitwise-selftests.c
@@ -151,9 +151,7 @@ copy_bitwise_tests (void)
} /* namespace selftests */
-void _initialize_copy_bitwise_utils_selftests ();
-void
-_initialize_copy_bitwise_utils_selftests ()
+INIT_GDB_FILE (copy_bitwise_utils_selftests)
{
selftests::register_test ("copy_bitwise", selftests::copy_bitwise_tests);
}
diff --git a/gdb/unittests/enum-flags-selftests.c b/gdb/unittests/enum-flags-selftests.c
index bb55019..3eb0f52 100644
--- a/gdb/unittests/enum-flags-selftests.c
+++ b/gdb/unittests/enum-flags-selftests.c
@@ -607,10 +607,7 @@ self_test ()
} /* namespace enum_flags_tests */
} /* namespace selftests */
-void _initialize_enum_flags_selftests ();
-
-void
-_initialize_enum_flags_selftests ()
+INIT_GDB_FILE (enum_flags_selftests)
{
selftests::register_test ("enum-flags",
selftests::enum_flags_tests::self_test);
diff --git a/gdb/unittests/environ-selftests.c b/gdb/unittests/environ-selftests.c
index 79bffed..5ac3384 100644
--- a/gdb/unittests/environ-selftests.c
+++ b/gdb/unittests/environ-selftests.c
@@ -297,9 +297,7 @@ run_tests ()
} /* namespace gdb_environ */
} /* namespace selftests */
-void _initialize_environ_selftests ();
-void
-_initialize_environ_selftests ()
+INIT_GDB_FILE (environ_selftests)
{
selftests::register_test ("gdb_environ",
selftests::gdb_environ_tests::run_tests);
diff --git a/gdb/unittests/filtered_iterator-selftests.c b/gdb/unittests/filtered_iterator-selftests.c
index b3ec70b..49c95cb 100644
--- a/gdb/unittests/filtered_iterator-selftests.c
+++ b/gdb/unittests/filtered_iterator-selftests.c
@@ -154,9 +154,7 @@ test_filtered_iterator_eq ()
} /* namespace selftests */
-void _initialize_filtered_iterator_selftests ();
-void
-_initialize_filtered_iterator_selftests ()
+INIT_GDB_FILE (filtered_iterator_selftests)
{
selftests::register_test ("filtered_iterator",
selftests::test_filtered_iterator);
diff --git a/gdb/unittests/format_pieces-selftests.c b/gdb/unittests/format_pieces-selftests.c
index 473d690..c7d8ff0 100644
--- a/gdb/unittests/format_pieces-selftests.c
+++ b/gdb/unittests/format_pieces-selftests.c
@@ -147,9 +147,7 @@ run_tests ()
} /* namespace format_pieces */
} /* namespace selftests */
-void _initialize_format_pieces_selftests ();
-void
-_initialize_format_pieces_selftests ()
+INIT_GDB_FILE (format_pieces_selftests)
{
selftests::register_test ("format_pieces",
selftests::format_pieces::run_tests);
diff --git a/gdb/unittests/frame_info_ptr-selftests.c b/gdb/unittests/frame_info_ptr-selftests.c
index c9eb4f4..d518482 100644
--- a/gdb/unittests/frame_info_ptr-selftests.c
+++ b/gdb/unittests/frame_info_ptr-selftests.c
@@ -66,9 +66,7 @@ test_user_created_frame ()
} /* namespace selftests */
-void _initialize_frame_info_ptr_selftests ();
-void
-_initialize_frame_info_ptr_selftests ()
+INIT_GDB_FILE (frame_info_ptr_selftests)
{
selftests::register_test ("frame_info_ptr_user",
selftests::test_user_created_frame);
diff --git a/gdb/unittests/function-view-selftests.c b/gdb/unittests/function-view-selftests.c
index 036c7f9..21838f1 100644
--- a/gdb/unittests/function-view-selftests.c
+++ b/gdb/unittests/function-view-selftests.c
@@ -250,9 +250,7 @@ run_tests ()
} /* namespace function_view */
} /* namespace selftests */
-void _initialize_function_view_selftests ();
-void
-_initialize_function_view_selftests ()
+INIT_GDB_FILE (function_view_selftests)
{
selftests::register_test ("function_view",
selftests::function_view::run_tests);
diff --git a/gdb/unittests/gdb_tilde_expand-selftests.c b/gdb/unittests/gdb_tilde_expand-selftests.c
index b0b7027..28c759f 100644
--- a/gdb/unittests/gdb_tilde_expand-selftests.c
+++ b/gdb/unittests/gdb_tilde_expand-selftests.c
@@ -84,9 +84,7 @@ do_test ()
} /* namespace gdb_tilde_expand_tests */
} /* namespace selftests */
-void _initialize_gdb_tilde_expand_selftests ();
-void
-_initialize_gdb_tilde_expand_selftests ()
+INIT_GDB_FILE (gdb_tilde_expand_selftests)
{
selftests::register_test
("gdb_tilde_expand", selftests::gdb_tilde_expand_tests::do_test);
diff --git a/gdb/unittests/gmp-utils-selftests.c b/gdb/unittests/gmp-utils-selftests.c
index 495947af..9843fcb 100644
--- a/gdb/unittests/gmp-utils-selftests.c
+++ b/gdb/unittests/gmp-utils-selftests.c
@@ -498,10 +498,7 @@ gdb_mpq_write_fixed_point ()
}
-void _initialize_gmp_utils_selftests ();
-
-void
-_initialize_gmp_utils_selftests ()
+INIT_GDB_FILE (gmp_utils_selftests)
{
selftests::register_test ("gdb_mpz_as_integer",
selftests::gdb_mpz_as_integer);
diff --git a/gdb/unittests/intrusive_list-selftests.c b/gdb/unittests/intrusive_list-selftests.c
index eaffbba..2dd1298 100644
--- a/gdb/unittests/intrusive_list-selftests.c
+++ b/gdb/unittests/intrusive_list-selftests.c
@@ -1648,10 +1648,7 @@ test_intrusive_list ()
test_node_is_linked ();
}
-void _initialize_intrusive_list_selftests ();
-
-void
-_initialize_intrusive_list_selftests ()
+INIT_GDB_FILE (intrusive_list_selftests)
{
selftests::register_test ("intrusive_list", test_intrusive_list);
}
diff --git a/gdb/unittests/lookup_name_info-selftests.c b/gdb/unittests/lookup_name_info-selftests.c
index 3e8440b..dc0d307 100644
--- a/gdb/unittests/lookup_name_info-selftests.c
+++ b/gdb/unittests/lookup_name_info-selftests.c
@@ -105,9 +105,7 @@ run_tests ()
}} /* namespace selftests::lookup_name */
-void _initialize_lookup_name_info_selftests ();
-void
-_initialize_lookup_name_info_selftests ()
+INIT_GDB_FILE (lookup_name_info_selftests)
{
selftests::register_test ("lookup_name_info",
selftests::lookup_name::run_tests);
diff --git a/gdb/unittests/main-thread-selftests.c b/gdb/unittests/main-thread-selftests.c
index 5f3d790..77adf47 100644
--- a/gdb/unittests/main-thread-selftests.c
+++ b/gdb/unittests/main-thread-selftests.c
@@ -73,9 +73,7 @@ run_tests ()
}
}
-void _initialize_main_thread_selftests ();
-void
-_initialize_main_thread_selftests ()
+INIT_GDB_FILE (main_thread_selftests)
{
#if CXX_STD_THREAD
selftests::register_test ("run_on_main_thread",
diff --git a/gdb/unittests/memory-map-selftests.c b/gdb/unittests/memory-map-selftests.c
index 6872d5a..c014c4d 100644
--- a/gdb/unittests/memory-map-selftests.c
+++ b/gdb/unittests/memory-map-selftests.c
@@ -75,9 +75,7 @@ parse_memory_map_tests ()
#endif /* HAVE_LIBEXPAT */
-void _initialize_memory_map_selftests ();
-void
-_initialize_memory_map_selftests ()
+INIT_GDB_FILE (memory_map_selftests)
{
#if defined(HAVE_LIBEXPAT)
selftests::register_test
diff --git a/gdb/unittests/memrange-selftests.c b/gdb/unittests/memrange-selftests.c
index 1433105..17e08e8 100644
--- a/gdb/unittests/memrange-selftests.c
+++ b/gdb/unittests/memrange-selftests.c
@@ -105,9 +105,7 @@ normalize_mem_ranges_tests ()
} /* namespace memrange_tests */
} /* namespace selftests */
-void _initialize_memrange_selftests ();
-void
-_initialize_memrange_selftests ()
+INIT_GDB_FILE (memrange_selftests)
{
selftests::register_test
("normalize_mem_ranges",
diff --git a/gdb/unittests/mkdir-recursive-selftests.c b/gdb/unittests/mkdir-recursive-selftests.c
index 764fe1a..b2ae383 100644
--- a/gdb/unittests/mkdir-recursive-selftests.c
+++ b/gdb/unittests/mkdir-recursive-selftests.c
@@ -80,9 +80,7 @@ test ()
}
}
-void _initialize_mkdir_recursive_selftests ();
-void
-_initialize_mkdir_recursive_selftests ()
+INIT_GDB_FILE (mkdir_recursive_selftests)
{
selftests::register_test ("mkdir_recursive",
selftests::mkdir_recursive::test);
diff --git a/gdb/unittests/observable-selftests.c b/gdb/unittests/observable-selftests.c
index 90d7392..0934249 100644
--- a/gdb/unittests/observable-selftests.c
+++ b/gdb/unittests/observable-selftests.c
@@ -237,9 +237,7 @@ run_tests ()
} /* namespace observers */
} /* namespace selftests */
-void _initialize_observer_selftest ();
-void
-_initialize_observer_selftest ()
+INIT_GDB_FILE (observer_selftest)
{
selftests::register_test ("gdb::observers",
selftests::observers::run_tests);
diff --git a/gdb/unittests/offset-type-selftests.c b/gdb/unittests/offset-type-selftests.c
index 1623f0d..2cba4e1 100644
--- a/gdb/unittests/offset-type-selftests.c
+++ b/gdb/unittests/offset-type-selftests.c
@@ -170,9 +170,7 @@ run_tests ()
} /* namespace offset_type */
} /* namespace selftests */
-void _initialize_offset_type_selftests ();
-void
-_initialize_offset_type_selftests ()
+INIT_GDB_FILE (offset_type_selftests)
{
selftests::register_test ("offset_type", selftests::offset_type::run_tests);
}
diff --git a/gdb/unittests/packed-selftests.c b/gdb/unittests/packed-selftests.c
index daa8036..5a91b29 100644
--- a/gdb/unittests/packed-selftests.c
+++ b/gdb/unittests/packed-selftests.c
@@ -119,9 +119,7 @@ run_tests ()
} /* namespace packed_tests */
} /* namespace selftests */
-void _initialize_packed_selftests ();
-void
-_initialize_packed_selftests ()
+INIT_GDB_FILE (packed_selftests)
{
selftests::register_test ("packed", selftests::packed_tests::run_tests);
}
diff --git a/gdb/unittests/parallel-for-selftests.c b/gdb/unittests/parallel-for-selftests.c
index 841d914..f545614 100644
--- a/gdb/unittests/parallel-for-selftests.c
+++ b/gdb/unittests/parallel-for-selftests.c
@@ -17,13 +17,6 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
-/* This file is divided in two parts:
- - FOR_EACH-undefined, and
- - FOR_EACH-defined.
- The former includes the latter, more than once, with different values for
- FOR_EACH. The FOR_EACH-defined part reads like a regular function. */
-#ifndef FOR_EACH
-
#include "gdbsupport/selftest.h"
#include "gdbsupport/parallel-for.h"
@@ -49,97 +42,77 @@ struct save_restore_n_threads
int n_threads;
};
-/* Define test_par using TEST in the FOR_EACH-defined part. */
-#define TEST test_par
-#define FOR_EACH gdb::parallel_for_each
-#include "parallel-for-selftests.c"
-#undef FOR_EACH
-#undef TEST
-
-/* Define test_seq using TEST in the FOR_EACH-defined part. */
-#define TEST test_seq
-#define FOR_EACH gdb::sequential_for_each
-#include "parallel-for-selftests.c"
-#undef FOR_EACH
-#undef TEST
+using foreach_callback_t = gdb::function_view<void (int first, int last)>;
+using do_foreach_t = gdb::function_view<void (int first, int last,
+ foreach_callback_t)>;
static void
-test (int n_threads)
+test_one (int n_threads, do_foreach_t do_foreach)
{
- test_par (n_threads);
- test_seq (n_threads);
+ save_restore_n_threads saver;
+ gdb::thread_pool::g_thread_pool->set_thread_count (n_threads);
+
+ {
+ constexpr int upper_bound = 1000;
+ std::atomic<int> counter (0);
+ do_foreach (0, upper_bound,
+ [&] (int start, int end) { counter += end - start; });
+ SELF_CHECK (counter == upper_bound);
+ }
+
+ {
+ std::atomic<int> counter (0);
+ do_foreach (0, 0, [&] (int start, int end) { counter += end - start; });
+ SELF_CHECK (counter == 0);
+ }
+
+ {
+ /* Check that if there are fewer tasks than threads, then we won't
+ end up with a null result. */
+ std::vector<std::unique_ptr<int>> intresults;
+ std::atomic<bool> any_empty_tasks (false);
+
+ do_foreach (0, 1,
+ [&] (int start, int end)
+ {
+ if (start == end)
+ any_empty_tasks = true;
+
+ return std::make_unique<int> (end - start);
+ });
+
+ SELF_CHECK (!any_empty_tasks);
+ SELF_CHECK (std::all_of (intresults.begin (), intresults.end (),
+ [] (const std::unique_ptr<int> &entry)
+ { return entry != nullptr; }));
+ }
}
static void
-test_n_threads ()
+test_parallel_for_each ()
{
- test (0);
- test (1);
- test (3);
+ const std::vector<do_foreach_t> for_each_functions
+ {
+ [] (int start, int end, foreach_callback_t callback)
+ { gdb::parallel_for_each<1> (start, end, callback); },
+ [] (int start, int end, foreach_callback_t callback)
+ { gdb::sequential_for_each (start, end, callback);}
+ };
+
+ for (int n_threads : { 0, 1, 3 })
+ for (const auto &for_each_function : for_each_functions)
+ test_one (n_threads, for_each_function);
}
-}
-}
+} /* namespace parallel_for */
+} /* namespace selftests */
#endif /* CXX_STD_THREAD */
-void _initialize_parallel_for_selftests ();
-void
-_initialize_parallel_for_selftests ()
+INIT_GDB_FILE (parallel_for_selftests)
{
#ifdef CXX_STD_THREAD
selftests::register_test ("parallel_for",
- selftests::parallel_for::test_n_threads);
+ selftests::parallel_for::test_parallel_for_each);
#endif /* CXX_STD_THREAD */
}
-
-#else /* FOR_EACH */
-
-static void
-TEST (int n_threads)
-{
- save_restore_n_threads saver;
- gdb::thread_pool::g_thread_pool->set_thread_count (n_threads);
-
-#define NUMBER 10000
-
- std::atomic<int> counter (0);
- FOR_EACH (1, 0, NUMBER,
- [&] (int start, int end)
- {
- counter += end - start;
- });
- SELF_CHECK (counter == NUMBER);
-
- counter = 0;
- FOR_EACH (1, 0, 0,
- [&] (int start, int end)
- {
- counter += end - start;
- });
- SELF_CHECK (counter == 0);
-
-#undef NUMBER
-
- /* Check that if there are fewer tasks than threads, then we won't
- end up with a null result. */
- std::vector<std::unique_ptr<int>> intresults;
- std::atomic<bool> any_empty_tasks (false);
-
- FOR_EACH (1, 0, 1,
- [&] (int start, int end)
- {
- if (start == end)
- any_empty_tasks = true;
- return std::make_unique<int> (end - start);
- });
- SELF_CHECK (!any_empty_tasks);
- SELF_CHECK (std::all_of (intresults.begin (),
- intresults.end (),
- [] (const std::unique_ptr<int> &entry)
- {
- return entry != nullptr;
- }));
-}
-
-#endif /* FOR_EACH */
diff --git a/gdb/unittests/parse-connection-spec-selftests.c b/gdb/unittests/parse-connection-spec-selftests.c
index 7104272..ce2da35 100644
--- a/gdb/unittests/parse-connection-spec-selftests.c
+++ b/gdb/unittests/parse-connection-spec-selftests.c
@@ -238,9 +238,7 @@ run_tests ()
} /* namespace parse_connection_spec_tests */
} /* namespace selftests */
-void _initialize_parse_connection_spec_selftests ();
-void
-_initialize_parse_connection_spec_selftests ()
+INIT_GDB_FILE (parse_connection_spec_selftests)
{
selftests::register_test ("parse_connection_spec",
selftests::parse_connection_spec_tests::run_tests);
diff --git a/gdb/unittests/path-join-selftests.c b/gdb/unittests/path-join-selftests.c
index a4003f0..8bc5a91 100644
--- a/gdb/unittests/path-join-selftests.c
+++ b/gdb/unittests/path-join-selftests.c
@@ -63,9 +63,7 @@ test ()
}
}
-void _initialize_path_join_selftests ();
-void
-_initialize_path_join_selftests ()
+INIT_GDB_FILE (path_join_selftests)
{
selftests::register_test ("path_join",
selftests::path_join::test);
diff --git a/gdb/unittests/remote-arg-selftests.c b/gdb/unittests/remote-arg-selftests.c
index 70f8a39..17b8d1d 100644
--- a/gdb/unittests/remote-arg-selftests.c
+++ b/gdb/unittests/remote-arg-selftests.c
@@ -156,10 +156,7 @@ self_test ()
} /* namespace remote_args_tests */
} /* namespace selftests */
-void _initialize_remote_arg_selftests ();
-
-void
-_initialize_remote_arg_selftests ()
+INIT_GDB_FILE (remote_arg_selftests)
{
selftests::register_test ("remote-args",
selftests::remote_args_tests::self_test);
diff --git a/gdb/unittests/rsp-low-selftests.c b/gdb/unittests/rsp-low-selftests.c
index 7a1b2de..d0002ae 100644
--- a/gdb/unittests/rsp-low-selftests.c
+++ b/gdb/unittests/rsp-low-selftests.c
@@ -60,9 +60,7 @@ static void test_hex2str ()
} /* namespace rsp_low */
} /* namespace selftests */
-void _initialize_rsp_low_selftests ();
-void
-_initialize_rsp_low_selftests ()
+INIT_GDB_FILE (rsp_low_selftests)
{
selftests::register_test ("hex2bin_byte_vector",
selftests::rsp_low::test_hex2bin_byte_vector);
diff --git a/gdb/unittests/scoped_fd-selftests.c b/gdb/unittests/scoped_fd-selftests.c
index 7abbbd8..da59a18 100644
--- a/gdb/unittests/scoped_fd-selftests.c
+++ b/gdb/unittests/scoped_fd-selftests.c
@@ -92,9 +92,7 @@ run_tests ()
} /* namespace scoped_fd */
} /* namespace selftests */
-void _initialize_scoped_fd_selftests ();
-void
-_initialize_scoped_fd_selftests ()
+INIT_GDB_FILE (scoped_fd_selftests)
{
selftests::register_test ("scoped_fd",
selftests::scoped_fd::run_tests);
diff --git a/gdb/unittests/scoped_ignore_signal-selftests.c b/gdb/unittests/scoped_ignore_signal-selftests.c
index fdfaca3..86c5031 100644
--- a/gdb/unittests/scoped_ignore_signal-selftests.c
+++ b/gdb/unittests/scoped_ignore_signal-selftests.c
@@ -114,9 +114,7 @@ test_sigpipe ()
} /* namespace scoped_ignore_sig */
} /* namespace selftests */
-void _initialize_scoped_ignore_signal_selftests ();
-void
-_initialize_scoped_ignore_signal_selftests ()
+INIT_GDB_FILE (scoped_ignore_signal_selftests)
{
#ifdef SIGPIPE
selftests::register_test ("scoped_ignore_sigpipe",
diff --git a/gdb/unittests/scoped_mmap-selftests.c b/gdb/unittests/scoped_mmap-selftests.c
index 695ed1e..72568fe 100644
--- a/gdb/unittests/scoped_mmap-selftests.c
+++ b/gdb/unittests/scoped_mmap-selftests.c
@@ -135,9 +135,7 @@ run_tests ()
#endif /* !defined(HAVE_SYS_MMAN_H) */
-void _initialize_scoped_mmap_selftests ();
-void
-_initialize_scoped_mmap_selftests ()
+INIT_GDB_FILE (scoped_mmap_selftests)
{
#if defined(HAVE_SYS_MMAN_H)
selftests::register_test ("scoped_mmap",
diff --git a/gdb/unittests/scoped_restore-selftests.c b/gdb/unittests/scoped_restore-selftests.c
index 18d898b..4396046 100644
--- a/gdb/unittests/scoped_restore-selftests.c
+++ b/gdb/unittests/scoped_restore-selftests.c
@@ -102,9 +102,7 @@ run_tests ()
} /* namespace scoped_restore_tests */
} /* namespace selftests */
-void _initialize_scoped_restore_selftests ();
-void
-_initialize_scoped_restore_selftests ()
+INIT_GDB_FILE (scoped_restore_selftests)
{
selftests::register_test ("scoped_restore",
selftests::scoped_restore_tests::run_tests);
diff --git a/gdb/unittests/search-memory-selftests.c b/gdb/unittests/search-memory-selftests.c
index 0e82d6c..c1942fc 100644
--- a/gdb/unittests/search-memory-selftests.c
+++ b/gdb/unittests/search-memory-selftests.c
@@ -89,9 +89,7 @@ run_tests ()
} /* namespace selftests */
-void _initialize_search_memory_selftests ();
-void
-_initialize_search_memory_selftests ()
+INIT_GDB_FILE (search_memory_selftests)
{
selftests::register_test ("search_memory",
selftests::search_memory_tests::run_tests);
diff --git a/gdb/unittests/style-selftests.c b/gdb/unittests/style-selftests.c
index 2cbe194..f2a37bb 100644
--- a/gdb/unittests/style-selftests.c
+++ b/gdb/unittests/style-selftests.c
@@ -100,9 +100,7 @@ run_tests ()
} /* namespace style */
} /* namespace selftests */
-void _initialize_style_selftest ();
-void
-_initialize_style_selftest ()
+INIT_GDB_FILE (style_selftest)
{
selftests::register_test ("style",
selftests::style::run_tests);
diff --git a/gdb/unittests/tracepoint-selftests.c b/gdb/unittests/tracepoint-selftests.c
index 235dd1e..bef51ae 100644
--- a/gdb/unittests/tracepoint-selftests.c
+++ b/gdb/unittests/tracepoint-selftests.c
@@ -60,9 +60,7 @@ test_parse_static_tracepoint_marker_definition ()
} /* namespace tracepoint_tests */
} /* namespace selftests */
-void _initialize_tracepoint_selftests ();
-void
-_initialize_tracepoint_selftests ()
+INIT_GDB_FILE (tracepoint_selftests)
{
selftests::register_test
("parse_static_tracepoint_marker_definition",
diff --git a/gdb/unittests/tui-selftests.c b/gdb/unittests/tui-selftests.c
index e61b0db..5235a07 100644
--- a/gdb/unittests/tui-selftests.c
+++ b/gdb/unittests/tui-selftests.c
@@ -45,9 +45,7 @@ run_tests ()
#endif /* TUI */
-void _initialize_tui_selftest ();
-void
-_initialize_tui_selftest ()
+INIT_GDB_FILE (tui_selftest)
{
#ifdef TUI
selftests::register_test ("tui", selftests::tui::run_tests);
diff --git a/gdb/unittests/ui-file-selftests.c b/gdb/unittests/ui-file-selftests.c
index b62fd4f..d78c6b0 100644
--- a/gdb/unittests/ui-file-selftests.c
+++ b/gdb/unittests/ui-file-selftests.c
@@ -53,9 +53,7 @@ run_tests ()
} /* namespace file*/
} /* namespace selftests */
-void _initialize_ui_file_selftest ();
-void
-_initialize_ui_file_selftest ()
+INIT_GDB_FILE (ui_file_selftest)
{
selftests::register_test ("ui-file",
selftests::file::run_tests);
diff --git a/gdb/unittests/unique_xmalloc_ptr_char.c b/gdb/unittests/unique_xmalloc_ptr_char.c
index 984f692..7f61c06 100644
--- a/gdb/unittests/unique_xmalloc_ptr_char.c
+++ b/gdb/unittests/unique_xmalloc_ptr_char.c
@@ -47,9 +47,7 @@ unique_xmalloc_ptr_char ()
}
}
-void _initialize_unique_xmalloc_ptr_char ();
-void
-_initialize_unique_xmalloc_ptr_char ()
+INIT_GDB_FILE (unique_xmalloc_ptr_char)
{
selftests::register_test ("unique_xmalloc_ptr_char",
selftests::unpack::unique_xmalloc_ptr_char);
diff --git a/gdb/unittests/unpack-selftests.c b/gdb/unittests/unpack-selftests.c
index 54af777..fccf7a2 100644
--- a/gdb/unittests/unpack-selftests.c
+++ b/gdb/unittests/unpack-selftests.c
@@ -52,9 +52,7 @@ unpack_field_as_long_tests (struct gdbarch *arch)
}
}
-void _initialize_unpack_selftests ();
-void
-_initialize_unpack_selftests ()
+INIT_GDB_FILE (unpack_selftests)
{
selftests::register_test_foreach_arch
("unpack_field_as_long", selftests::unpack::unpack_field_as_long_tests);
diff --git a/gdb/unittests/vec-utils-selftests.c b/gdb/unittests/vec-utils-selftests.c
index 4be0b86..11fad31 100644
--- a/gdb/unittests/vec-utils-selftests.c
+++ b/gdb/unittests/vec-utils-selftests.c
@@ -65,9 +65,7 @@ unordered_remove_tests ()
} /* namespace vector_utils_tests */
} /* namespace selftests */
-void _initialize_vec_utils_selftests ();
-void
-_initialize_vec_utils_selftests ()
+INIT_GDB_FILE (vec_utils_selftests)
{
selftests::register_test
("unordered_remove",
diff --git a/gdb/unittests/xml-utils-selftests.c b/gdb/unittests/xml-utils-selftests.c
index 5884faa..f4a637b 100644
--- a/gdb/unittests/xml-utils-selftests.c
+++ b/gdb/unittests/xml-utils-selftests.c
@@ -47,9 +47,7 @@ static void test_xml_escape_text_append ()
}
}
-void _initialize_xml_utils ();
-void
-_initialize_xml_utils ()
+INIT_GDB_FILE (xml_utils)
{
selftests::register_test ("xml_escape_text",
selftests::xml_utils::test_xml_escape_text);
diff --git a/gdb/user-regs.c b/gdb/user-regs.c
index 5860d7d..7170cda 100644
--- a/gdb/user-regs.c
+++ b/gdb/user-regs.c
@@ -237,9 +237,7 @@ maintenance_print_user_registers (const char *args, int from_tty)
}
}
-void _initialize_user_regs ();
-void
-_initialize_user_regs ()
+INIT_GDB_FILE (user_regs)
{
add_cmd ("user-registers", class_maintenance,
maintenance_print_user_registers,
diff --git a/gdb/utils.c b/gdb/utils.c
index 7b0c812..3114a4b 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -54,7 +54,6 @@
#include "top.h"
#include "ui.h"
#include "main.h"
-#include "solist.h"
#include "inferior.h"
@@ -1402,7 +1401,26 @@ pager_file::emit_style_escape (const ui_file_style &style)
{
m_applied_style = style;
if (m_paging)
- m_stream->emit_style_escape (style);
+ {
+ /* Previous style changes will have been sent to m_stream via
+ escape sequences encoded in the m_wrap_buffer. As a result,
+ the m_stream->m_applied_style will not have been updated.
+
+ If we now use m_stream->emit_style_escape, then the required
+ style might not actually be emitted as the requested style
+ might happen to match the out of date value in
+ m_stream->m_applied_style.
+
+ Instead, send the style change directly using m_stream->puts.
+
+ However, we track what style is currently applied to the
+ underlying stream in m_stream_style, this is updated whenever
+ m_wrap_buffer is flushed to the underlying stream. And so, if
+ the style we are applying matches what we know is currently
+ applied to the underlying stream, then we can skip sending
+ this style to the stream. */
+ this->set_stream_style (m_applied_style);
+ }
else
m_wrap_buffer.append (style.to_ansi ());
}
@@ -1425,8 +1443,8 @@ pager_file::prompt_for_continue ()
scoped_restore save_paging = make_scoped_restore (&m_paging, true);
- /* Clear the current styling. */
- m_stream->emit_style_escape (ui_file_style ());
+ /* Clear the current styling on ourselves and the managed stream. */
+ this->emit_style_escape (ui_file_style ());
if (annotation_level > 1)
m_stream->puts (("\n\032\032pre-prompt-for-continue\n"));
@@ -1509,6 +1527,7 @@ pager_file::flush_wrap_buffer ()
if (!m_paging && !m_wrap_buffer.empty ())
{
m_stream->puts (m_wrap_buffer.c_str ());
+ m_stream_style = m_applied_style;
m_wrap_buffer.clear ();
}
}
@@ -1725,7 +1744,8 @@ pager_file::puts (const char *linebuffer)
current applied style to how it was at the WRAP_COLUMN
location. */
m_applied_style = m_wrap_style;
- m_stream->emit_style_escape (ui_file_style ());
+ this->set_stream_style (ui_file_style ());
+
/* If we aren't actually wrapping, don't output
newline -- if chars_per_line is right, we
probably just overflowed anyway; if it's wrong,
@@ -1753,7 +1773,7 @@ pager_file::puts (const char *linebuffer)
/* Having finished inserting the wrapping we should
restore the style as it was at the WRAP_COLUMN. */
- m_stream->emit_style_escape (m_wrap_style);
+ this->set_stream_style (m_wrap_style);
/* The WRAP_BUFFER will still contain content, and that
content might set some alternative style. Restore
@@ -1768,7 +1788,7 @@ pager_file::puts (const char *linebuffer)
m_wrap_column = 0; /* And disable fancy wrap */
}
else if (did_paginate)
- m_stream->emit_style_escape (save_style);
+ this->emit_style_escape (save_style);
}
}
@@ -3333,7 +3353,7 @@ gdb_argv_as_array_view_test ()
argument. */
std::string
-ldirname (const char *filename)
+gdb_ldirname (const char *filename)
{
std::string dirname;
const char *base = lbasename (filename);
@@ -3696,9 +3716,7 @@ test_assign_set_return_if_changed ()
}
#endif
-void _initialize_utils ();
-void
-_initialize_utils ()
+INIT_GDB_FILE (utils)
{
add_setshow_uinteger_cmd ("width", class_support, &chars_per_line, _("\
Set number of characters where GDB should wrap lines of its output."), _("\
diff --git a/gdb/utils.h b/gdb/utils.h
index a8834cf..b37e8f7 100644
--- a/gdb/utils.h
+++ b/gdb/utils.h
@@ -133,7 +133,7 @@ private:
extern int gdb_filename_fnmatch (const char *pattern, const char *string,
int flags);
-std::string ldirname (const char *filename);
+std::string gdb_ldirname (const char *filename);
extern int count_path_elements (const char *path);
diff --git a/gdb/v850-tdep.c b/gdb/v850-tdep.c
index e9ec858..d592344 100644
--- a/gdb/v850-tdep.c
+++ b/gdb/v850-tdep.c
@@ -1461,9 +1461,7 @@ v850_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
return gdbarch;
}
-void _initialize_v850_tdep ();
-void
-_initialize_v850_tdep ()
+INIT_GDB_FILE (v850_tdep)
{
gdbarch_register (bfd_arch_v850, v850_gdbarch_init);
gdbarch_register (bfd_arch_v850_rh850, v850_gdbarch_init);
diff --git a/gdb/valops.c b/gdb/valops.c
index 94f908d..88f3e32 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -4162,9 +4162,7 @@ cast_into_complex (struct type *type, struct value *val)
error (_("cannot cast non-number to complex"));
}
-void _initialize_valops ();
-void
-_initialize_valops ()
+INIT_GDB_FILE (valops)
{
add_setshow_boolean_cmd ("overload-resolution", class_support,
&overload_resolution, _("\
diff --git a/gdb/valprint.c b/gdb/valprint.c
index ed03f6d..305faf7 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -3194,9 +3194,7 @@ test_print_flags (gdbarch *arch)
#endif
-void _initialize_valprint ();
-void
-_initialize_valprint ()
+INIT_GDB_FILE (valprint)
{
#if GDB_SELF_TEST
selftests::register_test_foreach_arch ("print-flags", test_print_flags);
diff --git a/gdb/value.c b/gdb/value.c
index 41dce77..5574642 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -4496,9 +4496,7 @@ test_value_copy ()
} /* namespace selftests */
#endif /* GDB_SELF_TEST */
-void _initialize_values ();
-void
-_initialize_values ()
+INIT_GDB_FILE (values)
{
cmd_list_element *show_convenience_cmd
= add_cmd ("convenience", no_class, show_convenience, _("\
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 8dc7a30..4dc986a 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -2424,9 +2424,7 @@ eq_varobj_and_string (const void *a, const void *b)
return obj->obj_name == name;
}
-void _initialize_varobj ();
-void
-_initialize_varobj ()
+INIT_GDB_FILE (varobj)
{
varobj_table = htab_create_alloc (5, hash_varobj, eq_varobj_and_string,
nullptr, xcalloc, xfree);
diff --git a/gdb/vax-bsd-nat.c b/gdb/vax-bsd-nat.c
index 6d8bb54..717314e 100644
--- a/gdb/vax-bsd-nat.c
+++ b/gdb/vax-bsd-nat.c
@@ -136,9 +136,7 @@ vaxbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
return 1;
}
-void _initialize_vaxbsd_nat ();
-void
-_initialize_vaxbsd_nat ()
+INIT_GDB_FILE (vaxbsd_nat)
{
add_inf_child_target (&the_vax_bsd_nat_target);
diff --git a/gdb/vax-netbsd-tdep.c b/gdb/vax-netbsd-tdep.c
index 34a9150..7781264 100644
--- a/gdb/vax-netbsd-tdep.c
+++ b/gdb/vax-netbsd-tdep.c
@@ -32,13 +32,10 @@ vaxnbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
nbsd_init_abi (info, gdbarch);
/* NetBSD ELF uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
}
-void _initialize_vaxnbsd_tdep ();
-void
-_initialize_vaxnbsd_tdep ()
+INIT_GDB_FILE (vaxnbsd_tdep)
{
gdbarch_register_osabi (bfd_arch_vax, 0, GDB_OSABI_NETBSD,
vaxnbsd_elf_init_abi);
diff --git a/gdb/vax-tdep.c b/gdb/vax-tdep.c
index 94dc308..0a83f4f 100644
--- a/gdb/vax-tdep.c
+++ b/gdb/vax-tdep.c
@@ -506,9 +506,7 @@ vax_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
return (gdbarch);
}
-void _initialize_vax_tdep ();
-void
-_initialize_vax_tdep ()
+INIT_GDB_FILE (vax_tdep)
{
gdbarch_register (bfd_arch_vax, vax_gdbarch_init, NULL);
}
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index 0fee4ad..c001d38 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -56,7 +56,6 @@
#include "cli/cli-style.h"
#include <unistd.h>
#include "exec.h"
-#include "solist.h"
#include "solib.h"
#include "xml-support.h"
#include "inttypes.h"
@@ -433,7 +432,12 @@ wait_for_single (HANDLE handle, DWORD howlong)
{
while (true)
{
- DWORD r = WaitForSingleObject (handle, howlong);
+ /* Using an INFINITE argument to WaitForSingleObject may cause a system
+ deadlock. Avoid it by waiting for a bit in a loop instead. */
+ DWORD milliseconds = howlong == INFINITE ? 100 : howlong;
+ DWORD r = WaitForSingleObject (handle, milliseconds);
+ if (howlong == INFINITE && r == WAIT_TIMEOUT)
+ continue;
if (r == WAIT_OBJECT_0)
return;
if (r == WAIT_FAILED)
@@ -3089,9 +3093,7 @@ windows_nat_target::thread_name (struct thread_info *thr)
}
-void _initialize_windows_nat ();
-void
-_initialize_windows_nat ()
+INIT_GDB_FILE (windows_nat)
{
x86_dr_low.set_control = cygwin_set_dr7;
x86_dr_low.set_addr = cygwin_set_dr;
@@ -3265,9 +3267,7 @@ windows_nat_target::thread_alive (ptid_t ptid)
return WaitForSingleObject (th->h, 0) != WAIT_OBJECT_0;
}
-void _initialize_check_for_gdb_ini ();
-void
-_initialize_check_for_gdb_ini ()
+INIT_GDB_FILE (check_for_gdb_ini)
{
char *homedir;
if (inhibit_gdbinit)
diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c
index 0ba1472..05335d2 100644
--- a/gdb/windows-tdep.c
+++ b/gdb/windows-tdep.c
@@ -36,7 +36,6 @@
#include "gdbcore.h"
#include "coff/internal.h"
#include "libcoff.h"
-#include "solist.h"
#define CYGWIN_DLL_NAME "cygwin1.dll"
@@ -863,10 +862,25 @@ windows_get_siginfo_type (struct gdbarch *gdbarch)
return siginfo_type;
}
+/* solib_ops for Windows systems. */
+
+struct windows_solib_ops : target_solib_ops
+{
+ void create_inferior_hook (int from_tty) const override;
+};
+
+/* Return a new solib_ops for Windows systems. */
+
+static solib_ops_up
+make_windows_solib_ops ()
+{
+ return std::make_unique<windows_solib_ops> ();
+}
+
/* Implement the "solib_create_inferior_hook" solib_ops method. */
-static void
-windows_solib_create_inferior_hook (int from_tty)
+void
+windows_solib_ops::create_inferior_hook (int from_tty) const
{
CORE_ADDR exec_base = 0;
@@ -911,8 +925,6 @@ windows_solib_create_inferior_hook (int from_tty)
}
}
-static solib_ops windows_so_ops;
-
/* Common parts for gdbarch initialization for the Windows and Cygwin OS
ABIs. */
@@ -929,10 +941,7 @@ windows_init_abi_common (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_iterate_over_objfiles_in_search_order
(gdbarch, windows_iterate_over_objfiles_in_search_order);
- windows_so_ops = solib_target_so_ops;
- windows_so_ops.solib_create_inferior_hook
- = windows_solib_create_inferior_hook;
- set_gdbarch_so_ops (gdbarch, &windows_so_ops);
+ set_gdbarch_make_solib_ops (gdbarch, make_windows_solib_ops);
set_gdbarch_get_siginfo_type (gdbarch, windows_get_siginfo_type);
}
@@ -1183,9 +1192,7 @@ windows_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid)
return normal_pid_to_str (ptid);
}
-void _initialize_windows_tdep ();
-void
-_initialize_windows_tdep ()
+INIT_GDB_FILE (windows_tdep)
{
init_w32_command_list ();
cmd_list_element *info_w32_thread_information_block_cmd
diff --git a/gdb/x86-bsd-nat.c b/gdb/x86-bsd-nat.c
index 0c9ddfd..37376bb 100644
--- a/gdb/x86-bsd-nat.c
+++ b/gdb/x86-bsd-nat.c
@@ -128,9 +128,7 @@ x86bsd_dr_get_control (void)
#endif /* PT_GETDBREGS */
-void _initialize_x86_bsd_nat ();
-void
-_initialize_x86_bsd_nat ()
+INIT_GDB_FILE (x86_bsd_nat)
{
#ifdef HAVE_PT_GETDBREGS
x86_dr_low.set_control = x86bsd_dr_set_control;
diff --git a/gdb/x86-gnu-nat.c b/gdb/x86-gnu-nat.c
index b9ba95b..e088189 100644
--- a/gdb/x86-gnu-nat.c
+++ b/gdb/x86-gnu-nat.c
@@ -491,9 +491,7 @@ x86_gnu_dr_get_control (void)
}
#endif /* i386_DEBUG_STATE */
-void _initialize_x86_gnu_nat ();
-void
-_initialize_x86_gnu_nat ()
+INIT_GDB_FILE (x86_gnu_nat)
{
#ifdef i386_DEBUG_STATE
x86_dr_low.set_control = x86_gnu_dr_set_control;
diff --git a/gdb/x86-linux-nat.c b/gdb/x86-linux-nat.c
index fc7c5f6..81db5d8 100644
--- a/gdb/x86-linux-nat.c
+++ b/gdb/x86-linux-nat.c
@@ -210,9 +210,7 @@ x86_linux_get_thread_area (pid_t pid, void *addr, unsigned int *base_addr)
}
-void _initialize_x86_linux_nat ();
-void
-_initialize_x86_linux_nat ()
+INIT_GDB_FILE (x86_linux_nat)
{
/* Initialize the debug register function vectors. */
x86_dr_low.set_control = x86_linux_dr_set_control;
diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c
index e91c64c..70585b3 100644
--- a/gdb/xcoffread.c
+++ b/gdb/xcoffread.c
@@ -2999,9 +2999,7 @@ xcoff_get_n_import_files (bfd *abfd)
return l_nimpid - 1;
}
-void _initialize_xcoffread ();
-void
-_initialize_xcoffread ()
+INIT_GDB_FILE (xcoffread)
{
add_symtab_fns (bfd_target_xcoff_flavour, &xcoff_sym_fns);
}
diff --git a/gdb/xml-support.c b/gdb/xml-support.c
index fb8b612..08524f8 100644
--- a/gdb/xml-support.c
+++ b/gdb/xml-support.c
@@ -999,10 +999,7 @@ xml_fetch_content_from_file (const char *filename, const char *dirname)
return text;
}
-void _initialize_xml_support ();
-void _initialize_xml_support ();
-void
-_initialize_xml_support ()
+INIT_GDB_FILE (xml_support)
{
add_setshow_boolean_cmd ("xml", class_maintenance, &debug_xml,
_("Set XML parser debugging."),
diff --git a/gdb/xml-syscall.c b/gdb/xml-syscall.c
index fe0ea2b..b58fe5d0 100644
--- a/gdb/xml-syscall.c
+++ b/gdb/xml-syscall.c
@@ -319,7 +319,7 @@ xml_init_syscalls_info (const char *filename)
if (!full_file)
return NULL;
- const std::string dirname = ldirname (filename);
+ const std::string dirname = gdb_ldirname (filename);
auto fetch_another = [&dirname] (const char *name)
{
return xml_fetch_content_from_file (name, dirname.c_str ());
diff --git a/gdb/xml-tdesc.c b/gdb/xml-tdesc.c
index 6c095af..2f213dc 100644
--- a/gdb/xml-tdesc.c
+++ b/gdb/xml-tdesc.c
@@ -670,7 +670,7 @@ file_read_description_xml (const char *filename)
return NULL;
}
- const std::string dirname = ldirname (filename);
+ const std::string dirname = gdb_ldirname (filename);
auto fetch_another = [&dirname] (const char *name)
{
return xml_fetch_content_from_file (name, dirname.c_str ());
diff --git a/gdb/xstormy16-tdep.c b/gdb/xstormy16-tdep.c
index 8482461..b4042f1 100644
--- a/gdb/xstormy16-tdep.c
+++ b/gdb/xstormy16-tdep.c
@@ -828,9 +828,7 @@ xstormy16_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
Initializer function for the Sanyo Xstormy16a module.
Called by gdb at start-up. */
-void _initialize_xstormy16_tdep ();
-void
-_initialize_xstormy16_tdep ()
+INIT_GDB_FILE (xstormy16_tdep)
{
gdbarch_register (bfd_arch_xstormy16, xstormy16_gdbarch_init);
}
diff --git a/gdb/xtensa-linux-nat.c b/gdb/xtensa-linux-nat.c
index 11fbf55..4a50f38 100644
--- a/gdb/xtensa-linux-nat.c
+++ b/gdb/xtensa-linux-nat.c
@@ -327,9 +327,7 @@ ps_get_thread_area (struct ps_prochandle *ph,
return PS_OK;
}
-void _initialize_xtensa_linux_nat ();
-void
-_initialize_xtensa_linux_nat ()
+INIT_GDB_FILE (xtensa_linux_nat)
{
const xtensa_regtable_t *ptr;
diff --git a/gdb/xtensa-linux-tdep.c b/gdb/xtensa-linux-tdep.c
index b72d683..7792408 100644
--- a/gdb/xtensa-linux-tdep.c
+++ b/gdb/xtensa-linux-tdep.c
@@ -20,6 +20,7 @@
#include "xtensa-tdep.h"
#include "osabi.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "solib-svr4.h"
#include "symtab.h"
#include "gdbarch.h"
@@ -111,8 +112,7 @@ xtensa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
linux_init_abi (info, gdbarch, 0);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_linux_ilp32_svr4_solib_ops);
set_gdbarch_gdb_signal_from_target (gdbarch,
xtensa_linux_gdb_signal_from_target);
@@ -124,9 +124,7 @@ xtensa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
svr4_fetch_objfile_link_map);
}
-void _initialize_xtensa_linux_tdep ();
-void
-_initialize_xtensa_linux_tdep ()
+INIT_GDB_FILE (xtensa_linux_tdep)
{
gdbarch_register_osabi (bfd_arch_xtensa, bfd_mach_xtensa, GDB_OSABI_LINUX,
xtensa_linux_init_abi);
diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c
index a4bbffb..8a2f129 100644
--- a/gdb/xtensa-tdep.c
+++ b/gdb/xtensa-tdep.c
@@ -3238,8 +3238,7 @@ xtensa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_iterate_over_regset_sections
(gdbarch, xtensa_iterate_over_regset_sections);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, make_svr4_ilp32_solib_ops);
/* Hook in the ABI-specific overrides, if they have been registered. */
gdbarch_init_osabi (info, gdbarch);
@@ -3253,9 +3252,7 @@ xtensa_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
error (_("xtensa_dump_tdep(): not implemented"));
}
-void _initialize_xtensa_tdep ();
-void
-_initialize_xtensa_tdep ()
+INIT_GDB_FILE (xtensa_tdep)
{
gdbarch_register (bfd_arch_xtensa, xtensa_gdbarch_init, xtensa_dump_tdep);
xtensa_init_reggroups ();
diff --git a/gdb/z80-tdep.c b/gdb/z80-tdep.c
index bfa52dd..abba50b 100644
--- a/gdb/z80-tdep.c
+++ b/gdb/z80-tdep.c
@@ -1331,14 +1331,14 @@ ez80_ddfd_insn_table[] =
{ 0007, 0307, 2, insn_default }, //"ld rr,(ii+d)"
{ 0061, 0377, 2, insn_default }, //"ld ii,(ii+d)"
/* common instructions */
- { 0011, 0367, 2, insn_default }, //"add ii,rr"
+ { 0011, 0317, 1, insn_default }, //"add ii,rr"
{ 0041, 0377, 3, insn_default }, //"ld ii,nn"
{ 0042, 0367, 3, insn_default }, //"ld (nn),ii", "ld ii,(nn)"
{ 0043, 0367, 1, insn_default }, //"inc ii", "dec ii"
{ 0044, 0366, 1, insn_default }, //"inc/dec iih/iil"
{ 0046, 0367, 2, insn_default }, //"ld iih,n", "ld iil,n"
{ 0064, 0376, 2, insn_default }, //"inc (ii+d)", "dec (ii+d)"
- { 0066, 0377, 2, insn_default }, //"ld (ii+d),n"
+ { 0066, 0377, 3, insn_default }, //"ld (ii+d),n"
{ 0166, 0377, 0, insn_default }, //not an instruction
{ 0160, 0370, 2, insn_default }, //"ld (ii+d),r"
{ 0104, 0306, 1, insn_default }, //"ld r,iih", "ld r,iil"
@@ -1360,7 +1360,7 @@ ez80_adl_ddfd_insn_table[] =
{
{ 0007, 0307, 2, insn_default }, //"ld rr,(ii+d)"
{ 0061, 0377, 2, insn_default }, //"ld ii,(ii+d)"
- { 0011, 0367, 1, insn_default }, //"add ii,rr"
+ { 0011, 0317, 1, insn_default }, //"add ii,rr"
{ 0041, 0377, 4, insn_default }, //"ld ii,nn"
{ 0042, 0367, 4, insn_default }, //"ld (nn),ii", "ld ii,(nn)"
{ 0043, 0367, 1, insn_default }, //"inc ii", "dec ii"
@@ -1455,10 +1455,7 @@ z80_get_insn_info (struct gdbarch *gdbarch, const gdb_byte *buf, int *size)
while (1);
}
-extern initialize_file_ftype _initialize_z80_tdep;
-
-void
-_initialize_z80_tdep ()
+INIT_GDB_FILE (z80_tdep)
{
gdbarch_register (bfd_arch_z80, z80_gdbarch_init);
initialize_tdesc_z80 ();