6c2659886f
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
1732 lines
47 KiB
C
1732 lines
47 KiB
C
/* CTF format support.
|
|
|
|
Copyright (C) 2012-2020 Free Software Foundation, Inc.
|
|
Contributed by Hui Zhu <hui_zhu@mentor.com>
|
|
Contributed by Yao Qi <yao@codesourcery.com>
|
|
|
|
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 "tracectf.h"
|
|
#include "tracepoint.h"
|
|
#include "regcache.h"
|
|
#include <sys/stat.h>
|
|
#include "exec.h"
|
|
#include "completer.h"
|
|
#include "inferior.h"
|
|
#include "gdbthread.h"
|
|
#include "tracefile.h"
|
|
#include <ctype.h>
|
|
#include <algorithm>
|
|
#include "gdbsupport/filestuff.h"
|
|
#include "gdbarch.h"
|
|
|
|
/* The CTF target. */
|
|
|
|
static const target_info ctf_target_info = {
|
|
"ctf",
|
|
N_("CTF file"),
|
|
N_("(Use a CTF directory as a target.\n\
|
|
Specify the filename of the CTF directory.")
|
|
};
|
|
|
|
class ctf_target final : public tracefile_target
|
|
{
|
|
public:
|
|
const target_info &info () const override
|
|
{ return ctf_target_info; }
|
|
|
|
void close () override;
|
|
void fetch_registers (struct regcache *, int) override;
|
|
enum target_xfer_status xfer_partial (enum target_object object,
|
|
const char *annex,
|
|
gdb_byte *readbuf,
|
|
const gdb_byte *writebuf,
|
|
ULONGEST offset, ULONGEST len,
|
|
ULONGEST *xfered_len) override;
|
|
void files_info () override;
|
|
int trace_find (enum trace_find_type type, int num,
|
|
CORE_ADDR addr1, CORE_ADDR addr2, int *tpp) override;
|
|
bool get_trace_state_variable_value (int tsv, LONGEST *val) override;
|
|
traceframe_info_up traceframe_info () override;
|
|
};
|
|
|
|
/* GDB saves trace buffers and other information (such as trace
|
|
status) got from the remote target into Common Trace Format (CTF).
|
|
The following types of information are expected to save in CTF:
|
|
|
|
1. The length (in bytes) of register cache. Event "register" will
|
|
be defined in metadata, which includes the length.
|
|
|
|
2. Trace status. Event "status" is defined in metadata, which
|
|
includes all aspects of trace status.
|
|
|
|
3. Uploaded trace variables. Event "tsv_def" is defined in
|
|
metadata, which is about all aspects of a uploaded trace variable.
|
|
Uploaded tracepoints. Event "tp_def" is defined in meta, which
|
|
is about all aspects of an uploaded tracepoint. Note that the
|
|
"sequence" (a CTF type, which is a dynamically-sized array.) is
|
|
used for "actions" "step_actions" and "cmd_strings".
|
|
|
|
4. Trace frames. Each trace frame is composed by several blocks
|
|
of different types ('R', 'M', 'V'). One trace frame is saved in
|
|
one CTF packet and the blocks of this frame are saved as events.
|
|
4.1: The trace frame related information (such as the number of
|
|
tracepoint associated with this frame) is saved in the packet
|
|
context.
|
|
4.2: The block 'M', 'R' and 'V' are saved in event "memory",
|
|
"register" and "tsv" respectively.
|
|
4.3: When iterating over events, babeltrace can't tell iterator
|
|
goes to a new packet, so we need a marker or anchor to tell GDB
|
|
that iterator goes into a new packet or frame. We define event
|
|
"frame". */
|
|
|
|
#define CTF_MAGIC 0xC1FC1FC1
|
|
#define CTF_SAVE_MAJOR 1
|
|
#define CTF_SAVE_MINOR 8
|
|
|
|
#define CTF_METADATA_NAME "metadata"
|
|
#define CTF_DATASTREAM_NAME "datastream"
|
|
|
|
/* Reserved event id. */
|
|
|
|
#define CTF_EVENT_ID_REGISTER 0
|
|
#define CTF_EVENT_ID_TSV 1
|
|
#define CTF_EVENT_ID_MEMORY 2
|
|
#define CTF_EVENT_ID_FRAME 3
|
|
#define CTF_EVENT_ID_STATUS 4
|
|
#define CTF_EVENT_ID_TSV_DEF 5
|
|
#define CTF_EVENT_ID_TP_DEF 6
|
|
|
|
#define CTF_PID (2)
|
|
|
|
/* The state kept while writing the CTF datastream file. */
|
|
|
|
struct trace_write_handler
|
|
{
|
|
/* File descriptor of metadata. */
|
|
FILE *metadata_fd;
|
|
/* File descriptor of traceframes. */
|
|
FILE *datastream_fd;
|
|
|
|
/* This is the content size of the current packet. */
|
|
size_t content_size;
|
|
|
|
/* This is the start offset of current packet. */
|
|
long packet_start;
|
|
};
|
|
|
|
/* Write metadata in FORMAT. */
|
|
|
|
static void
|
|
ctf_save_write_metadata (struct trace_write_handler *handler,
|
|
const char *format, ...)
|
|
ATTRIBUTE_PRINTF (2, 3);
|
|
|
|
static void
|
|
ctf_save_write_metadata (struct trace_write_handler *handler,
|
|
const char *format, ...)
|
|
{
|
|
va_list args;
|
|
|
|
va_start (args, format);
|
|
if (vfprintf (handler->metadata_fd, format, args) < 0)
|
|
error (_("Unable to write metadata file (%s)"),
|
|
safe_strerror (errno));
|
|
va_end (args);
|
|
}
|
|
|
|
/* Write BUF of length SIZE to datastream file represented by
|
|
HANDLER. */
|
|
|
|
static int
|
|
ctf_save_write (struct trace_write_handler *handler,
|
|
const gdb_byte *buf, size_t size)
|
|
{
|
|
if (fwrite (buf, size, 1, handler->datastream_fd) != 1)
|
|
error (_("Unable to write file for saving trace data (%s)"),
|
|
safe_strerror (errno));
|
|
|
|
handler->content_size += size;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Write a unsigned 32-bit integer to datastream file represented by
|
|
HANDLER. */
|
|
|
|
#define ctf_save_write_uint32(HANDLER, U32) \
|
|
ctf_save_write (HANDLER, (gdb_byte *) &U32, 4)
|
|
|
|
/* Write a signed 32-bit integer to datastream file represented by
|
|
HANDLER. */
|
|
|
|
#define ctf_save_write_int32(HANDLER, INT32) \
|
|
ctf_save_write ((HANDLER), (gdb_byte *) &(INT32), 4)
|
|
|
|
/* Set datastream file position. Update HANDLER->content_size
|
|
if WHENCE is SEEK_CUR. */
|
|
|
|
static int
|
|
ctf_save_fseek (struct trace_write_handler *handler, long offset,
|
|
int whence)
|
|
{
|
|
gdb_assert (whence != SEEK_END);
|
|
gdb_assert (whence != SEEK_SET
|
|
|| offset <= handler->content_size + handler->packet_start);
|
|
|
|
if (fseek (handler->datastream_fd, offset, whence))
|
|
error (_("Unable to seek file for saving trace data (%s)"),
|
|
safe_strerror (errno));
|
|
|
|
if (whence == SEEK_CUR)
|
|
handler->content_size += offset;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Change the datastream file position to align on ALIGN_SIZE,
|
|
and write BUF to datastream file. The size of BUF is SIZE. */
|
|
|
|
static int
|
|
ctf_save_align_write (struct trace_write_handler *handler,
|
|
const gdb_byte *buf,
|
|
size_t size, size_t align_size)
|
|
{
|
|
long offset
|
|
= (align_up (handler->content_size, align_size)
|
|
- handler->content_size);
|
|
|
|
if (ctf_save_fseek (handler, offset, SEEK_CUR))
|
|
return -1;
|
|
|
|
if (ctf_save_write (handler, buf, size))
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Write events to next new packet. */
|
|
|
|
static void
|
|
ctf_save_next_packet (struct trace_write_handler *handler)
|
|
{
|
|
handler->packet_start += (handler->content_size + 4);
|
|
ctf_save_fseek (handler, handler->packet_start, SEEK_SET);
|
|
handler->content_size = 0;
|
|
}
|
|
|
|
/* Write the CTF metadata header. */
|
|
|
|
static void
|
|
ctf_save_metadata_header (struct trace_write_handler *handler)
|
|
{
|
|
ctf_save_write_metadata (handler, "/* CTF %d.%d */\n",
|
|
CTF_SAVE_MAJOR, CTF_SAVE_MINOR);
|
|
ctf_save_write_metadata (handler,
|
|
"typealias integer { size = 8; align = 8; "
|
|
"signed = false; encoding = ascii;}"
|
|
" := ascii;\n");
|
|
ctf_save_write_metadata (handler,
|
|
"typealias integer { size = 8; align = 8; "
|
|
"signed = false; }"
|
|
" := uint8_t;\n");
|
|
ctf_save_write_metadata (handler,
|
|
"typealias integer { size = 16; align = 16;"
|
|
"signed = false; } := uint16_t;\n");
|
|
ctf_save_write_metadata (handler,
|
|
"typealias integer { size = 32; align = 32;"
|
|
"signed = false; } := uint32_t;\n");
|
|
ctf_save_write_metadata (handler,
|
|
"typealias integer { size = 64; align = 64;"
|
|
"signed = false; base = hex;}"
|
|
" := uint64_t;\n");
|
|
ctf_save_write_metadata (handler,
|
|
"typealias integer { size = 32; align = 32;"
|
|
"signed = true; } := int32_t;\n");
|
|
ctf_save_write_metadata (handler,
|
|
"typealias integer { size = 64; align = 64;"
|
|
"signed = true; } := int64_t;\n");
|
|
ctf_save_write_metadata (handler,
|
|
"typealias string { encoding = ascii;"
|
|
" } := chars;\n");
|
|
ctf_save_write_metadata (handler, "\n");
|
|
|
|
/* Get the byte order of the host and write CTF data in this byte
|
|
order. */
|
|
#if WORDS_BIGENDIAN
|
|
#define HOST_ENDIANNESS "be"
|
|
#else
|
|
#define HOST_ENDIANNESS "le"
|
|
#endif
|
|
|
|
ctf_save_write_metadata (handler,
|
|
"\ntrace {\n"
|
|
" major = %u;\n"
|
|
" minor = %u;\n"
|
|
" byte_order = %s;\n"
|
|
" packet.header := struct {\n"
|
|
" uint32_t magic;\n"
|
|
" };\n"
|
|
"};\n"
|
|
"\n"
|
|
"stream {\n"
|
|
" packet.context := struct {\n"
|
|
" uint32_t content_size;\n"
|
|
" uint32_t packet_size;\n"
|
|
" uint16_t tpnum;\n"
|
|
" };\n"
|
|
" event.header := struct {\n"
|
|
" uint32_t id;\n"
|
|
" };\n"
|
|
"};\n",
|
|
CTF_SAVE_MAJOR, CTF_SAVE_MINOR,
|
|
HOST_ENDIANNESS);
|
|
ctf_save_write_metadata (handler, "\n");
|
|
}
|
|
|
|
/* CTF trace writer. */
|
|
|
|
struct ctf_trace_file_writer
|
|
{
|
|
struct trace_file_writer base;
|
|
|
|
/* States related to writing CTF trace file. */
|
|
struct trace_write_handler tcs;
|
|
};
|
|
|
|
/* This is the implementation of trace_file_write_ops method
|
|
dtor. */
|
|
|
|
static void
|
|
ctf_dtor (struct trace_file_writer *self)
|
|
{
|
|
struct ctf_trace_file_writer *writer
|
|
= (struct ctf_trace_file_writer *) self;
|
|
|
|
if (writer->tcs.metadata_fd != NULL)
|
|
fclose (writer->tcs.metadata_fd);
|
|
|
|
if (writer->tcs.datastream_fd != NULL)
|
|
fclose (writer->tcs.datastream_fd);
|
|
|
|
}
|
|
|
|
/* This is the implementation of trace_file_write_ops method
|
|
target_save. */
|
|
|
|
static int
|
|
ctf_target_save (struct trace_file_writer *self,
|
|
const char *dirname)
|
|
{
|
|
/* Don't support save trace file to CTF format in the target. */
|
|
return 0;
|
|
}
|
|
|
|
/* This is the implementation of trace_file_write_ops method
|
|
start. It creates the directory DIRNAME, metadata and datastream
|
|
in the directory. */
|
|
|
|
static void
|
|
ctf_start (struct trace_file_writer *self, const char *dirname)
|
|
{
|
|
struct ctf_trace_file_writer *writer
|
|
= (struct ctf_trace_file_writer *) self;
|
|
mode_t hmode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH;
|
|
|
|
/* Create DIRNAME. */
|
|
if (mkdir (dirname, hmode) && errno != EEXIST)
|
|
error (_("Unable to open directory '%s' for saving trace data (%s)"),
|
|
dirname, safe_strerror (errno));
|
|
|
|
memset (&writer->tcs, '\0', sizeof (writer->tcs));
|
|
|
|
std::string file_name = string_printf ("%s/%s", dirname, CTF_METADATA_NAME);
|
|
|
|
writer->tcs.metadata_fd
|
|
= gdb_fopen_cloexec (file_name.c_str (), "w").release ();
|
|
if (writer->tcs.metadata_fd == NULL)
|
|
error (_("Unable to open file '%s' for saving trace data (%s)"),
|
|
file_name.c_str (), safe_strerror (errno));
|
|
|
|
ctf_save_metadata_header (&writer->tcs);
|
|
|
|
file_name = string_printf ("%s/%s", dirname, CTF_DATASTREAM_NAME);
|
|
writer->tcs.datastream_fd
|
|
= gdb_fopen_cloexec (file_name.c_str (), "w").release ();
|
|
if (writer->tcs.datastream_fd == NULL)
|
|
error (_("Unable to open file '%s' for saving trace data (%s)"),
|
|
file_name.c_str (), safe_strerror (errno));
|
|
}
|
|
|
|
/* This is the implementation of trace_file_write_ops method
|
|
write_header. Write the types of events on trace variable and
|
|
frame. */
|
|
|
|
static void
|
|
ctf_write_header (struct trace_file_writer *self)
|
|
{
|
|
struct ctf_trace_file_writer *writer
|
|
= (struct ctf_trace_file_writer *) self;
|
|
|
|
|
|
ctf_save_write_metadata (&writer->tcs, "\n");
|
|
ctf_save_write_metadata (&writer->tcs,
|
|
"event {\n\tname = \"memory\";\n\tid = %u;\n"
|
|
"\tfields := struct { \n"
|
|
"\t\tuint64_t address;\n"
|
|
"\t\tuint16_t length;\n"
|
|
"\t\tuint8_t contents[length];\n"
|
|
"\t};\n"
|
|
"};\n", CTF_EVENT_ID_MEMORY);
|
|
|
|
ctf_save_write_metadata (&writer->tcs, "\n");
|
|
ctf_save_write_metadata (&writer->tcs,
|
|
"event {\n\tname = \"tsv\";\n\tid = %u;\n"
|
|
"\tfields := struct { \n"
|
|
"\t\tuint64_t val;\n"
|
|
"\t\tuint32_t num;\n"
|
|
"\t};\n"
|
|
"};\n", CTF_EVENT_ID_TSV);
|
|
|
|
ctf_save_write_metadata (&writer->tcs, "\n");
|
|
ctf_save_write_metadata (&writer->tcs,
|
|
"event {\n\tname = \"frame\";\n\tid = %u;\n"
|
|
"\tfields := struct { \n"
|
|
"\t};\n"
|
|
"};\n", CTF_EVENT_ID_FRAME);
|
|
|
|
ctf_save_write_metadata (&writer->tcs, "\n");
|
|
ctf_save_write_metadata (&writer->tcs,
|
|
"event {\n\tname = \"tsv_def\";\n"
|
|
"\tid = %u;\n\tfields := struct { \n"
|
|
"\t\tint64_t initial_value;\n"
|
|
"\t\tint32_t number;\n"
|
|
"\t\tint32_t builtin;\n"
|
|
"\t\tchars name;\n"
|
|
"\t};\n"
|
|
"};\n", CTF_EVENT_ID_TSV_DEF);
|
|
|
|
ctf_save_write_metadata (&writer->tcs, "\n");
|
|
ctf_save_write_metadata (&writer->tcs,
|
|
"event {\n\tname = \"tp_def\";\n"
|
|
"\tid = %u;\n\tfields := struct { \n"
|
|
"\t\tuint64_t addr;\n"
|
|
"\t\tuint64_t traceframe_usage;\n"
|
|
"\t\tint32_t number;\n"
|
|
"\t\tint32_t enabled;\n"
|
|
"\t\tint32_t step;\n"
|
|
"\t\tint32_t pass;\n"
|
|
"\t\tint32_t hit_count;\n"
|
|
"\t\tint32_t type;\n"
|
|
"\t\tchars cond;\n"
|
|
|
|
"\t\tuint32_t action_num;\n"
|
|
"\t\tchars actions[action_num];\n"
|
|
|
|
"\t\tuint32_t step_action_num;\n"
|
|
"\t\tchars step_actions[step_action_num];\n"
|
|
|
|
"\t\tchars at_string;\n"
|
|
"\t\tchars cond_string;\n"
|
|
|
|
"\t\tuint32_t cmd_num;\n"
|
|
"\t\tchars cmd_strings[cmd_num];\n"
|
|
"\t};\n"
|
|
"};\n", CTF_EVENT_ID_TP_DEF);
|
|
|
|
gdb_assert (writer->tcs.content_size == 0);
|
|
gdb_assert (writer->tcs.packet_start == 0);
|
|
|
|
/* Create a new packet to contain this event. */
|
|
self->ops->frame_ops->start (self, 0);
|
|
}
|
|
|
|
/* This is the implementation of trace_file_write_ops method
|
|
write_regblock_type. Write the type of register event in
|
|
metadata. */
|
|
|
|
static void
|
|
ctf_write_regblock_type (struct trace_file_writer *self, int size)
|
|
{
|
|
struct ctf_trace_file_writer *writer
|
|
= (struct ctf_trace_file_writer *) self;
|
|
|
|
ctf_save_write_metadata (&writer->tcs, "\n");
|
|
|
|
ctf_save_write_metadata (&writer->tcs,
|
|
"event {\n\tname = \"register\";\n\tid = %u;\n"
|
|
"\tfields := struct { \n"
|
|
"\t\tascii contents[%d];\n"
|
|
"\t};\n"
|
|
"};\n",
|
|
CTF_EVENT_ID_REGISTER, size);
|
|
}
|
|
|
|
/* This is the implementation of trace_file_write_ops method
|
|
write_status. */
|
|
|
|
static void
|
|
ctf_write_status (struct trace_file_writer *self,
|
|
struct trace_status *ts)
|
|
{
|
|
struct ctf_trace_file_writer *writer
|
|
= (struct ctf_trace_file_writer *) self;
|
|
uint32_t id;
|
|
|
|
ctf_save_write_metadata (&writer->tcs, "\n");
|
|
ctf_save_write_metadata (&writer->tcs,
|
|
"event {\n\tname = \"status\";\n\tid = %u;\n"
|
|
"\tfields := struct { \n"
|
|
"\t\tint32_t stop_reason;\n"
|
|
"\t\tint32_t stopping_tracepoint;\n"
|
|
"\t\tint32_t traceframe_count;\n"
|
|
"\t\tint32_t traceframes_created;\n"
|
|
"\t\tint32_t buffer_free;\n"
|
|
"\t\tint32_t buffer_size;\n"
|
|
"\t\tint32_t disconnected_tracing;\n"
|
|
"\t\tint32_t circular_buffer;\n"
|
|
"\t};\n"
|
|
"};\n",
|
|
CTF_EVENT_ID_STATUS);
|
|
|
|
id = CTF_EVENT_ID_STATUS;
|
|
/* Event Id. */
|
|
ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
|
|
|
|
ctf_save_write_int32 (&writer->tcs, ts->stop_reason);
|
|
ctf_save_write_int32 (&writer->tcs, ts->stopping_tracepoint);
|
|
ctf_save_write_int32 (&writer->tcs, ts->traceframe_count);
|
|
ctf_save_write_int32 (&writer->tcs, ts->traceframes_created);
|
|
ctf_save_write_int32 (&writer->tcs, ts->buffer_free);
|
|
ctf_save_write_int32 (&writer->tcs, ts->buffer_size);
|
|
ctf_save_write_int32 (&writer->tcs, ts->disconnected_tracing);
|
|
ctf_save_write_int32 (&writer->tcs, ts->circular_buffer);
|
|
}
|
|
|
|
/* This is the implementation of trace_file_write_ops method
|
|
write_uploaded_tsv. */
|
|
|
|
static void
|
|
ctf_write_uploaded_tsv (struct trace_file_writer *self,
|
|
struct uploaded_tsv *tsv)
|
|
{
|
|
struct ctf_trace_file_writer *writer
|
|
= (struct ctf_trace_file_writer *) self;
|
|
int32_t int32;
|
|
int64_t int64;
|
|
const gdb_byte zero = 0;
|
|
|
|
/* Event Id. */
|
|
int32 = CTF_EVENT_ID_TSV_DEF;
|
|
ctf_save_align_write (&writer->tcs, (gdb_byte *) &int32, 4, 4);
|
|
|
|
/* initial_value */
|
|
int64 = tsv->initial_value;
|
|
ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8);
|
|
|
|
/* number */
|
|
ctf_save_write_int32 (&writer->tcs, tsv->number);
|
|
|
|
/* builtin */
|
|
ctf_save_write_int32 (&writer->tcs, tsv->builtin);
|
|
|
|
/* name */
|
|
if (tsv->name != NULL)
|
|
ctf_save_write (&writer->tcs, (gdb_byte *) tsv->name,
|
|
strlen (tsv->name));
|
|
ctf_save_write (&writer->tcs, &zero, 1);
|
|
}
|
|
|
|
/* This is the implementation of trace_file_write_ops method
|
|
write_uploaded_tp. */
|
|
|
|
static void
|
|
ctf_write_uploaded_tp (struct trace_file_writer *self,
|
|
struct uploaded_tp *tp)
|
|
{
|
|
struct ctf_trace_file_writer *writer
|
|
= (struct ctf_trace_file_writer *) self;
|
|
int32_t int32;
|
|
int64_t int64;
|
|
uint32_t u32;
|
|
const gdb_byte zero = 0;
|
|
|
|
/* Event Id. */
|
|
int32 = CTF_EVENT_ID_TP_DEF;
|
|
ctf_save_align_write (&writer->tcs, (gdb_byte *) &int32, 4, 4);
|
|
|
|
/* address */
|
|
int64 = tp->addr;
|
|
ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8);
|
|
|
|
/* traceframe_usage */
|
|
int64 = tp->traceframe_usage;
|
|
ctf_save_align_write (&writer->tcs, (gdb_byte *) &int64, 8, 8);
|
|
|
|
/* number */
|
|
ctf_save_write_int32 (&writer->tcs, tp->number);
|
|
|
|
/* enabled */
|
|
ctf_save_write_int32 (&writer->tcs, tp->enabled);
|
|
|
|
/* step */
|
|
ctf_save_write_int32 (&writer->tcs, tp->step);
|
|
|
|
/* pass */
|
|
ctf_save_write_int32 (&writer->tcs, tp->pass);
|
|
|
|
/* hit_count */
|
|
ctf_save_write_int32 (&writer->tcs, tp->hit_count);
|
|
|
|
/* type */
|
|
ctf_save_write_int32 (&writer->tcs, tp->type);
|
|
|
|
/* condition */
|
|
if (tp->cond != NULL)
|
|
ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond.get (),
|
|
strlen (tp->cond.get ()));
|
|
ctf_save_write (&writer->tcs, &zero, 1);
|
|
|
|
/* actions */
|
|
u32 = tp->actions.size ();
|
|
ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
|
|
for (const auto &act : tp->actions)
|
|
ctf_save_write (&writer->tcs, (gdb_byte *) act.get (),
|
|
strlen (act.get ()) + 1);
|
|
|
|
/* step_actions */
|
|
u32 = tp->step_actions.size ();
|
|
ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
|
|
for (const auto &act : tp->step_actions)
|
|
ctf_save_write (&writer->tcs, (gdb_byte *) act.get (),
|
|
strlen (act.get ()) + 1);
|
|
|
|
/* at_string */
|
|
if (tp->at_string != NULL)
|
|
ctf_save_write (&writer->tcs, (gdb_byte *) tp->at_string.get (),
|
|
strlen (tp->at_string.get ()));
|
|
ctf_save_write (&writer->tcs, &zero, 1);
|
|
|
|
/* cond_string */
|
|
if (tp->cond_string != NULL)
|
|
ctf_save_write (&writer->tcs, (gdb_byte *) tp->cond_string.get (),
|
|
strlen (tp->cond_string.get ()));
|
|
ctf_save_write (&writer->tcs, &zero, 1);
|
|
|
|
/* cmd_strings */
|
|
u32 = tp->cmd_strings.size ();
|
|
ctf_save_align_write (&writer->tcs, (gdb_byte *) &u32, 4, 4);
|
|
for (const auto &act : tp->cmd_strings)
|
|
ctf_save_write (&writer->tcs, (gdb_byte *) act.get (),
|
|
strlen (act.get ()) + 1);
|
|
|
|
}
|
|
|
|
/* This is the implementation of trace_file_write_ops method
|
|
write_tdesc. */
|
|
|
|
static void
|
|
ctf_write_tdesc (struct trace_file_writer *self)
|
|
{
|
|
/* Nothing so far. */
|
|
}
|
|
|
|
/* This is the implementation of trace_file_write_ops method
|
|
write_definition_end. */
|
|
|
|
static void
|
|
ctf_write_definition_end (struct trace_file_writer *self)
|
|
{
|
|
self->ops->frame_ops->end (self);
|
|
}
|
|
|
|
/* This is the implementation of trace_file_write_ops method
|
|
end. */
|
|
|
|
static void
|
|
ctf_end (struct trace_file_writer *self)
|
|
{
|
|
struct ctf_trace_file_writer *writer = (struct ctf_trace_file_writer *) self;
|
|
|
|
gdb_assert (writer->tcs.content_size == 0);
|
|
}
|
|
|
|
/* This is the implementation of trace_frame_write_ops method
|
|
start. */
|
|
|
|
static void
|
|
ctf_write_frame_start (struct trace_file_writer *self, uint16_t tpnum)
|
|
{
|
|
struct ctf_trace_file_writer *writer
|
|
= (struct ctf_trace_file_writer *) self;
|
|
uint32_t id = CTF_EVENT_ID_FRAME;
|
|
uint32_t u32;
|
|
|
|
/* Step 1: Write packet context. */
|
|
/* magic. */
|
|
u32 = CTF_MAGIC;
|
|
ctf_save_write_uint32 (&writer->tcs, u32);
|
|
/* content_size and packet_size.. We still don't know the value,
|
|
write it later. */
|
|
ctf_save_fseek (&writer->tcs, 4, SEEK_CUR);
|
|
ctf_save_fseek (&writer->tcs, 4, SEEK_CUR);
|
|
/* Tracepoint number. */
|
|
ctf_save_write (&writer->tcs, (gdb_byte *) &tpnum, 2);
|
|
|
|
/* Step 2: Write event "frame". */
|
|
/* Event Id. */
|
|
ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
|
|
}
|
|
|
|
/* This is the implementation of trace_frame_write_ops method
|
|
write_r_block. */
|
|
|
|
static void
|
|
ctf_write_frame_r_block (struct trace_file_writer *self,
|
|
gdb_byte *buf, int32_t size)
|
|
{
|
|
struct ctf_trace_file_writer *writer
|
|
= (struct ctf_trace_file_writer *) self;
|
|
uint32_t id = CTF_EVENT_ID_REGISTER;
|
|
|
|
/* Event Id. */
|
|
ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
|
|
|
|
/* array contents. */
|
|
ctf_save_align_write (&writer->tcs, buf, size, 1);
|
|
}
|
|
|
|
/* This is the implementation of trace_frame_write_ops method
|
|
write_m_block_header. */
|
|
|
|
static void
|
|
ctf_write_frame_m_block_header (struct trace_file_writer *self,
|
|
uint64_t addr, uint16_t length)
|
|
{
|
|
struct ctf_trace_file_writer *writer
|
|
= (struct ctf_trace_file_writer *) self;
|
|
uint32_t event_id = CTF_EVENT_ID_MEMORY;
|
|
|
|
/* Event Id. */
|
|
ctf_save_align_write (&writer->tcs, (gdb_byte *) &event_id, 4, 4);
|
|
|
|
/* Address. */
|
|
ctf_save_align_write (&writer->tcs, (gdb_byte *) &addr, 8, 8);
|
|
|
|
/* Length. */
|
|
ctf_save_align_write (&writer->tcs, (gdb_byte *) &length, 2, 2);
|
|
}
|
|
|
|
/* This is the implementation of trace_frame_write_ops method
|
|
write_m_block_memory. */
|
|
|
|
static void
|
|
ctf_write_frame_m_block_memory (struct trace_file_writer *self,
|
|
gdb_byte *buf, uint16_t length)
|
|
{
|
|
struct ctf_trace_file_writer *writer
|
|
= (struct ctf_trace_file_writer *) self;
|
|
|
|
/* Contents. */
|
|
ctf_save_align_write (&writer->tcs, (gdb_byte *) buf, length, 1);
|
|
}
|
|
|
|
/* This is the implementation of trace_frame_write_ops method
|
|
write_v_block. */
|
|
|
|
static void
|
|
ctf_write_frame_v_block (struct trace_file_writer *self,
|
|
int32_t num, uint64_t val)
|
|
{
|
|
struct ctf_trace_file_writer *writer
|
|
= (struct ctf_trace_file_writer *) self;
|
|
uint32_t id = CTF_EVENT_ID_TSV;
|
|
|
|
/* Event Id. */
|
|
ctf_save_align_write (&writer->tcs, (gdb_byte *) &id, 4, 4);
|
|
|
|
/* val. */
|
|
ctf_save_align_write (&writer->tcs, (gdb_byte *) &val, 8, 8);
|
|
/* num. */
|
|
ctf_save_align_write (&writer->tcs, (gdb_byte *) &num, 4, 4);
|
|
}
|
|
|
|
/* This is the implementation of trace_frame_write_ops method
|
|
end. */
|
|
|
|
static void
|
|
ctf_write_frame_end (struct trace_file_writer *self)
|
|
{
|
|
struct ctf_trace_file_writer *writer
|
|
= (struct ctf_trace_file_writer *) self;
|
|
uint32_t u32;
|
|
uint32_t t;
|
|
|
|
/* Write the content size to packet header. */
|
|
ctf_save_fseek (&writer->tcs, writer->tcs.packet_start + 4,
|
|
SEEK_SET);
|
|
u32 = writer->tcs.content_size * TARGET_CHAR_BIT;
|
|
|
|
t = writer->tcs.content_size;
|
|
ctf_save_write_uint32 (&writer->tcs, u32);
|
|
|
|
/* Write the packet size. */
|
|
u32 += 4 * TARGET_CHAR_BIT;
|
|
ctf_save_write_uint32 (&writer->tcs, u32);
|
|
|
|
writer->tcs.content_size = t;
|
|
|
|
/* Write zero at the end of the packet. */
|
|
ctf_save_fseek (&writer->tcs, writer->tcs.packet_start + t,
|
|
SEEK_SET);
|
|
u32 = 0;
|
|
ctf_save_write_uint32 (&writer->tcs, u32);
|
|
writer->tcs.content_size = t;
|
|
|
|
ctf_save_next_packet (&writer->tcs);
|
|
}
|
|
|
|
/* Operations to write various types of trace frames into CTF
|
|
format. */
|
|
|
|
static const struct trace_frame_write_ops ctf_write_frame_ops =
|
|
{
|
|
ctf_write_frame_start,
|
|
ctf_write_frame_r_block,
|
|
ctf_write_frame_m_block_header,
|
|
ctf_write_frame_m_block_memory,
|
|
ctf_write_frame_v_block,
|
|
ctf_write_frame_end,
|
|
};
|
|
|
|
/* Operations to write trace buffers into CTF format. */
|
|
|
|
static const struct trace_file_write_ops ctf_write_ops =
|
|
{
|
|
ctf_dtor,
|
|
ctf_target_save,
|
|
ctf_start,
|
|
ctf_write_header,
|
|
ctf_write_regblock_type,
|
|
ctf_write_status,
|
|
ctf_write_uploaded_tsv,
|
|
ctf_write_uploaded_tp,
|
|
ctf_write_tdesc,
|
|
ctf_write_definition_end,
|
|
NULL,
|
|
&ctf_write_frame_ops,
|
|
ctf_end,
|
|
};
|
|
|
|
/* Return a trace writer for CTF format. */
|
|
|
|
struct trace_file_writer *
|
|
ctf_trace_file_writer_new (void)
|
|
{
|
|
struct ctf_trace_file_writer *writer = XNEW (struct ctf_trace_file_writer);
|
|
|
|
writer->base.ops = &ctf_write_ops;
|
|
|
|
return (struct trace_file_writer *) writer;
|
|
}
|
|
|
|
#if HAVE_LIBBABELTRACE
|
|
/* Use libbabeltrace to read CTF data. The libbabeltrace provides
|
|
iterator to iterate over each event in CTF data and APIs to get
|
|
details of event and packet, so it is very convenient to use
|
|
libbabeltrace to access events in CTF. */
|
|
|
|
#include <babeltrace/babeltrace.h>
|
|
#include <babeltrace/ctf/events.h>
|
|
#include <babeltrace/ctf/iterator.h>
|
|
|
|
/* The struct pointer for current CTF directory. */
|
|
static int handle_id = -1;
|
|
static struct bt_context *ctx = NULL;
|
|
static struct bt_ctf_iter *ctf_iter = NULL;
|
|
/* The position of the first packet containing trace frame. */
|
|
static struct bt_iter_pos *start_pos;
|
|
|
|
/* The name of CTF directory. */
|
|
static char *trace_dirname;
|
|
|
|
static ctf_target ctf_ops;
|
|
|
|
/* Destroy ctf iterator and context. */
|
|
|
|
static void
|
|
ctf_destroy (void)
|
|
{
|
|
if (ctf_iter != NULL)
|
|
{
|
|
bt_ctf_iter_destroy (ctf_iter);
|
|
ctf_iter = NULL;
|
|
}
|
|
if (ctx != NULL)
|
|
{
|
|
bt_context_put (ctx);
|
|
ctx = NULL;
|
|
}
|
|
}
|
|
|
|
/* Open CTF trace data in DIRNAME. */
|
|
|
|
static void
|
|
ctf_open_dir (const char *dirname)
|
|
{
|
|
struct bt_iter_pos begin_pos;
|
|
unsigned int count, i;
|
|
struct bt_ctf_event_decl * const *list;
|
|
|
|
ctx = bt_context_create ();
|
|
if (ctx == NULL)
|
|
error (_("Unable to create bt_context"));
|
|
handle_id = bt_context_add_trace (ctx, dirname, "ctf", NULL, NULL, NULL);
|
|
if (handle_id < 0)
|
|
{
|
|
ctf_destroy ();
|
|
error (_("Unable to use libbabeltrace on directory \"%s\""),
|
|
dirname);
|
|
}
|
|
|
|
begin_pos.type = BT_SEEK_BEGIN;
|
|
ctf_iter = bt_ctf_iter_create (ctx, &begin_pos, NULL);
|
|
if (ctf_iter == NULL)
|
|
{
|
|
ctf_destroy ();
|
|
error (_("Unable to create bt_iterator"));
|
|
}
|
|
|
|
/* Look for the declaration of register block. Get the length of
|
|
array "contents" to set trace_regblock_size. */
|
|
|
|
bt_ctf_get_event_decl_list (handle_id, ctx, &list, &count);
|
|
for (i = 0; i < count; i++)
|
|
if (strcmp ("register", bt_ctf_get_decl_event_name (list[i])) == 0)
|
|
{
|
|
const struct bt_ctf_field_decl * const *field_list;
|
|
const struct bt_declaration *decl;
|
|
|
|
bt_ctf_get_decl_fields (list[i], BT_EVENT_FIELDS, &field_list,
|
|
&count);
|
|
|
|
gdb_assert (count == 1);
|
|
gdb_assert (0 == strcmp ("contents",
|
|
bt_ctf_get_decl_field_name (field_list[0])));
|
|
decl = bt_ctf_get_decl_from_field_decl (field_list[0]);
|
|
trace_regblock_size = bt_ctf_get_array_len (decl);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
#define SET_INT32_FIELD(EVENT, SCOPE, VAR, FIELD) \
|
|
(VAR)->FIELD = (int) bt_ctf_get_int64 (bt_ctf_get_field ((EVENT), \
|
|
(SCOPE), \
|
|
#FIELD))
|
|
|
|
#define SET_ENUM_FIELD(EVENT, SCOPE, VAR, TYPE, FIELD) \
|
|
(VAR)->FIELD = (TYPE) bt_ctf_get_int64 (bt_ctf_get_field ((EVENT), \
|
|
(SCOPE), \
|
|
#FIELD))
|
|
|
|
|
|
/* EVENT is the "status" event and TS is filled in. */
|
|
|
|
static void
|
|
ctf_read_status (struct bt_ctf_event *event, struct trace_status *ts)
|
|
{
|
|
const struct bt_definition *scope
|
|
= bt_ctf_get_top_level_scope (event, BT_EVENT_FIELDS);
|
|
|
|
SET_ENUM_FIELD (event, scope, ts, enum trace_stop_reason, stop_reason);
|
|
SET_INT32_FIELD (event, scope, ts, stopping_tracepoint);
|
|
SET_INT32_FIELD (event, scope, ts, traceframe_count);
|
|
SET_INT32_FIELD (event, scope, ts, traceframes_created);
|
|
SET_INT32_FIELD (event, scope, ts, buffer_free);
|
|
SET_INT32_FIELD (event, scope, ts, buffer_size);
|
|
SET_INT32_FIELD (event, scope, ts, disconnected_tracing);
|
|
SET_INT32_FIELD (event, scope, ts, circular_buffer);
|
|
|
|
bt_iter_next (bt_ctf_get_iter (ctf_iter));
|
|
}
|
|
|
|
/* Read the events "tsv_def" one by one, extract its contents and fill
|
|
in the list UPLOADED_TSVS. */
|
|
|
|
static void
|
|
ctf_read_tsv (struct uploaded_tsv **uploaded_tsvs)
|
|
{
|
|
gdb_assert (ctf_iter != NULL);
|
|
|
|
while (1)
|
|
{
|
|
struct bt_ctf_event *event;
|
|
const struct bt_definition *scope;
|
|
const struct bt_definition *def;
|
|
uint32_t event_id;
|
|
struct uploaded_tsv *utsv = NULL;
|
|
|
|
event = bt_ctf_iter_read_event (ctf_iter);
|
|
scope = bt_ctf_get_top_level_scope (event,
|
|
BT_STREAM_EVENT_HEADER);
|
|
event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope,
|
|
"id"));
|
|
if (event_id != CTF_EVENT_ID_TSV_DEF)
|
|
break;
|
|
|
|
scope = bt_ctf_get_top_level_scope (event,
|
|
BT_EVENT_FIELDS);
|
|
|
|
def = bt_ctf_get_field (event, scope, "number");
|
|
utsv = get_uploaded_tsv ((int32_t) bt_ctf_get_int64 (def),
|
|
uploaded_tsvs);
|
|
|
|
def = bt_ctf_get_field (event, scope, "builtin");
|
|
utsv->builtin = (int32_t) bt_ctf_get_int64 (def);
|
|
def = bt_ctf_get_field (event, scope, "initial_value");
|
|
utsv->initial_value = bt_ctf_get_int64 (def);
|
|
|
|
def = bt_ctf_get_field (event, scope, "name");
|
|
utsv->name = xstrdup (bt_ctf_get_string (def));
|
|
|
|
if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
/* Read the value of element whose index is NUM from CTF and write it
|
|
to the corresponding VAR->ARRAY. */
|
|
|
|
#define SET_ARRAY_FIELD(EVENT, SCOPE, VAR, NUM, ARRAY) \
|
|
do \
|
|
{ \
|
|
uint32_t lu32, i; \
|
|
const struct bt_definition *def; \
|
|
\
|
|
lu32 = (uint32_t) bt_ctf_get_uint64 (bt_ctf_get_field ((EVENT), \
|
|
(SCOPE), \
|
|
#NUM)); \
|
|
def = bt_ctf_get_field ((EVENT), (SCOPE), #ARRAY); \
|
|
for (i = 0; i < lu32; i++) \
|
|
{ \
|
|
const struct bt_definition *element \
|
|
= bt_ctf_get_index ((EVENT), def, i); \
|
|
\
|
|
(VAR)->ARRAY.emplace_back \
|
|
(xstrdup (bt_ctf_get_string (element))); \
|
|
} \
|
|
} \
|
|
while (0)
|
|
|
|
/* Read a string from CTF and set VAR->FIELD. If the length of string
|
|
is zero, set VAR->FIELD to NULL. */
|
|
|
|
#define SET_STRING_FIELD(EVENT, SCOPE, VAR, FIELD) \
|
|
do \
|
|
{ \
|
|
const char *p = bt_ctf_get_string (bt_ctf_get_field ((EVENT), \
|
|
(SCOPE), \
|
|
#FIELD)); \
|
|
\
|
|
if (strlen (p) > 0) \
|
|
(VAR)->FIELD.reset (xstrdup (p)); \
|
|
else \
|
|
(VAR)->FIELD = NULL; \
|
|
} \
|
|
while (0)
|
|
|
|
/* Read the events "tp_def" one by one, extract its contents and fill
|
|
in the list UPLOADED_TPS. */
|
|
|
|
static void
|
|
ctf_read_tp (struct uploaded_tp **uploaded_tps)
|
|
{
|
|
gdb_assert (ctf_iter != NULL);
|
|
|
|
while (1)
|
|
{
|
|
struct bt_ctf_event *event;
|
|
const struct bt_definition *scope;
|
|
uint32_t u32;
|
|
int32_t int32;
|
|
uint64_t u64;
|
|
struct uploaded_tp *utp = NULL;
|
|
|
|
event = bt_ctf_iter_read_event (ctf_iter);
|
|
scope = bt_ctf_get_top_level_scope (event,
|
|
BT_STREAM_EVENT_HEADER);
|
|
u32 = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope,
|
|
"id"));
|
|
if (u32 != CTF_EVENT_ID_TP_DEF)
|
|
break;
|
|
|
|
scope = bt_ctf_get_top_level_scope (event,
|
|
BT_EVENT_FIELDS);
|
|
int32 = (int32_t) bt_ctf_get_int64 (bt_ctf_get_field (event,
|
|
scope,
|
|
"number"));
|
|
u64 = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope,
|
|
"addr"));
|
|
utp = get_uploaded_tp (int32, u64, uploaded_tps);
|
|
|
|
SET_INT32_FIELD (event, scope, utp, enabled);
|
|
SET_INT32_FIELD (event, scope, utp, step);
|
|
SET_INT32_FIELD (event, scope, utp, pass);
|
|
SET_INT32_FIELD (event, scope, utp, hit_count);
|
|
SET_ENUM_FIELD (event, scope, utp, enum bptype, type);
|
|
|
|
/* Read 'cmd_strings'. */
|
|
SET_ARRAY_FIELD (event, scope, utp, cmd_num, cmd_strings);
|
|
/* Read 'actions'. */
|
|
SET_ARRAY_FIELD (event, scope, utp, action_num, actions);
|
|
/* Read 'step_actions'. */
|
|
SET_ARRAY_FIELD (event, scope, utp, step_action_num,
|
|
step_actions);
|
|
|
|
SET_STRING_FIELD(event, scope, utp, at_string);
|
|
SET_STRING_FIELD(event, scope, utp, cond_string);
|
|
|
|
if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* This is the implementation of target_ops method to_open. Open CTF
|
|
trace data, read trace status, trace state variables and tracepoint
|
|
definitions from the first packet. Set the start position at the
|
|
second packet which contains events on trace blocks. */
|
|
|
|
static void
|
|
ctf_target_open (const char *dirname, int from_tty)
|
|
{
|
|
struct bt_ctf_event *event;
|
|
uint32_t event_id;
|
|
const struct bt_definition *scope;
|
|
struct uploaded_tsv *uploaded_tsvs = NULL;
|
|
struct uploaded_tp *uploaded_tps = NULL;
|
|
|
|
if (!dirname)
|
|
error (_("No CTF directory specified."));
|
|
|
|
ctf_open_dir (dirname);
|
|
|
|
target_preopen (from_tty);
|
|
|
|
/* Skip the first packet which about the trace status. The first
|
|
event is "frame". */
|
|
event = bt_ctf_iter_read_event (ctf_iter);
|
|
scope = bt_ctf_get_top_level_scope (event, BT_STREAM_EVENT_HEADER);
|
|
event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "id"));
|
|
if (event_id != CTF_EVENT_ID_FRAME)
|
|
error (_("Wrong event id of the first event"));
|
|
/* The second event is "status". */
|
|
bt_iter_next (bt_ctf_get_iter (ctf_iter));
|
|
event = bt_ctf_iter_read_event (ctf_iter);
|
|
scope = bt_ctf_get_top_level_scope (event, BT_STREAM_EVENT_HEADER);
|
|
event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "id"));
|
|
if (event_id != CTF_EVENT_ID_STATUS)
|
|
error (_("Wrong event id of the second event"));
|
|
ctf_read_status (event, current_trace_status ());
|
|
|
|
ctf_read_tsv (&uploaded_tsvs);
|
|
|
|
ctf_read_tp (&uploaded_tps);
|
|
|
|
event = bt_ctf_iter_read_event (ctf_iter);
|
|
/* EVENT can be NULL if we've already gone to the end of stream of
|
|
events. */
|
|
if (event != NULL)
|
|
{
|
|
scope = bt_ctf_get_top_level_scope (event,
|
|
BT_STREAM_EVENT_HEADER);
|
|
event_id = bt_ctf_get_uint64 (bt_ctf_get_field (event,
|
|
scope, "id"));
|
|
if (event_id != CTF_EVENT_ID_FRAME)
|
|
error (_("Wrong event id of the first event of the second packet"));
|
|
}
|
|
|
|
start_pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
|
|
gdb_assert (start_pos->type == BT_SEEK_RESTORE);
|
|
|
|
trace_dirname = xstrdup (dirname);
|
|
push_target (&ctf_ops);
|
|
|
|
inferior_appeared (current_inferior (), CTF_PID);
|
|
inferior_ptid = ptid_t (CTF_PID);
|
|
add_thread_silent (&ctf_ops, inferior_ptid);
|
|
|
|
merge_uploaded_trace_state_variables (&uploaded_tsvs);
|
|
merge_uploaded_tracepoints (&uploaded_tps);
|
|
|
|
post_create_inferior (&ctf_ops, from_tty);
|
|
}
|
|
|
|
/* This is the implementation of target_ops method to_close. Destroy
|
|
CTF iterator and context. */
|
|
|
|
void
|
|
ctf_target::close ()
|
|
{
|
|
ctf_destroy ();
|
|
xfree (trace_dirname);
|
|
trace_dirname = NULL;
|
|
|
|
inferior_ptid = null_ptid; /* Avoid confusion from thread stuff. */
|
|
exit_inferior_silent (current_inferior ());
|
|
|
|
trace_reset_local_state ();
|
|
}
|
|
|
|
/* This is the implementation of target_ops method to_files_info.
|
|
Print the directory name of CTF trace data. */
|
|
|
|
void
|
|
ctf_target::files_info ()
|
|
{
|
|
printf_filtered ("\t`%s'\n", trace_dirname);
|
|
}
|
|
|
|
/* This is the implementation of target_ops method to_fetch_registers.
|
|
Iterate over events whose name is "register" in current frame,
|
|
extract contents from events, and set REGCACHE with the contents.
|
|
If no matched events are found, mark registers unavailable. */
|
|
|
|
void
|
|
ctf_target::fetch_registers (struct regcache *regcache, int regno)
|
|
{
|
|
struct gdbarch *gdbarch = regcache->arch ();
|
|
struct bt_ctf_event *event = NULL;
|
|
struct bt_iter_pos *pos;
|
|
|
|
/* An uninitialized reg size says we're not going to be
|
|
successful at getting register blocks. */
|
|
if (trace_regblock_size == 0)
|
|
return;
|
|
|
|
gdb_assert (ctf_iter != NULL);
|
|
/* Save the current position. */
|
|
pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
|
|
gdb_assert (pos->type == BT_SEEK_RESTORE);
|
|
|
|
while (1)
|
|
{
|
|
const char *name;
|
|
struct bt_ctf_event *event1;
|
|
|
|
event1 = bt_ctf_iter_read_event (ctf_iter);
|
|
|
|
name = bt_ctf_event_name (event1);
|
|
|
|
if (name == NULL || strcmp (name, "frame") == 0)
|
|
break;
|
|
else if (strcmp (name, "register") == 0)
|
|
{
|
|
event = event1;
|
|
break;
|
|
}
|
|
|
|
if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
|
|
break;
|
|
}
|
|
|
|
/* Restore the position. */
|
|
bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
|
|
|
|
if (event != NULL)
|
|
{
|
|
int offset, regsize, regn;
|
|
const struct bt_definition *scope
|
|
= bt_ctf_get_top_level_scope (event,
|
|
BT_EVENT_FIELDS);
|
|
const struct bt_definition *array
|
|
= bt_ctf_get_field (event, scope, "contents");
|
|
gdb_byte *regs = (gdb_byte *) bt_ctf_get_char_array (array);
|
|
|
|
/* Assume the block is laid out in GDB register number order,
|
|
each register with the size that it has in GDB. */
|
|
offset = 0;
|
|
for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++)
|
|
{
|
|
regsize = register_size (gdbarch, regn);
|
|
/* Make sure we stay within block bounds. */
|
|
if (offset + regsize >= trace_regblock_size)
|
|
break;
|
|
if (regcache->get_register_status (regn) == REG_UNKNOWN)
|
|
{
|
|
if (regno == regn)
|
|
{
|
|
regcache->raw_supply (regno, regs + offset);
|
|
break;
|
|
}
|
|
else if (regno == -1)
|
|
{
|
|
regcache->raw_supply (regn, regs + offset);
|
|
}
|
|
}
|
|
offset += regsize;
|
|
}
|
|
}
|
|
else
|
|
tracefile_fetch_registers (regcache, regno);
|
|
}
|
|
|
|
/* This is the implementation of target_ops method to_xfer_partial.
|
|
Iterate over events whose name is "memory" in
|
|
current frame, extract the address and length from events. If
|
|
OFFSET is within the range, read the contents from events to
|
|
READBUF. */
|
|
|
|
enum target_xfer_status
|
|
ctf_target::xfer_partial (enum target_object object,
|
|
const char *annex, gdb_byte *readbuf,
|
|
const gdb_byte *writebuf, ULONGEST offset,
|
|
ULONGEST len, ULONGEST *xfered_len)
|
|
{
|
|
/* We're only doing regular memory for now. */
|
|
if (object != TARGET_OBJECT_MEMORY)
|
|
return TARGET_XFER_E_IO;
|
|
|
|
if (readbuf == NULL)
|
|
error (_("ctf_xfer_partial: trace file is read-only"));
|
|
|
|
if (get_traceframe_number () != -1)
|
|
{
|
|
struct bt_iter_pos *pos;
|
|
enum target_xfer_status res;
|
|
/* Records the lowest available address of all blocks that
|
|
intersects the requested range. */
|
|
ULONGEST low_addr_available = 0;
|
|
|
|
gdb_assert (ctf_iter != NULL);
|
|
/* Save the current position. */
|
|
pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
|
|
gdb_assert (pos->type == BT_SEEK_RESTORE);
|
|
|
|
/* Iterate through the traceframe's blocks, looking for
|
|
memory. */
|
|
while (1)
|
|
{
|
|
ULONGEST amt;
|
|
uint64_t maddr;
|
|
uint16_t mlen;
|
|
const struct bt_definition *scope;
|
|
const struct bt_definition *def;
|
|
struct bt_ctf_event *event
|
|
= bt_ctf_iter_read_event (ctf_iter);
|
|
const char *name = bt_ctf_event_name (event);
|
|
|
|
if (name == NULL || strcmp (name, "frame") == 0)
|
|
break;
|
|
else if (strcmp (name, "memory") != 0)
|
|
{
|
|
if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
|
|
break;
|
|
|
|
continue;
|
|
}
|
|
|
|
scope = bt_ctf_get_top_level_scope (event,
|
|
BT_EVENT_FIELDS);
|
|
|
|
def = bt_ctf_get_field (event, scope, "address");
|
|
maddr = bt_ctf_get_uint64 (def);
|
|
def = bt_ctf_get_field (event, scope, "length");
|
|
mlen = (uint16_t) bt_ctf_get_uint64 (def);
|
|
|
|
/* If the block includes the first part of the desired
|
|
range, return as much it has; GDB will re-request the
|
|
remainder, which might be in a different block of this
|
|
trace frame. */
|
|
if (maddr <= offset && offset < (maddr + mlen))
|
|
{
|
|
const struct bt_definition *array
|
|
= bt_ctf_get_field (event, scope, "contents");
|
|
gdb_byte *contents;
|
|
int k;
|
|
|
|
contents = (gdb_byte *) xmalloc (mlen);
|
|
|
|
for (k = 0; k < mlen; k++)
|
|
{
|
|
const struct bt_definition *element
|
|
= bt_ctf_get_index (event, array, k);
|
|
|
|
contents[k] = (gdb_byte) bt_ctf_get_uint64 (element);
|
|
}
|
|
|
|
amt = (maddr + mlen) - offset;
|
|
if (amt > len)
|
|
amt = len;
|
|
|
|
memcpy (readbuf, &contents[offset - maddr], amt);
|
|
|
|
xfree (contents);
|
|
|
|
/* Restore the position. */
|
|
bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
|
|
|
|
if (amt == 0)
|
|
return TARGET_XFER_EOF;
|
|
else
|
|
{
|
|
*xfered_len = amt;
|
|
return TARGET_XFER_OK;
|
|
}
|
|
}
|
|
|
|
if (offset < maddr && maddr < (offset + len))
|
|
if (low_addr_available == 0 || low_addr_available > maddr)
|
|
low_addr_available = maddr;
|
|
|
|
if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
|
|
break;
|
|
}
|
|
|
|
/* Restore the position. */
|
|
bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
|
|
|
|
/* Requested memory is unavailable in the context of traceframes,
|
|
and this address falls within a read-only section, fallback
|
|
to reading from executable, up to LOW_ADDR_AVAILABLE */
|
|
if (offset < low_addr_available)
|
|
len = std::min (len, low_addr_available - offset);
|
|
res = exec_read_partial_read_only (readbuf, offset, len, xfered_len);
|
|
|
|
if (res == TARGET_XFER_OK)
|
|
return TARGET_XFER_OK;
|
|
else
|
|
{
|
|
/* No use trying further, we know some memory starting
|
|
at MEMADDR isn't available. */
|
|
*xfered_len = len;
|
|
return TARGET_XFER_UNAVAILABLE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Fallback to reading from read-only sections. */
|
|
return section_table_read_available_memory (readbuf, offset, len, xfered_len);
|
|
}
|
|
}
|
|
|
|
/* This is the implementation of target_ops method
|
|
to_get_trace_state_variable_value.
|
|
Iterate over events whose name is "tsv" in current frame. When the
|
|
trace variable is found, set the value of it to *VAL and return
|
|
true, otherwise return false. */
|
|
|
|
bool
|
|
ctf_target::get_trace_state_variable_value (int tsvnum, LONGEST *val)
|
|
{
|
|
struct bt_iter_pos *pos;
|
|
bool found = false;
|
|
|
|
gdb_assert (ctf_iter != NULL);
|
|
/* Save the current position. */
|
|
pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
|
|
gdb_assert (pos->type == BT_SEEK_RESTORE);
|
|
|
|
/* Iterate through the traceframe's blocks, looking for 'V'
|
|
block. */
|
|
while (1)
|
|
{
|
|
struct bt_ctf_event *event
|
|
= bt_ctf_iter_read_event (ctf_iter);
|
|
const char *name = bt_ctf_event_name (event);
|
|
|
|
if (name == NULL || strcmp (name, "frame") == 0)
|
|
break;
|
|
else if (strcmp (name, "tsv") == 0)
|
|
{
|
|
const struct bt_definition *scope;
|
|
const struct bt_definition *def;
|
|
|
|
scope = bt_ctf_get_top_level_scope (event,
|
|
BT_EVENT_FIELDS);
|
|
|
|
def = bt_ctf_get_field (event, scope, "num");
|
|
if (tsvnum == (int32_t) bt_ctf_get_uint64 (def))
|
|
{
|
|
def = bt_ctf_get_field (event, scope, "val");
|
|
*val = bt_ctf_get_uint64 (def);
|
|
|
|
found = true;
|
|
}
|
|
}
|
|
|
|
if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
|
|
break;
|
|
}
|
|
|
|
/* Restore the position. */
|
|
bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
|
|
|
|
return found;
|
|
}
|
|
|
|
/* Return the tracepoint number in "frame" event. */
|
|
|
|
static int
|
|
ctf_get_tpnum_from_frame_event (struct bt_ctf_event *event)
|
|
{
|
|
/* The packet context of events has a field "tpnum". */
|
|
const struct bt_definition *scope
|
|
= bt_ctf_get_top_level_scope (event, BT_STREAM_PACKET_CONTEXT);
|
|
uint64_t tpnum
|
|
= bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "tpnum"));
|
|
|
|
return (int) tpnum;
|
|
}
|
|
|
|
/* Return the address at which the current frame was collected. */
|
|
|
|
static CORE_ADDR
|
|
ctf_get_traceframe_address (void)
|
|
{
|
|
struct bt_ctf_event *event = NULL;
|
|
struct bt_iter_pos *pos;
|
|
CORE_ADDR addr = 0;
|
|
|
|
gdb_assert (ctf_iter != NULL);
|
|
pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
|
|
gdb_assert (pos->type == BT_SEEK_RESTORE);
|
|
|
|
while (1)
|
|
{
|
|
const char *name;
|
|
struct bt_ctf_event *event1;
|
|
|
|
event1 = bt_ctf_iter_read_event (ctf_iter);
|
|
|
|
name = bt_ctf_event_name (event1);
|
|
|
|
if (name == NULL)
|
|
break;
|
|
else if (strcmp (name, "frame") == 0)
|
|
{
|
|
event = event1;
|
|
break;
|
|
}
|
|
|
|
if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
|
|
break;
|
|
}
|
|
|
|
if (event != NULL)
|
|
{
|
|
int tpnum = ctf_get_tpnum_from_frame_event (event);
|
|
struct tracepoint *tp
|
|
= get_tracepoint_by_number_on_target (tpnum);
|
|
|
|
if (tp && tp->loc)
|
|
addr = tp->loc->address;
|
|
}
|
|
|
|
/* Restore the position. */
|
|
bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
|
|
|
|
return addr;
|
|
}
|
|
|
|
/* This is the implementation of target_ops method to_trace_find.
|
|
Iterate the events whose name is "frame", extract the tracepoint
|
|
number in it. Return traceframe number when matched. */
|
|
|
|
int
|
|
ctf_target::trace_find (enum trace_find_type type, int num,
|
|
CORE_ADDR addr1, CORE_ADDR addr2, int *tpp)
|
|
{
|
|
int tfnum = 0;
|
|
int found = 0;
|
|
|
|
if (num == -1)
|
|
{
|
|
if (tpp != NULL)
|
|
*tpp = -1;
|
|
return -1;
|
|
}
|
|
|
|
gdb_assert (ctf_iter != NULL);
|
|
/* Set iterator back to the start. */
|
|
bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), start_pos);
|
|
|
|
while (1)
|
|
{
|
|
struct bt_ctf_event *event;
|
|
const char *name;
|
|
|
|
event = bt_ctf_iter_read_event (ctf_iter);
|
|
|
|
name = bt_ctf_event_name (event);
|
|
|
|
if (event == NULL || name == NULL)
|
|
break;
|
|
|
|
if (strcmp (name, "frame") == 0)
|
|
{
|
|
CORE_ADDR tfaddr;
|
|
|
|
if (type == tfind_number)
|
|
{
|
|
/* Looking for a specific trace frame. */
|
|
if (tfnum == num)
|
|
found = 1;
|
|
}
|
|
else
|
|
{
|
|
/* Start from the _next_ trace frame. */
|
|
if (tfnum > get_traceframe_number ())
|
|
{
|
|
switch (type)
|
|
{
|
|
case tfind_tp:
|
|
{
|
|
struct tracepoint *tp = get_tracepoint (num);
|
|
|
|
if (tp != NULL
|
|
&& (tp->number_on_target
|
|
== ctf_get_tpnum_from_frame_event (event)))
|
|
found = 1;
|
|
break;
|
|
}
|
|
case tfind_pc:
|
|
tfaddr = ctf_get_traceframe_address ();
|
|
if (tfaddr == addr1)
|
|
found = 1;
|
|
break;
|
|
case tfind_range:
|
|
tfaddr = ctf_get_traceframe_address ();
|
|
if (addr1 <= tfaddr && tfaddr <= addr2)
|
|
found = 1;
|
|
break;
|
|
case tfind_outside:
|
|
tfaddr = ctf_get_traceframe_address ();
|
|
if (!(addr1 <= tfaddr && tfaddr <= addr2))
|
|
found = 1;
|
|
break;
|
|
default:
|
|
internal_error (__FILE__, __LINE__, _("unknown tfind type"));
|
|
}
|
|
}
|
|
}
|
|
if (found)
|
|
{
|
|
if (tpp != NULL)
|
|
*tpp = ctf_get_tpnum_from_frame_event (event);
|
|
|
|
/* Skip the event "frame". */
|
|
bt_iter_next (bt_ctf_get_iter (ctf_iter));
|
|
|
|
return tfnum;
|
|
}
|
|
tfnum++;
|
|
}
|
|
|
|
if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
|
|
break;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/* This is the implementation of target_ops method to_traceframe_info.
|
|
Iterate the events whose name is "memory", in current
|
|
frame, extract memory range information, and return them in
|
|
traceframe_info. */
|
|
|
|
traceframe_info_up
|
|
ctf_target::traceframe_info ()
|
|
{
|
|
traceframe_info_up info (new struct traceframe_info);
|
|
const char *name;
|
|
struct bt_iter_pos *pos;
|
|
|
|
gdb_assert (ctf_iter != NULL);
|
|
/* Save the current position. */
|
|
pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
|
|
gdb_assert (pos->type == BT_SEEK_RESTORE);
|
|
|
|
do
|
|
{
|
|
struct bt_ctf_event *event
|
|
= bt_ctf_iter_read_event (ctf_iter);
|
|
|
|
name = bt_ctf_event_name (event);
|
|
|
|
if (name == NULL || strcmp (name, "register") == 0
|
|
|| strcmp (name, "frame") == 0)
|
|
;
|
|
else if (strcmp (name, "memory") == 0)
|
|
{
|
|
const struct bt_definition *scope
|
|
= bt_ctf_get_top_level_scope (event,
|
|
BT_EVENT_FIELDS);
|
|
const struct bt_definition *def;
|
|
|
|
def = bt_ctf_get_field (event, scope, "address");
|
|
CORE_ADDR start = bt_ctf_get_uint64 (def);
|
|
|
|
def = bt_ctf_get_field (event, scope, "length");
|
|
int length = (uint16_t) bt_ctf_get_uint64 (def);
|
|
|
|
info->memory.emplace_back (start, length);
|
|
}
|
|
else if (strcmp (name, "tsv") == 0)
|
|
{
|
|
int vnum;
|
|
const struct bt_definition *scope
|
|
= bt_ctf_get_top_level_scope (event,
|
|
BT_EVENT_FIELDS);
|
|
const struct bt_definition *def;
|
|
|
|
def = bt_ctf_get_field (event, scope, "num");
|
|
vnum = (int) bt_ctf_get_uint64 (def);
|
|
info->tvars.push_back (vnum);
|
|
}
|
|
else
|
|
{
|
|
warning (_("Unhandled trace block type (%s) "
|
|
"while building trace frame info."),
|
|
name);
|
|
}
|
|
|
|
if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
|
|
break;
|
|
}
|
|
while (name != NULL && strcmp (name, "frame") != 0);
|
|
|
|
/* Restore the position. */
|
|
bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
|
|
|
|
return info;
|
|
}
|
|
|
|
#endif
|
|
|
|
/* module initialization */
|
|
|
|
void _initialize_ctf ();
|
|
void
|
|
_initialize_ctf ()
|
|
{
|
|
#if HAVE_LIBBABELTRACE
|
|
add_target (ctf_target_info, ctf_target_open, filename_completer);
|
|
#endif
|
|
}
|