binutils-gdb/gdb/s390-linux-nat.c
Simon Marchi 6c2659886f gdb: add back declarations for _initialize functions
I'd like to enable the -Wmissing-declarations warning.  However, it
warns for every _initialize function, for example:

      CXX    dcache.o
    /home/smarchi/src/binutils-gdb/gdb/dcache.c: In function ‘void _initialize_dcache()’:
    /home/smarchi/src/binutils-gdb/gdb/dcache.c:688:1: error: no previous declaration for ‘void _initialize_dcache()’ [-Werror=missing-declarations]
     _initialize_dcache (void)
     ^~~~~~~~~~~~~~~~~~

The only practical way forward I found is to add back the declarations,
which were removed by this commit:

    commit 481695ed5f
    Author: John Baldwin <jhb@FreeBSD.org>
    Date:   Sat Sep 9 11:02:37 2017 -0700

        Remove unnecessary function prototypes.

I don't think it's a big problem to have the declarations for these
functions, but if anybody has a better solution for this, I'll be happy
to use it.

gdb/ChangeLog:

	* aarch64-fbsd-nat.c (_initialize_aarch64_fbsd_nat): Add declaration.
	* aarch64-fbsd-tdep.c (_initialize_aarch64_fbsd_tdep): Add declaration.
	* aarch64-linux-nat.c (_initialize_aarch64_linux_nat): Add declaration.
	* aarch64-linux-tdep.c (_initialize_aarch64_linux_tdep): Add declaration.
	* aarch64-newlib-tdep.c (_initialize_aarch64_newlib_tdep): Add declaration.
	* aarch64-tdep.c (_initialize_aarch64_tdep): Add declaration.
	* ada-exp.y (_initialize_ada_exp): Add declaration.
	* ada-lang.c (_initialize_ada_language): Add declaration.
	* ada-tasks.c (_initialize_tasks): Add declaration.
	* agent.c (_initialize_agent): Add declaration.
	* aix-thread.c (_initialize_aix_thread): Add declaration.
	* alpha-bsd-nat.c (_initialize_alphabsd_nat): Add declaration.
	* alpha-linux-nat.c (_initialize_alpha_linux_nat): Add declaration.
	* alpha-linux-tdep.c (_initialize_alpha_linux_tdep): Add declaration.
	* alpha-nbsd-tdep.c (_initialize_alphanbsd_tdep): Add declaration.
	* alpha-obsd-tdep.c (_initialize_alphaobsd_tdep): Add declaration.
	* alpha-tdep.c (_initialize_alpha_tdep): Add declaration.
	* amd64-darwin-tdep.c (_initialize_amd64_darwin_tdep): Add declaration.
	* amd64-dicos-tdep.c (_initialize_amd64_dicos_tdep): Add declaration.
	* amd64-fbsd-nat.c (_initialize_amd64fbsd_nat): Add declaration.
	* amd64-fbsd-tdep.c (_initialize_amd64fbsd_tdep): Add declaration.
	* amd64-linux-nat.c (_initialize_amd64_linux_nat): Add declaration.
	* amd64-linux-tdep.c (_initialize_amd64_linux_tdep): Add declaration.
	* amd64-nbsd-nat.c (_initialize_amd64nbsd_nat): Add declaration.
	* amd64-nbsd-tdep.c (_initialize_amd64nbsd_tdep): Add declaration.
	* amd64-obsd-nat.c (_initialize_amd64obsd_nat): Add declaration.
	* amd64-obsd-tdep.c (_initialize_amd64obsd_tdep): Add declaration.
	* amd64-sol2-tdep.c (_initialize_amd64_sol2_tdep): Add declaration.
	* amd64-tdep.c (_initialize_amd64_tdep): Add declaration.
	* amd64-windows-nat.c (_initialize_amd64_windows_nat): Add declaration.
	* amd64-windows-tdep.c (_initialize_amd64_windows_tdep): Add declaration.
	* annotate.c (_initialize_annotate): Add declaration.
	* arc-newlib-tdep.c (_initialize_arc_newlib_tdep): Add declaration.
	* arc-tdep.c (_initialize_arc_tdep): Add declaration.
	* arch-utils.c (_initialize_gdbarch_utils): Add declaration.
	* arm-fbsd-nat.c (_initialize_arm_fbsd_nat): Add declaration.
	* arm-fbsd-tdep.c (_initialize_arm_fbsd_tdep): Add declaration.
	* arm-linux-nat.c (_initialize_arm_linux_nat): Add declaration.
	* arm-linux-tdep.c (_initialize_arm_linux_tdep): Add declaration.
	* arm-nbsd-nat.c (_initialize_arm_netbsd_nat): Add declaration.
	* arm-nbsd-tdep.c (_initialize_arm_netbsd_tdep): Add declaration.
	* arm-obsd-tdep.c (_initialize_armobsd_tdep): Add declaration.
	* arm-pikeos-tdep.c (_initialize_arm_pikeos_tdep): Add declaration.
	* arm-symbian-tdep.c (_initialize_arm_symbian_tdep): Add declaration.
	* arm-tdep.c (_initialize_arm_tdep): Add declaration.
	* arm-wince-tdep.c (_initialize_arm_wince_tdep): Add declaration.
	* auto-load.c (_initialize_auto_load): Add declaration.
	* auxv.c (_initialize_auxv): Add declaration.
	* avr-tdep.c (_initialize_avr_tdep): Add declaration.
	* ax-gdb.c (_initialize_ax_gdb): Add declaration.
	* bfin-linux-tdep.c (_initialize_bfin_linux_tdep): Add declaration.
	* bfin-tdep.c (_initialize_bfin_tdep): Add declaration.
	* break-catch-sig.c (_initialize_break_catch_sig): Add declaration.
	* break-catch-syscall.c (_initialize_break_catch_syscall): Add declaration.
	* break-catch-throw.c (_initialize_break_catch_throw): Add declaration.
	* breakpoint.c (_initialize_breakpoint): Add declaration.
	* bsd-uthread.c (_initialize_bsd_uthread): Add declaration.
	* btrace.c (_initialize_btrace): Add declaration.
	* charset.c (_initialize_charset): Add declaration.
	* cli/cli-cmds.c (_initialize_cli_cmds): Add declaration.
	* cli/cli-dump.c (_initialize_cli_dump): Add declaration.
	* cli/cli-interp.c (_initialize_cli_interp): Add declaration.
	* cli/cli-logging.c (_initialize_cli_logging): Add declaration.
	* cli/cli-script.c (_initialize_cli_script): Add declaration.
	* cli/cli-style.c (_initialize_cli_style): Add declaration.
	* coff-pe-read.c (_initialize_coff_pe_read): Add declaration.
	* coffread.c (_initialize_coffread): Add declaration.
	* compile/compile-cplus-types.c (_initialize_compile_cplus_types): Add declaration.
	* compile/compile.c (_initialize_compile): Add declaration.
	* complaints.c (_initialize_complaints): Add declaration.
	* completer.c (_initialize_completer): Add declaration.
	* copying.c (_initialize_copying): Add declaration.
	* corefile.c (_initialize_core): Add declaration.
	* corelow.c (_initialize_corelow): Add declaration.
	* cp-abi.c (_initialize_cp_abi): Add declaration.
	* cp-namespace.c (_initialize_cp_namespace): Add declaration.
	* cp-support.c (_initialize_cp_support): Add declaration.
	* cp-valprint.c (_initialize_cp_valprint): Add declaration.
	* cris-linux-tdep.c (_initialize_cris_linux_tdep): Add declaration.
	* cris-tdep.c (_initialize_cris_tdep): Add declaration.
	* csky-linux-tdep.c (_initialize_csky_linux_tdep): Add declaration.
	* csky-tdep.c (_initialize_csky_tdep): Add declaration.
	* ctfread.c (_initialize_ctfread): Add declaration.
	* d-lang.c (_initialize_d_language): Add declaration.
	* darwin-nat-info.c (_initialize_darwin_info_commands): Add declaration.
	* darwin-nat.c (_initialize_darwin_nat): Add declaration.
	* dbxread.c (_initialize_dbxread): Add declaration.
	* dcache.c (_initialize_dcache): Add declaration.
	* disasm-selftests.c (_initialize_disasm_selftests): Add declaration.
	* disasm.c (_initialize_disasm): Add declaration.
	* dtrace-probe.c (_initialize_dtrace_probe): Add declaration.
	* dummy-frame.c (_initialize_dummy_frame): Add declaration.
	* dwarf-index-cache.c (_initialize_index_cache): Add declaration.
	* dwarf-index-write.c (_initialize_dwarf_index_write): Add declaration.
	* dwarf2-frame-tailcall.c (_initialize_tailcall_frame): Add declaration.
	* dwarf2-frame.c (_initialize_dwarf2_frame): Add declaration.
	* dwarf2expr.c (_initialize_dwarf2expr): Add declaration.
	* dwarf2loc.c (_initialize_dwarf2loc): Add declaration.
	* dwarf2read.c (_initialize_dwarf2_read): Add declaration.
	* elfread.c (_initialize_elfread): Add declaration.
	* exec.c (_initialize_exec): Add declaration.
	* extension.c (_initialize_extension): Add declaration.
	* f-lang.c (_initialize_f_language): Add declaration.
	* f-valprint.c (_initialize_f_valprint): Add declaration.
	* fbsd-nat.c (_initialize_fbsd_nat): Add declaration.
	* fbsd-tdep.c (_initialize_fbsd_tdep): Add declaration.
	* filesystem.c (_initialize_filesystem): Add declaration.
	* findcmd.c (_initialize_mem_search): Add declaration.
	* findvar.c (_initialize_findvar): Add declaration.
	* fork-child.c (_initialize_fork_child): Add declaration.
	* frame-base.c (_initialize_frame_base): Add declaration.
	* frame-unwind.c (_initialize_frame_unwind): Add declaration.
	* frame.c (_initialize_frame): Add declaration.
	* frv-linux-tdep.c (_initialize_frv_linux_tdep): Add declaration.
	* frv-tdep.c (_initialize_frv_tdep): Add declaration.
	* ft32-tdep.c (_initialize_ft32_tdep): Add declaration.
	* gcore.c (_initialize_gcore): Add declaration.
	* gdb-demangle.c (_initialize_gdb_demangle): Add declaration.
	* gdb_bfd.c (_initialize_gdb_bfd): Add declaration.
	* gdbarch-selftests.c (_initialize_gdbarch_selftests): Add declaration.
	* gdbarch.c (_initialize_gdbarch): Add declaration.
	* gdbtypes.c (_initialize_gdbtypes): Add declaration.
	* gnu-nat.c (_initialize_gnu_nat): Add declaration.
	* gnu-v2-abi.c (_initialize_gnu_v2_abi): Add declaration.
	* gnu-v3-abi.c (_initialize_gnu_v3_abi): Add declaration.
	* go-lang.c (_initialize_go_language): Add declaration.
	* go32-nat.c (_initialize_go32_nat): Add declaration.
	* guile/guile.c (_initialize_guile): Add declaration.
	* h8300-tdep.c (_initialize_h8300_tdep): Add declaration.
	* hppa-linux-nat.c (_initialize_hppa_linux_nat): Add declaration.
	* hppa-linux-tdep.c (_initialize_hppa_linux_tdep): Add declaration.
	* hppa-nbsd-nat.c (_initialize_hppanbsd_nat): Add declaration.
	* hppa-nbsd-tdep.c (_initialize_hppanbsd_tdep): Add declaration.
	* hppa-obsd-nat.c (_initialize_hppaobsd_nat): Add declaration.
	* hppa-obsd-tdep.c (_initialize_hppabsd_tdep): Add declaration.
	* hppa-tdep.c (_initialize_hppa_tdep): Add declaration.
	* i386-bsd-nat.c (_initialize_i386bsd_nat): Add declaration.
	* i386-cygwin-tdep.c (_initialize_i386_cygwin_tdep): Add declaration.
	* i386-darwin-nat.c (_initialize_i386_darwin_nat): Add declaration.
	* i386-darwin-tdep.c (_initialize_i386_darwin_tdep): Add declaration.
	* i386-dicos-tdep.c (_initialize_i386_dicos_tdep): Add declaration.
	* i386-fbsd-nat.c (_initialize_i386fbsd_nat): Add declaration.
	* i386-fbsd-tdep.c (_initialize_i386fbsd_tdep): Add declaration.
	* i386-gnu-nat.c (_initialize_i386gnu_nat): Add declaration.
	* i386-gnu-tdep.c (_initialize_i386gnu_tdep): Add declaration.
	* i386-go32-tdep.c (_initialize_i386_go32_tdep): Add declaration.
	* i386-linux-nat.c (_initialize_i386_linux_nat): Add declaration.
	* i386-linux-tdep.c (_initialize_i386_linux_tdep): Add declaration.
	* i386-nbsd-nat.c (_initialize_i386nbsd_nat): Add declaration.
	* i386-nbsd-tdep.c (_initialize_i386nbsd_tdep): Add declaration.
	* i386-nto-tdep.c (_initialize_i386nto_tdep): Add declaration.
	* i386-obsd-nat.c (_initialize_i386obsd_nat): Add declaration.
	* i386-obsd-tdep.c (_initialize_i386obsd_tdep): Add declaration.
	* i386-sol2-nat.c (_initialize_amd64_sol2_nat): Add declaration.
	* i386-sol2-tdep.c (_initialize_i386_sol2_tdep): Add declaration.
	* i386-tdep.c (_initialize_i386_tdep): Add declaration.
	* i386-windows-nat.c (_initialize_i386_windows_nat): Add declaration.
	* ia64-libunwind-tdep.c (_initialize_libunwind_frame): Add declaration.
	* ia64-linux-nat.c (_initialize_ia64_linux_nat): Add declaration.
	* ia64-linux-tdep.c (_initialize_ia64_linux_tdep): Add declaration.
	* ia64-tdep.c (_initialize_ia64_tdep): Add declaration.
	* ia64-vms-tdep.c (_initialize_ia64_vms_tdep): Add declaration.
	* infcall.c (_initialize_infcall): Add declaration.
	* infcmd.c (_initialize_infcmd): Add declaration.
	* inflow.c (_initialize_inflow): Add declaration.
	* infrun.c (_initialize_infrun): Add declaration.
	* interps.c (_initialize_interpreter): Add declaration.
	* iq2000-tdep.c (_initialize_iq2000_tdep): Add declaration.
	* jit.c (_initialize_jit): Add declaration.
	* language.c (_initialize_language): Add declaration.
	* linux-fork.c (_initialize_linux_fork): Add declaration.
	* linux-nat.c (_initialize_linux_nat): Add declaration.
	* linux-tdep.c (_initialize_linux_tdep): Add declaration.
	* linux-thread-db.c (_initialize_thread_db): Add declaration.
	* lm32-tdep.c (_initialize_lm32_tdep): Add declaration.
	* m2-lang.c (_initialize_m2_language): Add declaration.
	* m32c-tdep.c (_initialize_m32c_tdep): Add declaration.
	* m32r-linux-nat.c (_initialize_m32r_linux_nat): Add declaration.
	* m32r-linux-tdep.c (_initialize_m32r_linux_tdep): Add declaration.
	* m32r-tdep.c (_initialize_m32r_tdep): Add declaration.
	* m68hc11-tdep.c (_initialize_m68hc11_tdep): Add declaration.
	* m68k-bsd-nat.c (_initialize_m68kbsd_nat): Add declaration.
	* m68k-bsd-tdep.c (_initialize_m68kbsd_tdep): Add declaration.
	* m68k-linux-nat.c (_initialize_m68k_linux_nat): Add declaration.
	* m68k-linux-tdep.c (_initialize_m68k_linux_tdep): Add declaration.
	* m68k-tdep.c (_initialize_m68k_tdep): Add declaration.
	* machoread.c (_initialize_machoread): Add declaration.
	* macrocmd.c (_initialize_macrocmd): Add declaration.
	* macroscope.c (_initialize_macroscope): Add declaration.
	* maint-test-options.c (_initialize_maint_test_options): Add declaration.
	* maint-test-settings.c (_initialize_maint_test_settings): Add declaration.
	* maint.c (_initialize_maint_cmds): Add declaration.
	* mdebugread.c (_initialize_mdebugread): Add declaration.
	* memattr.c (_initialize_mem): Add declaration.
	* mep-tdep.c (_initialize_mep_tdep): Add declaration.
	* mi/mi-cmd-env.c (_initialize_mi_cmd_env): Add declaration.
	* mi/mi-cmds.c (_initialize_mi_cmds): Add declaration.
	* mi/mi-interp.c (_initialize_mi_interp): Add declaration.
	* mi/mi-main.c (_initialize_mi_main): Add declaration.
	* microblaze-linux-tdep.c (_initialize_microblaze_linux_tdep): Add declaration.
	* microblaze-tdep.c (_initialize_microblaze_tdep): Add declaration.
	* mips-fbsd-nat.c (_initialize_mips_fbsd_nat): Add declaration.
	* mips-fbsd-tdep.c (_initialize_mips_fbsd_tdep): Add declaration.
	* mips-linux-nat.c (_initialize_mips_linux_nat): Add declaration.
	* mips-linux-tdep.c (_initialize_mips_linux_tdep): Add declaration.
	* mips-nbsd-nat.c (_initialize_mipsnbsd_nat): Add declaration.
	* mips-nbsd-tdep.c (_initialize_mipsnbsd_tdep): Add declaration.
	* mips-sde-tdep.c (_initialize_mips_sde_tdep): Add declaration.
	* mips-tdep.c (_initialize_mips_tdep): Add declaration.
	* mips64-obsd-nat.c (_initialize_mips64obsd_nat): Add declaration.
	* mips64-obsd-tdep.c (_initialize_mips64obsd_tdep): Add declaration.
	* mipsread.c (_initialize_mipsread): Add declaration.
	* mn10300-linux-tdep.c (_initialize_mn10300_linux_tdep): Add declaration.
	* mn10300-tdep.c (_initialize_mn10300_tdep): Add declaration.
	* moxie-tdep.c (_initialize_moxie_tdep): Add declaration.
	* msp430-tdep.c (_initialize_msp430_tdep): Add declaration.
	* nds32-tdep.c (_initialize_nds32_tdep): Add declaration.
	* nios2-linux-tdep.c (_initialize_nios2_linux_tdep): Add declaration.
	* nios2-tdep.c (_initialize_nios2_tdep): Add declaration.
	* nto-procfs.c (_initialize_procfs): Add declaration.
	* objc-lang.c (_initialize_objc_language): Add declaration.
	* observable.c (_initialize_observer): Add declaration.
	* opencl-lang.c (_initialize_opencl_language): Add declaration.
	* or1k-linux-tdep.c (_initialize_or1k_linux_tdep): Add declaration.
	* or1k-tdep.c (_initialize_or1k_tdep): Add declaration.
	* osabi.c (_initialize_gdb_osabi): Add declaration.
	* osdata.c (_initialize_osdata): Add declaration.
	* p-valprint.c (_initialize_pascal_valprint): Add declaration.
	* parse.c (_initialize_parse): Add declaration.
	* ppc-fbsd-nat.c (_initialize_ppcfbsd_nat): Add declaration.
	* ppc-fbsd-tdep.c (_initialize_ppcfbsd_tdep): Add declaration.
	* ppc-linux-nat.c (_initialize_ppc_linux_nat): Add declaration.
	* ppc-linux-tdep.c (_initialize_ppc_linux_tdep): Add declaration.
	* ppc-nbsd-nat.c (_initialize_ppcnbsd_nat): Add declaration.
	* ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Add declaration.
	* ppc-obsd-nat.c (_initialize_ppcobsd_nat): Add declaration.
	* ppc-obsd-tdep.c (_initialize_ppcobsd_tdep): Add declaration.
	* printcmd.c (_initialize_printcmd): Add declaration.
	* probe.c (_initialize_probe): Add declaration.
	* proc-api.c (_initialize_proc_api): Add declaration.
	* proc-events.c (_initialize_proc_events): Add declaration.
	* proc-service.c (_initialize_proc_service): Add declaration.
	* procfs.c (_initialize_procfs): Add declaration.
	* producer.c (_initialize_producer): Add declaration.
	* psymtab.c (_initialize_psymtab): Add declaration.
	* python/python.c (_initialize_python): Add declaration.
	* ravenscar-thread.c (_initialize_ravenscar): Add declaration.
	* record-btrace.c (_initialize_record_btrace): Add declaration.
	* record-full.c (_initialize_record_full): Add declaration.
	* record.c (_initialize_record): Add declaration.
	* regcache-dump.c (_initialize_regcache_dump): Add declaration.
	* regcache.c (_initialize_regcache): Add declaration.
	* reggroups.c (_initialize_reggroup): Add declaration.
	* remote-notif.c (_initialize_notif): Add declaration.
	* remote-sim.c (_initialize_remote_sim): Add declaration.
	* remote.c (_initialize_remote): Add declaration.
	* reverse.c (_initialize_reverse): Add declaration.
	* riscv-fbsd-nat.c (_initialize_riscv_fbsd_nat): Add declaration.
	* riscv-fbsd-tdep.c (_initialize_riscv_fbsd_tdep): Add declaration.
	* riscv-linux-nat.c (_initialize_riscv_linux_nat): Add declaration.
	* riscv-linux-tdep.c (_initialize_riscv_linux_tdep): Add declaration.
	* riscv-tdep.c (_initialize_riscv_tdep): Add declaration.
	* rl78-tdep.c (_initialize_rl78_tdep): Add declaration.
	* rs6000-aix-tdep.c (_initialize_rs6000_aix_tdep): Add declaration.
	* rs6000-lynx178-tdep.c (_initialize_rs6000_lynx178_tdep):
	Add declaration.
	* rs6000-nat.c (_initialize_rs6000_nat): Add declaration.
	* rs6000-tdep.c (_initialize_rs6000_tdep): Add declaration.
	* run-on-main-thread.c (_initialize_run_on_main_thread): Add declaration.
	* rust-exp.y (_initialize_rust_exp): Add declaration.
	* rx-tdep.c (_initialize_rx_tdep): Add declaration.
	* s12z-tdep.c (_initialize_s12z_tdep): Add declaration.
	* s390-linux-nat.c (_initialize_s390_nat): Add declaration.
	* s390-linux-tdep.c (_initialize_s390_linux_tdep): Add declaration.
	* s390-tdep.c (_initialize_s390_tdep): Add declaration.
	* score-tdep.c (_initialize_score_tdep): Add declaration.
	* ser-go32.c (_initialize_ser_dos): Add declaration.
	* ser-mingw.c (_initialize_ser_windows): Add declaration.
	* ser-pipe.c (_initialize_ser_pipe): Add declaration.
	* ser-tcp.c (_initialize_ser_tcp): Add declaration.
	* ser-uds.c (_initialize_ser_socket): Add declaration.
	* ser-unix.c (_initialize_ser_hardwire): Add declaration.
	* serial.c (_initialize_serial): Add declaration.
	* sh-linux-tdep.c (_initialize_sh_linux_tdep): Add declaration.
	* sh-nbsd-nat.c (_initialize_shnbsd_nat): Add declaration.
	* sh-nbsd-tdep.c (_initialize_shnbsd_tdep): Add declaration.
	* sh-tdep.c (_initialize_sh_tdep): Add declaration.
	* skip.c (_initialize_step_skip): Add declaration.
	* sol-thread.c (_initialize_sol_thread): Add declaration.
	* solib-aix.c (_initialize_solib_aix): Add declaration.
	* solib-darwin.c (_initialize_darwin_solib): Add declaration.
	* solib-dsbt.c (_initialize_dsbt_solib): Add declaration.
	* solib-frv.c (_initialize_frv_solib): Add declaration.
	* solib-svr4.c (_initialize_svr4_solib): Add declaration.
	* solib-target.c (_initialize_solib_target): Add declaration.
	* solib.c (_initialize_solib): Add declaration.
	* source-cache.c (_initialize_source_cache): Add declaration.
	* source.c (_initialize_source): Add declaration.
	* sparc-linux-nat.c (_initialize_sparc_linux_nat): Add declaration.
	* sparc-linux-tdep.c (_initialize_sparc_linux_tdep): Add declaration.
	* sparc-nat.c (_initialize_sparc_nat): Add declaration.
	* sparc-nbsd-nat.c (_initialize_sparcnbsd_nat): Add declaration.
	* sparc-nbsd-tdep.c (_initialize_sparcnbsd_tdep): Add declaration.
	* sparc-obsd-tdep.c (_initialize_sparc32obsd_tdep): Add declaration.
	* sparc-sol2-tdep.c (_initialize_sparc_sol2_tdep): Add declaration.
	* sparc-tdep.c (_initialize_sparc_tdep): Add declaration.
	* sparc64-fbsd-nat.c (_initialize_sparc64fbsd_nat): Add declaration.
	* sparc64-fbsd-tdep.c (_initialize_sparc64fbsd_tdep): Add declaration.
	* sparc64-linux-nat.c (_initialize_sparc64_linux_nat): Add declaration.
	* sparc64-linux-tdep.c (_initialize_sparc64_linux_tdep): Add declaration.
	* sparc64-nat.c (_initialize_sparc64_nat): Add declaration.
	* sparc64-nbsd-nat.c (_initialize_sparc64nbsd_nat): Add declaration.
	* sparc64-nbsd-tdep.c (_initialize_sparc64nbsd_tdep): Add declaration.
	* sparc64-obsd-nat.c (_initialize_sparc64obsd_nat): Add declaration.
	* sparc64-obsd-tdep.c (_initialize_sparc64obsd_tdep): Add declaration.
	* sparc64-sol2-tdep.c (_initialize_sparc64_sol2_tdep): Add declaration.
	* sparc64-tdep.c (_initialize_sparc64_adi_tdep): Add declaration.
	* stabsread.c (_initialize_stabsread): Add declaration.
	* stack.c (_initialize_stack): Add declaration.
	* stap-probe.c (_initialize_stap_probe): Add declaration.
	* std-regs.c (_initialize_frame_reg): Add declaration.
	* symfile-debug.c (_initialize_symfile_debug): Add declaration.
	* symfile-mem.c (_initialize_symfile_mem): Add declaration.
	* symfile.c (_initialize_symfile): Add declaration.
	* symmisc.c (_initialize_symmisc): Add declaration.
	* symtab.c (_initialize_symtab): Add declaration.
	* target.c (_initialize_target): Add declaration.
	* target-connection.c (_initialize_target_connection): Add
	declaration.
	* target-dcache.c (_initialize_target_dcache): Add declaration.
	* target-descriptions.c (_initialize_target_descriptions): Add declaration.
	* thread.c (_initialize_thread): Add declaration.
	* tic6x-linux-tdep.c (_initialize_tic6x_linux_tdep): Add declaration.
	* tic6x-tdep.c (_initialize_tic6x_tdep): Add declaration.
	* tilegx-linux-nat.c (_initialize_tile_linux_nat): Add declaration.
	* tilegx-linux-tdep.c (_initialize_tilegx_linux_tdep): Add declaration.
	* tilegx-tdep.c (_initialize_tilegx_tdep): Add declaration.
	* tracectf.c (_initialize_ctf): Add declaration.
	* tracefile-tfile.c (_initialize_tracefile_tfile): Add declaration.
	* tracefile.c (_initialize_tracefile): Add declaration.
	* tracepoint.c (_initialize_tracepoint): Add declaration.
	* tui/tui-hooks.c (_initialize_tui_hooks): Add declaration.
	* tui/tui-interp.c (_initialize_tui_interp): Add declaration.
	* tui/tui-layout.c (_initialize_tui_layout): Add declaration.
	* tui/tui-regs.c (_initialize_tui_regs): Add declaration.
	* tui/tui-stack.c (_initialize_tui_stack): Add declaration.
	* tui/tui-win.c (_initialize_tui_win): Add declaration.
	* tui/tui.c (_initialize_tui): Add declaration.
	* typeprint.c (_initialize_typeprint): Add declaration.
	* ui-style.c (_initialize_ui_style): Add declaration.
	* unittests/array-view-selftests.c (_initialize_array_view_selftests): Add declaration.
	* unittests/child-path-selftests.c (_initialize_child_path_selftests): Add declaration.
	* unittests/cli-utils-selftests.c (_initialize_cli_utils_selftests): Add declaration.
	* unittests/common-utils-selftests.c (_initialize_common_utils_selftests): Add declaration.
	* unittests/copy_bitwise-selftests.c (_initialize_copy_bitwise_utils_selftests): Add declaration.
	* unittests/environ-selftests.c (_initialize_environ_selftests): Add declaration.
	* unittests/filtered_iterator-selftests.c
	(_initialize_filtered_iterator_selftests): Add declaration.
	* unittests/format_pieces-selftests.c (_initialize_format_pieces_selftests): Add declaration.
	* unittests/function-view-selftests.c (_initialize_function_view_selftests): Add declaration.
	* unittests/help-doc-selftests.c (_initialize_help_doc_selftests): Add declaration.
	* unittests/lookup_name_info-selftests.c (_initialize_lookup_name_info_selftests): Add declaration.
	* unittests/main-thread-selftests.c
	(_initialize_main_thread_selftests): Add declaration.
	* unittests/memory-map-selftests.c (_initialize_memory_map_selftests): Add declaration.
	* unittests/memrange-selftests.c (_initialize_memrange_selftests): Add declaration.
	* unittests/mkdir-recursive-selftests.c (_initialize_mkdir_recursive_selftests): Add declaration.
	* unittests/observable-selftests.c (_initialize_observer_selftest): Add declaration.
	* unittests/offset-type-selftests.c (_initialize_offset_type_selftests): Add declaration.
	* unittests/optional-selftests.c (_initialize_optional_selftests): Add declaration.
	* unittests/parse-connection-spec-selftests.c (_initialize_parse_connection_spec_selftests): Add declaration.
	* unittests/rsp-low-selftests.c (_initialize_rsp_low_selftests): Add declaration.
	* unittests/scoped_fd-selftests.c (_initialize_scoped_fd_selftests): Add declaration.
	* unittests/scoped_mmap-selftests.c (_initialize_scoped_mmap_selftests): Add declaration.
	* unittests/scoped_restore-selftests.c (_initialize_scoped_restore_selftests): Add declaration.
	* unittests/string_view-selftests.c (_initialize_string_view_selftests): Add declaration.
	* unittests/style-selftests.c (_initialize_style_selftest): Add declaration.
	* unittests/tracepoint-selftests.c (_initialize_tracepoint_selftests): Add declaration.
	* unittests/tui-selftests.c (_initialize_tui_selftest): Add
	declaration.
	* unittests/unpack-selftests.c (_initialize_unpack_selftests): Add declaration.
	* unittests/utils-selftests.c (_initialize_utils_selftests): Add declaration.
	* unittests/vec-utils-selftests.c (_initialize_vec_utils_selftests): Add declaration.
	* unittests/xml-utils-selftests.c (_initialize_xml_utils): Add declaration.
	* user-regs.c (_initialize_user_regs): Add declaration.
	* utils.c (_initialize_utils): Add declaration.
	* v850-tdep.c (_initialize_v850_tdep): Add declaration.
	* valops.c (_initialize_valops): Add declaration.
	* valprint.c (_initialize_valprint): Add declaration.
	* value.c (_initialize_values): Add declaration.
	* varobj.c (_initialize_varobj): Add declaration.
	* vax-bsd-nat.c (_initialize_vaxbsd_nat): Add declaration.
	* vax-nbsd-tdep.c (_initialize_vaxnbsd_tdep): Add declaration.
	* vax-tdep.c (_initialize_vax_tdep): Add declaration.
	* windows-nat.c (_initialize_windows_nat): Add declaration.
	(_initialize_check_for_gdb_ini): Add declaration.
	(_initialize_loadable): Add declaration.
	* windows-tdep.c (_initialize_windows_tdep): Add declaration.
	* x86-bsd-nat.c (_initialize_x86_bsd_nat): Add declaration.
	* x86-linux-nat.c (_initialize_x86_linux_nat): Add declaration.
	* xcoffread.c (_initialize_xcoffread): Add declaration.
	* xml-support.c (_initialize_xml_support): Add declaration.
	* xstormy16-tdep.c (_initialize_xstormy16_tdep): Add declaration.
	* xtensa-linux-nat.c (_initialize_xtensa_linux_nat): Add declaration.
	* xtensa-linux-tdep.c (_initialize_xtensa_linux_tdep): Add declaration.
	* xtensa-tdep.c (_initialize_xtensa_tdep): Add declaration.

Change-Id: I13eec7e0ed2b3c427377a7bdb055cf46da64def9
2020-01-13 14:01:38 -05:00

1069 lines
31 KiB
C

/* S390 native-dependent code for GDB, the GNU debugger.
Copyright (C) 2001-2020 Free Software Foundation, Inc.
Contributed by D.J. Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
for IBM Deutschland Entwicklung GmbH, IBM Corporation.
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 "defs.h"
#include "regcache.h"
#include "inferior.h"
#include "target.h"
#include "linux-nat.h"
#include "auxv.h"
#include "gregset.h"
#include "regset.h"
#include "nat/linux-ptrace.h"
#include "gdbcmd.h"
#include "s390-tdep.h"
#include "s390-linux-tdep.h"
#include "elf/common.h"
#include <asm/ptrace.h>
#include "nat/gdb_ptrace.h"
#include <asm/types.h>
#include <sys/procfs.h>
#include <sys/ucontext.h>
#include <elf.h>
#include <algorithm>
#include "inf-ptrace.h"
#include "linux-tdep.h"
#include "gdbarch.h"
/* Per-thread arch-specific data. */
struct arch_lwp_info
{
/* Non-zero if the thread's PER info must be re-written. */
int per_info_changed;
};
static int have_regset_last_break = 0;
static int have_regset_system_call = 0;
static int have_regset_tdb = 0;
static int have_regset_vxrs = 0;
static int have_regset_gs = 0;
/* Register map for 32-bit executables running under a 64-bit
kernel. */
#ifdef __s390x__
static const struct regcache_map_entry s390_64_regmap_gregset[] =
{
/* Skip PSWM and PSWA, since they must be handled specially. */
{ 2, REGCACHE_MAP_SKIP, 8 },
{ 1, S390_R0_UPPER_REGNUM, 4 }, { 1, S390_R0_REGNUM, 4 },
{ 1, S390_R1_UPPER_REGNUM, 4 }, { 1, S390_R1_REGNUM, 4 },
{ 1, S390_R2_UPPER_REGNUM, 4 }, { 1, S390_R2_REGNUM, 4 },
{ 1, S390_R3_UPPER_REGNUM, 4 }, { 1, S390_R3_REGNUM, 4 },
{ 1, S390_R4_UPPER_REGNUM, 4 }, { 1, S390_R4_REGNUM, 4 },
{ 1, S390_R5_UPPER_REGNUM, 4 }, { 1, S390_R5_REGNUM, 4 },
{ 1, S390_R6_UPPER_REGNUM, 4 }, { 1, S390_R6_REGNUM, 4 },
{ 1, S390_R7_UPPER_REGNUM, 4 }, { 1, S390_R7_REGNUM, 4 },
{ 1, S390_R8_UPPER_REGNUM, 4 }, { 1, S390_R8_REGNUM, 4 },
{ 1, S390_R9_UPPER_REGNUM, 4 }, { 1, S390_R9_REGNUM, 4 },
{ 1, S390_R10_UPPER_REGNUM, 4 }, { 1, S390_R10_REGNUM, 4 },
{ 1, S390_R11_UPPER_REGNUM, 4 }, { 1, S390_R11_REGNUM, 4 },
{ 1, S390_R12_UPPER_REGNUM, 4 }, { 1, S390_R12_REGNUM, 4 },
{ 1, S390_R13_UPPER_REGNUM, 4 }, { 1, S390_R13_REGNUM, 4 },
{ 1, S390_R14_UPPER_REGNUM, 4 }, { 1, S390_R14_REGNUM, 4 },
{ 1, S390_R15_UPPER_REGNUM, 4 }, { 1, S390_R15_REGNUM, 4 },
{ 16, S390_A0_REGNUM, 4 },
{ 1, REGCACHE_MAP_SKIP, 4 }, { 1, S390_ORIG_R2_REGNUM, 4 },
{ 0 }
};
static const struct regset s390_64_gregset =
{
s390_64_regmap_gregset,
regcache_supply_regset,
regcache_collect_regset
};
#define S390_PSWM_OFFSET 0
#define S390_PSWA_OFFSET 8
#endif
/* PER-event mask bits and PER control bits (CR9). */
#define PER_BIT(n) (1UL << (63 - (n)))
#define PER_EVENT_BRANCH PER_BIT (32)
#define PER_EVENT_IFETCH PER_BIT (33)
#define PER_EVENT_STORE PER_BIT (34)
#define PER_EVENT_NULLIFICATION PER_BIT (39)
#define PER_CONTROL_BRANCH_ADDRESS PER_BIT (40)
#define PER_CONTROL_SUSPENSION PER_BIT (41)
#define PER_CONTROL_ALTERATION PER_BIT (42)
class s390_linux_nat_target final : public linux_nat_target
{
public:
/* Add our register access methods. */
void fetch_registers (struct regcache *, int) override;
void store_registers (struct regcache *, int) override;
/* Add our watchpoint methods. */
int can_use_hw_breakpoint (enum bptype, int, int) override;
int insert_hw_breakpoint (struct gdbarch *, struct bp_target_info *)
override;
int remove_hw_breakpoint (struct gdbarch *, struct bp_target_info *)
override;
int region_ok_for_hw_watchpoint (CORE_ADDR, int) override;
bool stopped_by_watchpoint () override;
int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
struct expression *) override;
int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
struct expression *) override;
/* Detect target architecture. */
const struct target_desc *read_description () override;
int auxv_parse (gdb_byte **readptr,
gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
override;
/* Override linux_nat_target low methods. */
void low_new_thread (struct lwp_info *lp) override;
void low_delete_thread (struct arch_lwp_info *lp) override;
void low_prepare_to_resume (struct lwp_info *lp) override;
void low_new_fork (struct lwp_info *parent, pid_t child_pid) override;
void low_forget_process (pid_t pid) override;
};
static s390_linux_nat_target the_s390_linux_nat_target;
/* Fill GDB's register array with the general-purpose register values
in *REGP.
When debugging a 32-bit executable running under a 64-bit kernel,
we have to fix up the 64-bit registers we get from the kernel to
make them look like 32-bit registers. */
void
supply_gregset (struct regcache *regcache, const gregset_t *regp)
{
#ifdef __s390x__
struct gdbarch *gdbarch = regcache->arch ();
if (gdbarch_ptr_bit (gdbarch) == 32)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
ULONGEST pswm, pswa;
gdb_byte buf[4];
regcache_supply_regset (&s390_64_gregset, regcache, -1,
regp, sizeof (gregset_t));
pswm = extract_unsigned_integer ((const gdb_byte *) regp
+ S390_PSWM_OFFSET, 8, byte_order);
pswa = extract_unsigned_integer ((const gdb_byte *) regp
+ S390_PSWA_OFFSET, 8, byte_order);
store_unsigned_integer (buf, 4, byte_order, (pswm >> 32) | 0x80000);
regcache->raw_supply (S390_PSWM_REGNUM, buf);
store_unsigned_integer (buf, 4, byte_order,
(pswa & 0x7fffffff) | (pswm & 0x80000000));
regcache->raw_supply (S390_PSWA_REGNUM, buf);
return;
}
#endif
regcache_supply_regset (&s390_gregset, regcache, -1, regp,
sizeof (gregset_t));
}
/* Fill register REGNO (if it is a general-purpose register) in
*REGP with the value in GDB's register array. If REGNO is -1,
do this for all registers. */
void
fill_gregset (const struct regcache *regcache, gregset_t *regp, int regno)
{
#ifdef __s390x__
struct gdbarch *gdbarch = regcache->arch ();
if (gdbarch_ptr_bit (gdbarch) == 32)
{
regcache_collect_regset (&s390_64_gregset, regcache, regno,
regp, sizeof (gregset_t));
if (regno == -1
|| regno == S390_PSWM_REGNUM || regno == S390_PSWA_REGNUM)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
ULONGEST pswa, pswm;
gdb_byte buf[4];
gdb_byte *pswm_p = (gdb_byte *) regp + S390_PSWM_OFFSET;
gdb_byte *pswa_p = (gdb_byte *) regp + S390_PSWA_OFFSET;
pswm = extract_unsigned_integer (pswm_p, 8, byte_order);
if (regno == -1 || regno == S390_PSWM_REGNUM)
{
pswm &= 0x80000000;
regcache->raw_collect (S390_PSWM_REGNUM, buf);
pswm |= (extract_unsigned_integer (buf, 4, byte_order)
& 0xfff7ffff) << 32;
}
if (regno == -1 || regno == S390_PSWA_REGNUM)
{
regcache->raw_collect (S390_PSWA_REGNUM, buf);
pswa = extract_unsigned_integer (buf, 4, byte_order);
pswm ^= (pswm ^ pswa) & 0x80000000;
pswa &= 0x7fffffff;
store_unsigned_integer (pswa_p, 8, byte_order, pswa);
}
store_unsigned_integer (pswm_p, 8, byte_order, pswm);
}
return;
}
#endif
regcache_collect_regset (&s390_gregset, regcache, regno, regp,
sizeof (gregset_t));
}
/* Fill GDB's register array with the floating-point register values
in *REGP. */
void
supply_fpregset (struct regcache *regcache, const fpregset_t *regp)
{
regcache_supply_regset (&s390_fpregset, regcache, -1, regp,
sizeof (fpregset_t));
}
/* Fill register REGNO (if it is a general-purpose register) in
*REGP with the value in GDB's register array. If REGNO is -1,
do this for all registers. */
void
fill_fpregset (const struct regcache *regcache, fpregset_t *regp, int regno)
{
regcache_collect_regset (&s390_fpregset, regcache, regno, regp,
sizeof (fpregset_t));
}
/* Find the TID for the current inferior thread to use with ptrace. */
static int
s390_inferior_tid (void)
{
/* GNU/Linux LWP ID's are process ID's. */
int tid = inferior_ptid.lwp ();
if (tid == 0)
tid = inferior_ptid.pid (); /* Not a threaded program. */
return tid;
}
/* Fetch all general-purpose registers from process/thread TID and
store their values in GDB's register cache. */
static void
fetch_regs (struct regcache *regcache, int tid)
{
gregset_t regs;
ptrace_area parea;
parea.len = sizeof (regs);
parea.process_addr = (addr_t) &regs;
parea.kernel_addr = offsetof (struct user_regs_struct, psw);
if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea, 0) < 0)
perror_with_name (_("Couldn't get registers"));
supply_gregset (regcache, (const gregset_t *) &regs);
}
/* Store all valid general-purpose registers in GDB's register cache
into the process/thread specified by TID. */
static void
store_regs (const struct regcache *regcache, int tid, int regnum)
{
gregset_t regs;
ptrace_area parea;
parea.len = sizeof (regs);
parea.process_addr = (addr_t) &regs;
parea.kernel_addr = offsetof (struct user_regs_struct, psw);
if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea, 0) < 0)
perror_with_name (_("Couldn't get registers"));
fill_gregset (regcache, &regs, regnum);
if (ptrace (PTRACE_POKEUSR_AREA, tid, (long) &parea, 0) < 0)
perror_with_name (_("Couldn't write registers"));
}
/* Fetch all floating-point registers from process/thread TID and store
their values in GDB's register cache. */
static void
fetch_fpregs (struct regcache *regcache, int tid)
{
fpregset_t fpregs;
ptrace_area parea;
parea.len = sizeof (fpregs);
parea.process_addr = (addr_t) &fpregs;
parea.kernel_addr = offsetof (struct user_regs_struct, fp_regs);
if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea, 0) < 0)
perror_with_name (_("Couldn't get floating point status"));
supply_fpregset (regcache, (const fpregset_t *) &fpregs);
}
/* Store all valid floating-point registers in GDB's register cache
into the process/thread specified by TID. */
static void
store_fpregs (const struct regcache *regcache, int tid, int regnum)
{
fpregset_t fpregs;
ptrace_area parea;
parea.len = sizeof (fpregs);
parea.process_addr = (addr_t) &fpregs;
parea.kernel_addr = offsetof (struct user_regs_struct, fp_regs);
if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea, 0) < 0)
perror_with_name (_("Couldn't get floating point status"));
fill_fpregset (regcache, &fpregs, regnum);
if (ptrace (PTRACE_POKEUSR_AREA, tid, (long) &parea, 0) < 0)
perror_with_name (_("Couldn't write floating point status"));
}
/* Fetch all registers in the kernel's register set whose number is
REGSET_ID, whose size is REGSIZE, and whose layout is described by
REGSET, from process/thread TID and store their values in GDB's
register cache. */
static void
fetch_regset (struct regcache *regcache, int tid,
int regset_id, int regsize, const struct regset *regset)
{
void *buf = alloca (regsize);
struct iovec iov;
iov.iov_base = buf;
iov.iov_len = regsize;
if (ptrace (PTRACE_GETREGSET, tid, (long) regset_id, (long) &iov) < 0)
{
if (errno == ENODATA)
regcache_supply_regset (regset, regcache, -1, NULL, regsize);
else
perror_with_name (_("Couldn't get register set"));
}
else
regcache_supply_regset (regset, regcache, -1, buf, regsize);
}
/* Store all registers in the kernel's register set whose number is
REGSET_ID, whose size is REGSIZE, and whose layout is described by
REGSET, from GDB's register cache back to process/thread TID. */
static void
store_regset (struct regcache *regcache, int tid,
int regset_id, int regsize, const struct regset *regset)
{
void *buf = alloca (regsize);
struct iovec iov;
iov.iov_base = buf;
iov.iov_len = regsize;
if (ptrace (PTRACE_GETREGSET, tid, (long) regset_id, (long) &iov) < 0)
perror_with_name (_("Couldn't get register set"));
regcache_collect_regset (regset, regcache, -1, buf, regsize);
if (ptrace (PTRACE_SETREGSET, tid, (long) regset_id, (long) &iov) < 0)
perror_with_name (_("Couldn't set register set"));
}
/* Check whether the kernel provides a register set with number REGSET
of size REGSIZE for process/thread TID. */
static int
check_regset (int tid, int regset, int regsize)
{
void *buf = alloca (regsize);
struct iovec iov;
iov.iov_base = buf;
iov.iov_len = regsize;
if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) >= 0
|| errno == ENODATA)
return 1;
return 0;
}
/* Fetch register REGNUM from the child process. If REGNUM is -1, do
this for all registers. */
void
s390_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum)
{
pid_t tid = get_ptrace_pid (regcache->ptid ());
if (regnum == -1 || S390_IS_GREGSET_REGNUM (regnum))
fetch_regs (regcache, tid);
if (regnum == -1 || S390_IS_FPREGSET_REGNUM (regnum))
fetch_fpregs (regcache, tid);
if (have_regset_last_break)
if (regnum == -1 || regnum == S390_LAST_BREAK_REGNUM)
fetch_regset (regcache, tid, NT_S390_LAST_BREAK, 8,
(gdbarch_ptr_bit (regcache->arch ()) == 32
? &s390_last_break_regset : &s390x_last_break_regset));
if (have_regset_system_call)
if (regnum == -1 || regnum == S390_SYSTEM_CALL_REGNUM)
fetch_regset (regcache, tid, NT_S390_SYSTEM_CALL, 4,
&s390_system_call_regset);
if (have_regset_tdb)
if (regnum == -1 || S390_IS_TDBREGSET_REGNUM (regnum))
fetch_regset (regcache, tid, NT_S390_TDB, s390_sizeof_tdbregset,
&s390_tdb_regset);
if (have_regset_vxrs)
{
if (regnum == -1 || (regnum >= S390_V0_LOWER_REGNUM
&& regnum <= S390_V15_LOWER_REGNUM))
fetch_regset (regcache, tid, NT_S390_VXRS_LOW, 16 * 8,
&s390_vxrs_low_regset);
if (regnum == -1 || (regnum >= S390_V16_REGNUM
&& regnum <= S390_V31_REGNUM))
fetch_regset (regcache, tid, NT_S390_VXRS_HIGH, 16 * 16,
&s390_vxrs_high_regset);
}
if (have_regset_gs)
{
if (regnum == -1 || (regnum >= S390_GSD_REGNUM
&& regnum <= S390_GSEPLA_REGNUM))
fetch_regset (regcache, tid, NT_S390_GS_CB, 4 * 8,
&s390_gs_regset);
if (regnum == -1 || (regnum >= S390_BC_GSD_REGNUM
&& regnum <= S390_BC_GSEPLA_REGNUM))
fetch_regset (regcache, tid, NT_S390_GS_BC, 4 * 8,
&s390_gsbc_regset);
}
}
/* Store register REGNUM back into the child process. If REGNUM is
-1, do this for all registers. */
void
s390_linux_nat_target::store_registers (struct regcache *regcache, int regnum)
{
pid_t tid = get_ptrace_pid (regcache->ptid ());
if (regnum == -1 || S390_IS_GREGSET_REGNUM (regnum))
store_regs (regcache, tid, regnum);
if (regnum == -1 || S390_IS_FPREGSET_REGNUM (regnum))
store_fpregs (regcache, tid, regnum);
/* S390_LAST_BREAK_REGNUM is read-only. */
if (have_regset_system_call)
if (regnum == -1 || regnum == S390_SYSTEM_CALL_REGNUM)
store_regset (regcache, tid, NT_S390_SYSTEM_CALL, 4,
&s390_system_call_regset);
if (have_regset_vxrs)
{
if (regnum == -1 || (regnum >= S390_V0_LOWER_REGNUM
&& regnum <= S390_V15_LOWER_REGNUM))
store_regset (regcache, tid, NT_S390_VXRS_LOW, 16 * 8,
&s390_vxrs_low_regset);
if (regnum == -1 || (regnum >= S390_V16_REGNUM
&& regnum <= S390_V31_REGNUM))
store_regset (regcache, tid, NT_S390_VXRS_HIGH, 16 * 16,
&s390_vxrs_high_regset);
}
}
/* Hardware-assisted watchpoint handling. */
/* For each process we maintain a list of all currently active
watchpoints, in order to properly handle watchpoint removal.
The only thing we actually need is the total address space area
spanned by the watchpoints. */
struct watch_area
{
CORE_ADDR lo_addr;
CORE_ADDR hi_addr;
};
/* Hardware debug state. */
struct s390_debug_reg_state
{
std::vector<watch_area> watch_areas;
std::vector<watch_area> break_areas;
};
/* Per-process data. */
struct s390_process_info
{
struct s390_process_info *next = nullptr;
pid_t pid = 0;
struct s390_debug_reg_state state;
};
static struct s390_process_info *s390_process_list = NULL;
/* Find process data for process PID. */
static struct s390_process_info *
s390_find_process_pid (pid_t pid)
{
struct s390_process_info *proc;
for (proc = s390_process_list; proc; proc = proc->next)
if (proc->pid == pid)
return proc;
return NULL;
}
/* Add process data for process PID. Returns newly allocated info
object. */
static struct s390_process_info *
s390_add_process (pid_t pid)
{
struct s390_process_info *proc = new struct s390_process_info;
proc->pid = pid;
proc->next = s390_process_list;
s390_process_list = proc;
return proc;
}
/* Get data specific info for process PID, creating it if necessary.
Never returns NULL. */
static struct s390_process_info *
s390_process_info_get (pid_t pid)
{
struct s390_process_info *proc;
proc = s390_find_process_pid (pid);
if (proc == NULL)
proc = s390_add_process (pid);
return proc;
}
/* Get hardware debug state for process PID. */
static struct s390_debug_reg_state *
s390_get_debug_reg_state (pid_t pid)
{
return &s390_process_info_get (pid)->state;
}
/* Called whenever GDB is no longer debugging process PID. It deletes
data structures that keep track of hardware debug state. */
void
s390_linux_nat_target::low_forget_process (pid_t pid)
{
struct s390_process_info *proc, **proc_link;
proc = s390_process_list;
proc_link = &s390_process_list;
while (proc != NULL)
{
if (proc->pid == pid)
{
*proc_link = proc->next;
delete proc;
return;
}
proc_link = &proc->next;
proc = *proc_link;
}
}
/* linux_nat_new_fork hook. */
void
s390_linux_nat_target::low_new_fork (struct lwp_info *parent, pid_t child_pid)
{
pid_t parent_pid;
struct s390_debug_reg_state *parent_state;
struct s390_debug_reg_state *child_state;
/* NULL means no watchpoint has ever been set in the parent. In
that case, there's nothing to do. */
if (lwp_arch_private_info (parent) == NULL)
return;
/* GDB core assumes the child inherits the watchpoints/hw breakpoints of
the parent. So copy the debug state from parent to child. */
parent_pid = parent->ptid.pid ();
parent_state = s390_get_debug_reg_state (parent_pid);
child_state = s390_get_debug_reg_state (child_pid);
child_state->watch_areas = parent_state->watch_areas;
child_state->break_areas = parent_state->break_areas;
}
/* Dump PER state. */
static void
s390_show_debug_regs (int tid, const char *where)
{
per_struct per_info;
ptrace_area parea;
parea.len = sizeof (per_info);
parea.process_addr = (addr_t) &per_info;
parea.kernel_addr = offsetof (struct user_regs_struct, per_info);
if (ptrace (PTRACE_PEEKUSR_AREA, tid, &parea, 0) < 0)
perror_with_name (_("Couldn't retrieve debug regs"));
debug_printf ("PER (debug) state for %d -- %s\n"
" cr9-11: %lx %lx %lx\n"
" start, end: %lx %lx\n"
" code/ATMID: %x address: %lx PAID: %x\n",
tid,
where,
per_info.control_regs.words.cr[0],
per_info.control_regs.words.cr[1],
per_info.control_regs.words.cr[2],
per_info.starting_addr,
per_info.ending_addr,
per_info.lowcore.words.perc_atmid,
per_info.lowcore.words.address,
per_info.lowcore.words.access_id);
}
bool
s390_linux_nat_target::stopped_by_watchpoint ()
{
struct s390_debug_reg_state *state
= s390_get_debug_reg_state (inferior_ptid.pid ());
per_lowcore_bits per_lowcore;
ptrace_area parea;
if (show_debug_regs)
s390_show_debug_regs (s390_inferior_tid (), "stop");
/* Speed up common case. */
if (state->watch_areas.empty ())
return false;
parea.len = sizeof (per_lowcore);
parea.process_addr = (addr_t) & per_lowcore;
parea.kernel_addr = offsetof (struct user_regs_struct, per_info.lowcore);
if (ptrace (PTRACE_PEEKUSR_AREA, s390_inferior_tid (), &parea, 0) < 0)
perror_with_name (_("Couldn't retrieve watchpoint status"));
bool result = (per_lowcore.perc_storage_alteration == 1
&& per_lowcore.perc_store_real_address == 0);
if (result)
{
/* Do not report this watchpoint again. */
memset (&per_lowcore, 0, sizeof (per_lowcore));
if (ptrace (PTRACE_POKEUSR_AREA, s390_inferior_tid (), &parea, 0) < 0)
perror_with_name (_("Couldn't clear watchpoint status"));
}
return result;
}
/* Each time before resuming a thread, update its PER info. */
void
s390_linux_nat_target::low_prepare_to_resume (struct lwp_info *lp)
{
int tid;
pid_t pid = ptid_of_lwp (lp).pid ();
per_struct per_info;
ptrace_area parea;
CORE_ADDR watch_lo_addr = (CORE_ADDR)-1, watch_hi_addr = 0;
struct arch_lwp_info *lp_priv = lwp_arch_private_info (lp);
struct s390_debug_reg_state *state = s390_get_debug_reg_state (pid);
int step = lwp_is_stepping (lp);
/* Nothing to do if there was never any PER info for this thread. */
if (lp_priv == NULL)
return;
/* If PER info has changed, update it. When single-stepping, disable
hardware breakpoints (if any). Otherwise we're done. */
if (!lp_priv->per_info_changed)
{
if (!step || state->break_areas.empty ())
return;
}
lp_priv->per_info_changed = 0;
tid = ptid_of_lwp (lp).lwp ();
if (tid == 0)
tid = pid;
parea.len = sizeof (per_info);
parea.process_addr = (addr_t) & per_info;
parea.kernel_addr = offsetof (struct user_regs_struct, per_info);
/* Clear PER info, but adjust the single_step field (used by older
kernels only). */
memset (&per_info, 0, sizeof (per_info));
per_info.single_step = (step != 0);
if (!state->watch_areas.empty ())
{
for (const auto &area : state->watch_areas)
{
watch_lo_addr = std::min (watch_lo_addr, area.lo_addr);
watch_hi_addr = std::max (watch_hi_addr, area.hi_addr);
}
/* Enable storage-alteration events. */
per_info.control_regs.words.cr[0] |= (PER_EVENT_STORE
| PER_CONTROL_ALTERATION);
}
if (!state->break_areas.empty ())
{
/* Don't install hardware breakpoints while single-stepping, since
our PER settings (e.g. the nullification bit) might then conflict
with the kernel's. But re-install them afterwards. */
if (step)
lp_priv->per_info_changed = 1;
else
{
for (const auto &area : state->break_areas)
{
watch_lo_addr = std::min (watch_lo_addr, area.lo_addr);
watch_hi_addr = std::max (watch_hi_addr, area.hi_addr);
}
/* If there's just one breakpoint, enable instruction-fetching
nullification events for the breakpoint address (fast).
Otherwise stop after any instruction within the PER area and
after any branch into it (slow). */
if (watch_hi_addr == watch_lo_addr)
per_info.control_regs.words.cr[0] |= (PER_EVENT_NULLIFICATION
| PER_EVENT_IFETCH);
else
{
/* The PER area must include the instruction before the
first breakpoint address. */
watch_lo_addr = watch_lo_addr > 6 ? watch_lo_addr - 6 : 0;
per_info.control_regs.words.cr[0]
|= (PER_EVENT_BRANCH
| PER_EVENT_IFETCH
| PER_CONTROL_BRANCH_ADDRESS);
}
}
}
per_info.starting_addr = watch_lo_addr;
per_info.ending_addr = watch_hi_addr;
if (ptrace (PTRACE_POKEUSR_AREA, tid, &parea, 0) < 0)
perror_with_name (_("Couldn't modify watchpoint status"));
if (show_debug_regs)
s390_show_debug_regs (tid, "resume");
}
/* Mark the PER info as changed, so the next resume will update it. */
static void
s390_mark_per_info_changed (struct lwp_info *lp)
{
if (lwp_arch_private_info (lp) == NULL)
lwp_set_arch_private_info (lp, XCNEW (struct arch_lwp_info));
lwp_arch_private_info (lp)->per_info_changed = 1;
}
/* When attaching to a new thread, mark its PER info as changed. */
void
s390_linux_nat_target::low_new_thread (struct lwp_info *lp)
{
s390_mark_per_info_changed (lp);
}
/* Function to call when a thread is being deleted. */
void
s390_linux_nat_target::low_delete_thread (struct arch_lwp_info *arch_lwp)
{
xfree (arch_lwp);
}
/* Iterator callback for s390_refresh_per_info. */
static int
s390_refresh_per_info_cb (struct lwp_info *lp)
{
s390_mark_per_info_changed (lp);
if (!lwp_is_stopped (lp))
linux_stop_lwp (lp);
return 0;
}
/* Make sure that threads are stopped and mark PER info as changed. */
static int
s390_refresh_per_info (void)
{
ptid_t pid_ptid = ptid_t (current_lwp_ptid ().pid ());
iterate_over_lwps (pid_ptid, s390_refresh_per_info_cb);
return 0;
}
int
s390_linux_nat_target::insert_watchpoint (CORE_ADDR addr, int len,
enum target_hw_bp_type type,
struct expression *cond)
{
watch_area area;
struct s390_debug_reg_state *state
= s390_get_debug_reg_state (inferior_ptid.pid ());
area.lo_addr = addr;
area.hi_addr = addr + len - 1;
state->watch_areas.push_back (area);
return s390_refresh_per_info ();
}
int
s390_linux_nat_target::remove_watchpoint (CORE_ADDR addr, int len,
enum target_hw_bp_type type,
struct expression *cond)
{
unsigned ix;
struct s390_debug_reg_state *state
= s390_get_debug_reg_state (inferior_ptid.pid ());
for (ix = 0; ix < state->watch_areas.size (); ix++)
{
watch_area &area = state->watch_areas[ix];
if (area.lo_addr == addr && area.hi_addr == addr + len - 1)
{
unordered_remove (state->watch_areas, ix);
return s390_refresh_per_info ();
}
}
fprintf_unfiltered (gdb_stderr,
"Attempt to remove nonexistent watchpoint.\n");
return -1;
}
/* Implement the "can_use_hw_breakpoint" target_ops method. */
int
s390_linux_nat_target::can_use_hw_breakpoint (enum bptype type,
int cnt, int othertype)
{
if (type == bp_hardware_watchpoint || type == bp_hardware_breakpoint)
return 1;
return 0;
}
/* Implement the "insert_hw_breakpoint" target_ops method. */
int
s390_linux_nat_target::insert_hw_breakpoint (struct gdbarch *gdbarch,
struct bp_target_info *bp_tgt)
{
watch_area area;
struct s390_debug_reg_state *state;
area.lo_addr = bp_tgt->placed_address = bp_tgt->reqstd_address;
area.hi_addr = area.lo_addr;
state = s390_get_debug_reg_state (inferior_ptid.pid ());
state->break_areas.push_back (area);
return s390_refresh_per_info ();
}
/* Implement the "remove_hw_breakpoint" target_ops method. */
int
s390_linux_nat_target::remove_hw_breakpoint (struct gdbarch *gdbarch,
struct bp_target_info *bp_tgt)
{
unsigned ix;
struct s390_debug_reg_state *state;
state = s390_get_debug_reg_state (inferior_ptid.pid ());
for (ix = 0; state->break_areas.size (); ix++)
{
watch_area &area = state->break_areas[ix];
if (area.lo_addr == bp_tgt->placed_address)
{
unordered_remove (state->break_areas, ix);
return s390_refresh_per_info ();
}
}
fprintf_unfiltered (gdb_stderr,
"Attempt to remove nonexistent breakpoint.\n");
return -1;
}
int
s390_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int cnt)
{
return 1;
}
static int
s390_target_wordsize (void)
{
int wordsize = 4;
/* Check for 64-bit inferior process. This is the case when the host is
64-bit, and in addition bit 32 of the PSW mask is set. */
#ifdef __s390x__
long pswm;
errno = 0;
pswm = (long) ptrace (PTRACE_PEEKUSER, s390_inferior_tid (), PT_PSWMASK, 0);
if (errno == 0 && (pswm & 0x100000000ul) != 0)
wordsize = 8;
#endif
return wordsize;
}
int
s390_linux_nat_target::auxv_parse (gdb_byte **readptr,
gdb_byte *endptr, CORE_ADDR *typep,
CORE_ADDR *valp)
{
int sizeof_auxv_field = s390_target_wordsize ();
enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
gdb_byte *ptr = *readptr;
if (endptr == ptr)
return 0;
if (endptr - ptr < sizeof_auxv_field * 2)
return -1;
*typep = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
ptr += sizeof_auxv_field;
*valp = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
ptr += sizeof_auxv_field;
*readptr = ptr;
return 1;
}
const struct target_desc *
s390_linux_nat_target::read_description ()
{
int tid = s390_inferior_tid ();
have_regset_last_break
= check_regset (tid, NT_S390_LAST_BREAK, 8);
have_regset_system_call
= check_regset (tid, NT_S390_SYSTEM_CALL, 4);
/* If GDB itself is compiled as 64-bit, we are running on a machine in
z/Architecture mode. If the target is running in 64-bit addressing
mode, report s390x architecture. If the target is running in 31-bit
addressing mode, but the kernel supports using 64-bit registers in
that mode, report s390 architecture with 64-bit GPRs. */
#ifdef __s390x__
{
CORE_ADDR hwcap = linux_get_hwcap (current_top_target ());
have_regset_tdb = (hwcap & HWCAP_S390_TE)
&& check_regset (tid, NT_S390_TDB, s390_sizeof_tdbregset);
have_regset_vxrs = (hwcap & HWCAP_S390_VX)
&& check_regset (tid, NT_S390_VXRS_LOW, 16 * 8)
&& check_regset (tid, NT_S390_VXRS_HIGH, 16 * 16);
have_regset_gs = (hwcap & HWCAP_S390_GS)
&& check_regset (tid, NT_S390_GS_CB, 4 * 8)
&& check_regset (tid, NT_S390_GS_BC, 4 * 8);
if (s390_target_wordsize () == 8)
return (have_regset_gs ? tdesc_s390x_gs_linux64 :
have_regset_vxrs ?
(have_regset_tdb ? tdesc_s390x_tevx_linux64 :
tdesc_s390x_vx_linux64) :
have_regset_tdb ? tdesc_s390x_te_linux64 :
have_regset_system_call ? tdesc_s390x_linux64v2 :
have_regset_last_break ? tdesc_s390x_linux64v1 :
tdesc_s390x_linux64);
if (hwcap & HWCAP_S390_HIGH_GPRS)
return (have_regset_gs ? tdesc_s390_gs_linux64 :
have_regset_vxrs ?
(have_regset_tdb ? tdesc_s390_tevx_linux64 :
tdesc_s390_vx_linux64) :
have_regset_tdb ? tdesc_s390_te_linux64 :
have_regset_system_call ? tdesc_s390_linux64v2 :
have_regset_last_break ? tdesc_s390_linux64v1 :
tdesc_s390_linux64);
}
#endif
/* If GDB itself is compiled as 31-bit, or if we're running a 31-bit inferior
on a 64-bit kernel that does not support using 64-bit registers in 31-bit
mode, report s390 architecture with 32-bit GPRs. */
return (have_regset_system_call? tdesc_s390_linux32v2 :
have_regset_last_break? tdesc_s390_linux32v1 :
tdesc_s390_linux32);
}
void _initialize_s390_nat ();
void
_initialize_s390_nat ()
{
/* Register the target. */
linux_target = &the_s390_linux_nat_target;
add_inf_child_target (&the_s390_linux_nat_target);
/* A maintenance command to enable showing the PER state. */
add_setshow_boolean_cmd ("show-debug-regs", class_maintenance,
&show_debug_regs, _("\
Set whether to show the PER (debug) hardware state."), _("\
Show whether to show the PER (debug) hardware state."), _("\
Use \"on\" to enable, \"off\" to disable.\n\
If enabled, the PER state is shown after it is changed by GDB,\n\
and when the inferior triggers a breakpoint or watchpoint."),
NULL,
NULL,
&maintenance_set_cmdlist,
&maintenance_show_cmdlist);
}